Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

AttackArrow.js 5.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. /**
  2. * @Author: Caven
  3. * @Date: 2020-08-29 21:45:14
  4. */
  5. import { Cesium } from '@dc-modules/namespace'
  6. import State from '@dc-modules/state/State'
  7. import Parse from '@dc-modules/parse/Parse'
  8. import { Util, PlotUtil } from '@dc-modules/utils'
  9. import { Transform } from '@dc-modules/transform'
  10. import Overlay from '../Overlay'
  11. const HALF_PI = Math.PI / 2
  12. class AttackArrow extends Overlay {
  13. constructor(positions) {
  14. super()
  15. this._positions = Parse.parsePositions(positions)
  16. this._delegate = new Cesium.Entity({ polygon: {} })
  17. this.headHeightFactor = 0.18
  18. this.headWidthFactor = 0.3
  19. this.neckHeightFactor = 0.85
  20. this.neckWidthFactor = 0.15
  21. this.headTailFactor = 0.8
  22. this._state = State.INITIALIZED
  23. }
  24. get type() {
  25. return Overlay.getOverlayType('attack_arrow')
  26. }
  27. set positions(positions) {
  28. this._positions = Parse.parsePositions(positions)
  29. this._delegate.polygon.hierarchy = this._getHierarchy()
  30. return this
  31. }
  32. get positions() {
  33. return this._positions
  34. }
  35. _getArrowHeadPoints(points, tailLeft, tailRight) {
  36. let len = PlotUtil.getBaseLength(points)
  37. let headHeight = len * this.headHeightFactor
  38. let headPnt = points[points.length - 1]
  39. len = PlotUtil.distance(headPnt, points[points.length - 2])
  40. let tailWidth = PlotUtil.distance(tailLeft, tailRight)
  41. if (headHeight > tailWidth * this.headTailFactor) {
  42. headHeight = tailWidth * this.headTailFactor
  43. }
  44. let headWidth = headHeight * this.headWidthFactor
  45. let neckWidth = headHeight * this.neckWidthFactor
  46. headHeight = headHeight > len ? len : headHeight
  47. let neckHeight = headHeight * this.neckHeightFactor
  48. let headEndPnt = PlotUtil.getThirdPoint(
  49. points[points.length - 2],
  50. headPnt,
  51. 0,
  52. headHeight,
  53. true
  54. )
  55. let neckEndPnt = PlotUtil.getThirdPoint(
  56. points[points.length - 2],
  57. headPnt,
  58. 0,
  59. neckHeight,
  60. true
  61. )
  62. let headLeft = PlotUtil.getThirdPoint(
  63. headPnt,
  64. headEndPnt,
  65. HALF_PI,
  66. headWidth,
  67. false
  68. )
  69. let headRight = PlotUtil.getThirdPoint(
  70. headPnt,
  71. headEndPnt,
  72. HALF_PI,
  73. headWidth,
  74. true
  75. )
  76. let neckLeft = PlotUtil.getThirdPoint(
  77. headPnt,
  78. neckEndPnt,
  79. HALF_PI,
  80. neckWidth,
  81. false
  82. )
  83. let neckRight = PlotUtil.getThirdPoint(
  84. headPnt,
  85. neckEndPnt,
  86. HALF_PI,
  87. neckWidth,
  88. true
  89. )
  90. return [neckLeft, headLeft, headPnt, headRight, neckRight]
  91. }
  92. _getArrowBodyPoints(points, neckLeft, neckRight, tailWidthFactor) {
  93. let allLen = PlotUtil.wholeDistance(points)
  94. let len = PlotUtil.getBaseLength(points)
  95. let tailWidth = len * tailWidthFactor
  96. let neckWidth = PlotUtil.distance(neckLeft, neckRight)
  97. let widthDif = (tailWidth - neckWidth) / 2
  98. let tempLen = 0
  99. let leftBodyPnts = []
  100. let rightBodyPnts = []
  101. for (let i = 1; i < points.length - 1; i++) {
  102. let angle =
  103. PlotUtil.getAngleOfThreePoints(
  104. points[i - 1],
  105. points[i],
  106. points[i + 1]
  107. ) / 2
  108. tempLen += PlotUtil.distance(points[i - 1], points[i])
  109. let w = (tailWidth / 2 - (tempLen / allLen) * widthDif) / Math.sin(angle)
  110. let left = PlotUtil.getThirdPoint(
  111. points[i - 1],
  112. points[i],
  113. Math.PI - angle,
  114. w,
  115. true
  116. )
  117. let right = PlotUtil.getThirdPoint(
  118. points[i - 1],
  119. points[i],
  120. angle,
  121. w,
  122. false
  123. )
  124. leftBodyPnts.push(left)
  125. rightBodyPnts.push(right)
  126. }
  127. return leftBodyPnts.concat(rightBodyPnts)
  128. }
  129. _getHierarchy() {
  130. let pnts = Parse.parsePolygonCoordToArray(this._positions)[0]
  131. let tailLeft = pnts[0]
  132. let tailRight = pnts[1]
  133. if (PlotUtil.isClockWise(pnts[0], pnts[1], pnts[2])) {
  134. tailLeft = pnts[1]
  135. tailRight = pnts[0]
  136. }
  137. let midTail = PlotUtil.mid(tailLeft, tailRight)
  138. let bonePnts = [midTail].concat(pnts.slice(2))
  139. // 计算箭头
  140. let headPnts = this._getArrowHeadPoints(bonePnts, tailLeft, tailRight)
  141. let neckLeft = headPnts[0]
  142. let neckRight = headPnts[4]
  143. let tailWidthFactor =
  144. PlotUtil.distance(tailLeft, tailRight) / PlotUtil.getBaseLength(bonePnts)
  145. // 计算箭身
  146. let bodyPnts = this._getArrowBodyPoints(
  147. bonePnts,
  148. neckLeft,
  149. neckRight,
  150. tailWidthFactor
  151. )
  152. // 整合
  153. let count = bodyPnts.length
  154. let leftPnts = [tailLeft].concat(bodyPnts.slice(0, count / 2))
  155. leftPnts.push(neckLeft)
  156. let rightPnts = [tailRight].concat(bodyPnts.slice(count / 2, count))
  157. rightPnts.push(neckRight)
  158. leftPnts = PlotUtil.getQBSplinePoints(leftPnts)
  159. rightPnts = PlotUtil.getQBSplinePoints(rightPnts)
  160. return new Cesium.PolygonHierarchy(
  161. Transform.transformWGS84ArrayToCartesianArray(
  162. Parse.parsePositions(leftPnts.concat(headPnts, rightPnts.reverse()))
  163. )
  164. )
  165. }
  166. _mountedHook() {
  167. /**
  168. * set the location
  169. */
  170. this.positions = this._positions
  171. }
  172. /**
  173. *
  174. * @param text
  175. * @param textStyle
  176. * @returns {AttackArrow}
  177. */
  178. setLabel(text, textStyle) {
  179. return this
  180. }
  181. /**
  182. * Sets Style
  183. * @param style
  184. * @returns {AttackArrow}
  185. */
  186. setStyle(style) {
  187. if (Object.keys(style).length === 0) {
  188. return this
  189. }
  190. delete style['positions']
  191. this._style = style
  192. Util.merge(this._delegate.polygon, this._style)
  193. return this
  194. }
  195. }
  196. Overlay.registerType('attack_arrow')
  197. export default AttackArrow