RightmostEdgeFinder.js 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. import Position from '../../geomgraph/Position'
  2. import Orientation from '../../algorithm/Orientation'
  3. import Assert from '../../util/Assert'
  4. export default class RightmostEdgeFinder {
  5. constructor() {
  6. RightmostEdgeFinder.constructor_.apply(this, arguments)
  7. }
  8. static constructor_() {
  9. this._minIndex = -1
  10. this._minCoord = null
  11. this._minDe = null
  12. this._orientedDe = null
  13. }
  14. getCoordinate() {
  15. return this._minCoord
  16. }
  17. getRightmostSide(de, index) {
  18. let side = this.getRightmostSideOfSegment(de, index)
  19. if (side < 0) side = this.getRightmostSideOfSegment(de, index - 1)
  20. if (side < 0) {
  21. this._minCoord = null
  22. this.checkForRightmostCoordinate(de)
  23. }
  24. return side
  25. }
  26. findRightmostEdgeAtVertex() {
  27. const pts = this._minDe.getEdge().getCoordinates()
  28. Assert.isTrue(this._minIndex > 0 && this._minIndex < pts.length, 'rightmost point expected to be interior vertex of edge')
  29. const pPrev = pts[this._minIndex - 1]
  30. const pNext = pts[this._minIndex + 1]
  31. const orientation = Orientation.index(this._minCoord, pNext, pPrev)
  32. let usePrev = false
  33. if (pPrev.y < this._minCoord.y && pNext.y < this._minCoord.y && orientation === Orientation.COUNTERCLOCKWISE)
  34. usePrev = true
  35. else if (pPrev.y > this._minCoord.y && pNext.y > this._minCoord.y && orientation === Orientation.CLOCKWISE)
  36. usePrev = true
  37. if (usePrev)
  38. this._minIndex = this._minIndex - 1
  39. }
  40. getRightmostSideOfSegment(de, i) {
  41. const e = de.getEdge()
  42. const coord = e.getCoordinates()
  43. if (i < 0 || i + 1 >= coord.length) return -1
  44. if (coord[i].y === coord[i + 1].y) return -1
  45. let pos = Position.LEFT
  46. if (coord[i].y < coord[i + 1].y) pos = Position.RIGHT
  47. return pos
  48. }
  49. getEdge() {
  50. return this._orientedDe
  51. }
  52. checkForRightmostCoordinate(de) {
  53. const coord = de.getEdge().getCoordinates()
  54. for (let i = 0; i < coord.length - 1; i++)
  55. if (this._minCoord === null || coord[i].x > this._minCoord.x) {
  56. this._minDe = de
  57. this._minIndex = i
  58. this._minCoord = coord[i]
  59. }
  60. }
  61. findRightmostEdgeAtNode() {
  62. const node = this._minDe.getNode()
  63. const star = node.getEdges()
  64. this._minDe = star.getRightmostEdge()
  65. if (!this._minDe.isForward()) {
  66. this._minDe = this._minDe.getSym()
  67. this._minIndex = this._minDe.getEdge().getCoordinates().length - 1
  68. }
  69. }
  70. findEdge(dirEdgeList) {
  71. for (let i = dirEdgeList.iterator(); i.hasNext(); ) {
  72. const de = i.next()
  73. if (!de.isForward()) continue
  74. this.checkForRightmostCoordinate(de)
  75. }
  76. Assert.isTrue(this._minIndex !== 0 || this._minCoord.equals(this._minDe.getCoordinate()), 'inconsistency in rightmost processing')
  77. if (this._minIndex === 0)
  78. this.findRightmostEdgeAtNode()
  79. else
  80. this.findRightmostEdgeAtVertex()
  81. this._orientedDe = this._minDe
  82. const rightmostSide = this.getRightmostSide(this._minDe, this._minIndex)
  83. if (rightmostSide === Position.LEFT)
  84. this._orientedDe = this._minDe.getSym()
  85. }
  86. }