Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

AttackArrowGraphics.js 4.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. /**
  2. * @Author: Caven
  3. * @Date: 2020-08-30 16:22:50
  4. */
  5. import { Cesium } from '@dc-modules/namespace'
  6. import Parse from '@dc-modules/parse/Parse'
  7. import { Transform } from '@dc-modules/transform'
  8. import { PlotUtil } from '@dc-modules/utils'
  9. const HALF_PI = Math.PI / 2
  10. class AttackArrowGraphics {
  11. constructor(options) {
  12. this._positions = options?.positions || []
  13. this.headHeightFactor = 0.18
  14. this.headWidthFactor = 0.3
  15. this.neckHeightFactor = 0.85
  16. this.neckWidthFactor = 0.15
  17. this.headTailFactor = 0.8
  18. }
  19. set positions(positions) {
  20. this._positions = positions
  21. }
  22. get positions() {
  23. return this._positions
  24. }
  25. get hierarchy() {
  26. return this._createHierarchy()
  27. }
  28. _getArrowHeadPoints(points, tailLeft, tailRight) {
  29. let len = PlotUtil.getBaseLength(points)
  30. let headHeight = len * this.headHeightFactor
  31. let headPnt = points[points.length - 1]
  32. len = PlotUtil.distance(headPnt, points[points.length - 2])
  33. let tailWidth = PlotUtil.distance(tailLeft, tailRight)
  34. if (headHeight > tailWidth * this.headTailFactor) {
  35. headHeight = tailWidth * this.headTailFactor
  36. }
  37. let headWidth = headHeight * this.headWidthFactor
  38. let neckWidth = headHeight * this.neckWidthFactor
  39. headHeight = headHeight > len ? len : headHeight
  40. let neckHeight = headHeight * this.neckHeightFactor
  41. let headEndPnt = PlotUtil.getThirdPoint(
  42. points[points.length - 2],
  43. headPnt,
  44. 0,
  45. headHeight,
  46. true
  47. )
  48. let neckEndPnt = PlotUtil.getThirdPoint(
  49. points[points.length - 2],
  50. headPnt,
  51. 0,
  52. neckHeight,
  53. true
  54. )
  55. let headLeft = PlotUtil.getThirdPoint(
  56. headPnt,
  57. headEndPnt,
  58. HALF_PI,
  59. headWidth,
  60. false
  61. )
  62. let headRight = PlotUtil.getThirdPoint(
  63. headPnt,
  64. headEndPnt,
  65. HALF_PI,
  66. headWidth,
  67. true
  68. )
  69. let neckLeft = PlotUtil.getThirdPoint(
  70. headPnt,
  71. neckEndPnt,
  72. HALF_PI,
  73. neckWidth,
  74. false
  75. )
  76. let neckRight = PlotUtil.getThirdPoint(
  77. headPnt,
  78. neckEndPnt,
  79. HALF_PI,
  80. neckWidth,
  81. true
  82. )
  83. return [neckLeft, headLeft, headPnt, headRight, neckRight]
  84. }
  85. _getArrowBodyPoints(points, neckLeft, neckRight, tailWidthFactor) {
  86. let allLen = PlotUtil.wholeDistance(points)
  87. let len = PlotUtil.getBaseLength(points)
  88. let tailWidth = len * tailWidthFactor
  89. let neckWidth = PlotUtil.distance(neckLeft, neckRight)
  90. let widthDif = (tailWidth - neckWidth) / 2
  91. let tempLen = 0
  92. let leftBodyPnts = []
  93. let rightBodyPnts = []
  94. for (let i = 1; i < points.length - 1; i++) {
  95. let angle =
  96. PlotUtil.getAngleOfThreePoints(
  97. points[i - 1],
  98. points[i],
  99. points[i + 1]
  100. ) / 2
  101. tempLen += PlotUtil.distance(points[i - 1], points[i])
  102. let w = (tailWidth / 2 - (tempLen / allLen) * widthDif) / Math.sin(angle)
  103. let left = PlotUtil.getThirdPoint(
  104. points[i - 1],
  105. points[i],
  106. Math.PI - angle,
  107. w,
  108. true
  109. )
  110. let right = PlotUtil.getThirdPoint(
  111. points[i - 1],
  112. points[i],
  113. angle,
  114. w,
  115. false
  116. )
  117. leftBodyPnts.push(left)
  118. rightBodyPnts.push(right)
  119. }
  120. return leftBodyPnts.concat(rightBodyPnts)
  121. }
  122. _createHierarchy() {
  123. let pnts = Parse.parsePolygonCoordToArray(
  124. Transform.transformCartesianArrayToWGS84Array(this._positions)
  125. )[0]
  126. let tailLeft = pnts[0]
  127. let tailRight = pnts[1]
  128. if (PlotUtil.isClockWise(pnts[0], pnts[1], pnts[2])) {
  129. tailLeft = pnts[1]
  130. tailRight = pnts[0]
  131. }
  132. let midTail = PlotUtil.mid(tailLeft, tailRight)
  133. let bonePnts = [midTail].concat(pnts.slice(2))
  134. // 计算箭头
  135. let headPnts = this._getArrowHeadPoints(bonePnts, tailLeft, tailRight)
  136. let neckLeft = headPnts[0]
  137. let neckRight = headPnts[4]
  138. let tailWidthFactor =
  139. PlotUtil.distance(tailLeft, tailRight) / PlotUtil.getBaseLength(bonePnts)
  140. // 计算箭身
  141. let bodyPnts = this._getArrowBodyPoints(
  142. bonePnts,
  143. neckLeft,
  144. neckRight,
  145. tailWidthFactor
  146. )
  147. // 整合
  148. let count = bodyPnts.length
  149. let leftPnts = [tailLeft].concat(bodyPnts.slice(0, count / 2))
  150. leftPnts.push(neckLeft)
  151. let rightPnts = [tailRight].concat(bodyPnts.slice(count / 2, count))
  152. rightPnts.push(neckRight)
  153. leftPnts = PlotUtil.getQBSplinePoints(leftPnts)
  154. rightPnts = PlotUtil.getQBSplinePoints(rightPnts)
  155. return new Cesium.PolygonHierarchy(
  156. Transform.transformWGS84ArrayToCartesianArray(
  157. Parse.parsePositions(leftPnts.concat(headPnts, rightPnts.reverse()))
  158. )
  159. )
  160. }
  161. }
  162. export default AttackArrowGraphics