Orientation.js 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. import hasInterface from '../../../../hasInterface'
  2. import IllegalArgumentException from '../../../../java/lang/IllegalArgumentException'
  3. import CGAlgorithmsDD from './CGAlgorithmsDD'
  4. import CoordinateSequence from '../geom/CoordinateSequence'
  5. export default class Orientation {
  6. static index(p1, p2, q) {
  7. return CGAlgorithmsDD.orientationIndex(p1, p2, q)
  8. }
  9. static isCCW() {
  10. if (arguments[0] instanceof Array) {
  11. const ring = arguments[0]
  12. const nPts = ring.length - 1
  13. if (nPts < 3) throw new IllegalArgumentException('Ring has fewer than 4 points, so orientation cannot be determined')
  14. let hiPt = ring[0]
  15. let hiIndex = 0
  16. for (let i = 1; i <= nPts; i++) {
  17. const p = ring[i]
  18. if (p.y > hiPt.y) {
  19. hiPt = p
  20. hiIndex = i
  21. }
  22. }
  23. let iPrev = hiIndex
  24. do {
  25. iPrev = iPrev - 1
  26. if (iPrev < 0) iPrev = nPts
  27. } while (ring[iPrev].equals2D(hiPt) && iPrev !== hiIndex)
  28. let iNext = hiIndex
  29. do
  30. iNext = (iNext + 1) % nPts
  31. while (ring[iNext].equals2D(hiPt) && iNext !== hiIndex)
  32. const prev = ring[iPrev]
  33. const next = ring[iNext]
  34. if (prev.equals2D(hiPt) || next.equals2D(hiPt) || prev.equals2D(next)) return false
  35. const disc = Orientation.index(prev, hiPt, next)
  36. let isCCW = null
  37. if (disc === 0)
  38. isCCW = prev.x > next.x
  39. else
  40. isCCW = disc > 0
  41. return isCCW
  42. } else if (hasInterface(arguments[0], CoordinateSequence)) {
  43. const ring = arguments[0]
  44. const nPts = ring.size() - 1
  45. if (nPts < 3) throw new IllegalArgumentException('Ring has fewer than 4 points, so orientation cannot be determined')
  46. let hiPt = ring.getCoordinate(0)
  47. let hiIndex = 0
  48. for (let i = 1; i <= nPts; i++) {
  49. const p = ring.getCoordinate(i)
  50. if (p.y > hiPt.y) {
  51. hiPt = p
  52. hiIndex = i
  53. }
  54. }
  55. let prev = null
  56. let iPrev = hiIndex
  57. do {
  58. iPrev = iPrev - 1
  59. if (iPrev < 0) iPrev = nPts
  60. prev = ring.getCoordinate(iPrev)
  61. } while (prev.equals2D(hiPt) && iPrev !== hiIndex)
  62. let next = null
  63. let iNext = hiIndex
  64. do {
  65. iNext = (iNext + 1) % nPts
  66. next = ring.getCoordinate(iNext)
  67. } while (next.equals2D(hiPt) && iNext !== hiIndex)
  68. if (prev.equals2D(hiPt) || next.equals2D(hiPt) || prev.equals2D(next)) return false
  69. const disc = Orientation.index(prev, hiPt, next)
  70. let isCCW = null
  71. if (disc === 0)
  72. isCCW = prev.x > next.x
  73. else
  74. isCCW = disc > 0
  75. return isCCW
  76. }
  77. }
  78. }
  79. Orientation.CLOCKWISE = -1
  80. Orientation.RIGHT = Orientation.CLOCKWISE
  81. Orientation.COUNTERCLOCKWISE = 1
  82. Orientation.LEFT = Orientation.COUNTERCLOCKWISE
  83. Orientation.COLLINEAR = 0
  84. Orientation.STRAIGHT = Orientation.COLLINEAR