Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

AttackArrow.js 5.3KB

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