You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

AttackArrow.js 5.4KB

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