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.

DoubleArrowGraphics.js 7.3KB

4 jaren geleden
4 jaren geleden
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. /**
  2. * @Author: Caven
  3. * @Date: 2020-08-30 16:27:29
  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 DoubleArrowGraphics {
  11. constructor(options) {
  12. this._positions = options?.positions || []
  13. this.headHeightFactor = 0.25
  14. this.headWidthFactor = 0.3
  15. this.neckHeightFactor = 0.85
  16. this.neckWidthFactor = 0.15
  17. }
  18. set positions(positions) {
  19. this._positions = positions
  20. }
  21. get positions() {
  22. return this._positions
  23. }
  24. get hierarchy() {
  25. return this._createHierarchy()
  26. }
  27. _getArrowPoints(pnt1, pnt2, pnt3, clockWise) {
  28. let midPnt = PlotUtil.mid(pnt1, pnt2)
  29. let len = PlotUtil.distance(midPnt, pnt3)
  30. let midPnt1 = PlotUtil.getThirdPoint(pnt3, midPnt, 0, len * 0.3, true)
  31. let midPnt2 = PlotUtil.getThirdPoint(pnt3, midPnt, 0, len * 0.5, true)
  32. midPnt1 = PlotUtil.getThirdPoint(
  33. midPnt,
  34. midPnt1,
  35. HALF_PI,
  36. len / 5,
  37. clockWise
  38. )
  39. midPnt2 = PlotUtil.getThirdPoint(
  40. midPnt,
  41. midPnt2,
  42. HALF_PI,
  43. len / 4,
  44. clockWise
  45. )
  46. let points = [midPnt, midPnt1, midPnt2, pnt3]
  47. // 计算箭头部分
  48. let arrowPnts = this._getArrowHeadPoints(points)
  49. let neckLeftPoint = arrowPnts[0]
  50. let neckRightPoint = arrowPnts[4]
  51. // 计算箭身部分
  52. let tailWidthFactor =
  53. PlotUtil.distance(pnt1, pnt2) / PlotUtil.getBaseLength(points) / 2
  54. let bodyPnts = this._getArrowBodyPoints(
  55. points,
  56. neckLeftPoint,
  57. neckRightPoint,
  58. tailWidthFactor
  59. )
  60. let n = bodyPnts.length
  61. let lPoints = bodyPnts.slice(0, n / 2)
  62. let rPoints = bodyPnts.slice(n / 2, n)
  63. lPoints.push(neckLeftPoint)
  64. rPoints.push(neckRightPoint)
  65. lPoints = lPoints.reverse()
  66. lPoints.push(pnt2)
  67. rPoints = rPoints.reverse()
  68. rPoints.push(pnt1)
  69. return lPoints.reverse().concat(arrowPnts, rPoints)
  70. }
  71. _getArrowHeadPoints(points) {
  72. let len = PlotUtil.getBaseLength(points)
  73. let headHeight = len * this.headHeightFactor
  74. let headPnt = points[points.length - 1]
  75. let headWidth = headHeight * this.headWidthFactor
  76. let neckWidth = headHeight * this.neckWidthFactor
  77. let neckHeight = headHeight * this.neckHeightFactor
  78. let headEndPnt = PlotUtil.getThirdPoint(
  79. points[points.length - 2],
  80. headPnt,
  81. 0,
  82. headHeight,
  83. true
  84. )
  85. let neckEndPnt = PlotUtil.getThirdPoint(
  86. points[points.length - 2],
  87. headPnt,
  88. 0,
  89. neckHeight,
  90. true
  91. )
  92. let headLeft = PlotUtil.getThirdPoint(
  93. headPnt,
  94. headEndPnt,
  95. HALF_PI,
  96. headWidth,
  97. false
  98. )
  99. let headRight = PlotUtil.getThirdPoint(
  100. headPnt,
  101. headEndPnt,
  102. HALF_PI,
  103. headWidth,
  104. true
  105. )
  106. let neckLeft = PlotUtil.getThirdPoint(
  107. headPnt,
  108. neckEndPnt,
  109. HALF_PI,
  110. neckWidth,
  111. false
  112. )
  113. let neckRight = PlotUtil.getThirdPoint(
  114. headPnt,
  115. neckEndPnt,
  116. HALF_PI,
  117. neckWidth,
  118. true
  119. )
  120. return [neckLeft, headLeft, headPnt, headRight, neckRight]
  121. }
  122. _getArrowBodyPoints(points, neckLeft, neckRight, tailWidthFactor) {
  123. let allLen = PlotUtil.wholeDistance(points)
  124. let len = PlotUtil.getBaseLength(points)
  125. let tailWidth = len * tailWidthFactor
  126. let neckWidth = PlotUtil.distance(neckLeft, neckRight)
  127. let widthDif = (tailWidth - neckWidth) / 2
  128. let tempLen = 0
  129. let leftBodyPnts = []
  130. let rightBodyPnts = []
  131. for (let i = 1; i < points.length - 1; i++) {
  132. let angle =
  133. PlotUtil.getAngleOfThreePoints(
  134. points[i - 1],
  135. points[i],
  136. points[i + 1]
  137. ) / 2
  138. tempLen += PlotUtil.distance(points[i - 1], points[i])
  139. let w = (tailWidth / 2 - (tempLen / allLen) * widthDif) / Math.sin(angle)
  140. let left = PlotUtil.getThirdPoint(
  141. points[i - 1],
  142. points[i],
  143. Math.PI - angle,
  144. w,
  145. true
  146. )
  147. let right = PlotUtil.getThirdPoint(
  148. points[i - 1],
  149. points[i],
  150. angle,
  151. w,
  152. false
  153. )
  154. leftBodyPnts.push(left)
  155. rightBodyPnts.push(right)
  156. }
  157. return leftBodyPnts.concat(rightBodyPnts)
  158. }
  159. _getTempPoint4(linePnt1, linePnt2, point) {
  160. let midPnt = PlotUtil.mid(linePnt1, linePnt2)
  161. let len = PlotUtil.distance(midPnt, point)
  162. let angle = PlotUtil.getAngleOfThreePoints(linePnt1, midPnt, point)
  163. let symPnt, distance1, distance2, mid
  164. if (angle < HALF_PI) {
  165. distance1 = len * Math.sin(angle)
  166. distance2 = len * Math.cos(angle)
  167. mid = PlotUtil.getThirdPoint(linePnt1, midPnt, HALF_PI, distance1, false)
  168. symPnt = PlotUtil.getThirdPoint(midPnt, mid, HALF_PI, distance2, true)
  169. } else if (angle >= HALF_PI && angle < Math.PI) {
  170. distance1 = len * Math.sin(Math.PI - angle)
  171. distance2 = len * Math.cos(Math.PI - angle)
  172. mid = PlotUtil.getThirdPoint(linePnt1, midPnt, HALF_PI, distance1, false)
  173. symPnt = PlotUtil.getThirdPoint(midPnt, mid, HALF_PI, distance2, false)
  174. } else if (angle >= Math.PI && angle < Math.PI * 1.5) {
  175. distance1 = len * Math.sin(angle - Math.PI)
  176. distance2 = len * Math.cos(angle - Math.PI)
  177. mid = PlotUtil.getThirdPoint(linePnt1, midPnt, HALF_PI, distance1, true)
  178. symPnt = PlotUtil.getThirdPoint(midPnt, mid, HALF_PI, distance2, true)
  179. } else {
  180. distance1 = len * Math.sin(Math.PI * 2 - angle)
  181. distance2 = len * Math.cos(Math.PI * 2 - angle)
  182. mid = PlotUtil.getThirdPoint(linePnt1, midPnt, HALF_PI, distance1, true)
  183. symPnt = PlotUtil.getThirdPoint(midPnt, mid, HALF_PI, distance2, false)
  184. }
  185. return symPnt
  186. }
  187. _createHierarchy() {
  188. let count = this._positions.length
  189. let tempPoint4 = undefined
  190. let connPoint = undefined
  191. let pnts = Parse.parsePolygonCoordToArray(
  192. Transform.transformCartesianArrayToWGS84Array(this._positions)
  193. )[0]
  194. let pnt1 = pnts[0]
  195. let pnt2 = pnts[1]
  196. let pnt3 = pnts[2]
  197. if (count === 3) tempPoint4 = this._getTempPoint4(pnt1, pnt2, pnt3)
  198. else tempPoint4 = pnts[3]
  199. if (count === 3 || count === 4) connPoint = PlotUtil.mid(pnt1, pnt2)
  200. else connPoint = pnts[4]
  201. let leftArrowPnts, rightArrowPnts
  202. if (PlotUtil.isClockWise(pnt1, pnt2, pnt3)) {
  203. leftArrowPnts = this._getArrowPoints(pnt1, connPoint, tempPoint4, false)
  204. rightArrowPnts = this._getArrowPoints(connPoint, pnt2, pnt3, true)
  205. } else {
  206. leftArrowPnts = this._getArrowPoints(pnt2, connPoint, pnt3, false)
  207. rightArrowPnts = this._getArrowPoints(connPoint, pnt1, tempPoint4, true)
  208. }
  209. let m = leftArrowPnts.length
  210. let t = (m - 5) / 2
  211. let llBodyPnts = leftArrowPnts.slice(0, t)
  212. let lArrowPnts = leftArrowPnts.slice(t, t + 5)
  213. let lrBodyPnts = leftArrowPnts.slice(t + 5, m)
  214. let rlBodyPnts = rightArrowPnts.slice(0, t)
  215. let rArrowPnts = rightArrowPnts.slice(t, t + 5)
  216. let rrBodyPnts = rightArrowPnts.slice(t + 5, m)
  217. rlBodyPnts = PlotUtil.getBezierPoints(rlBodyPnts)
  218. let bodyPnts = PlotUtil.getBezierPoints(
  219. rrBodyPnts.concat(llBodyPnts.slice(1))
  220. )
  221. lrBodyPnts = PlotUtil.getBezierPoints(lrBodyPnts)
  222. return new Cesium.PolygonHierarchy(
  223. Transform.transformWGS84ArrayToCartesianArray(
  224. Parse.parsePositions(
  225. rlBodyPnts.concat(rArrowPnts, bodyPnts, lArrowPnts, lrBodyPnts)
  226. )
  227. )
  228. )
  229. }
  230. }
  231. export default DoubleArrowGraphics