MonotoneChainEdge.js 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. import MonotoneChainIndexer from './MonotoneChainIndexer'
  2. import Envelope from '../../geom/Envelope'
  3. export default class MonotoneChainEdge {
  4. constructor() {
  5. MonotoneChainEdge.constructor_.apply(this, arguments)
  6. }
  7. static constructor_() {
  8. this.e = null
  9. this.pts = null
  10. this.startIndex = null
  11. const e = arguments[0]
  12. this.e = e
  13. this.pts = e.getCoordinates()
  14. const mcb = new MonotoneChainIndexer()
  15. this.startIndex = mcb.getChainStartIndices(this.pts)
  16. }
  17. getCoordinates() {
  18. return this.pts
  19. }
  20. getMaxX(chainIndex) {
  21. const x1 = this.pts[this.startIndex[chainIndex]].x
  22. const x2 = this.pts[this.startIndex[chainIndex + 1]].x
  23. return x1 > x2 ? x1 : x2
  24. }
  25. getMinX(chainIndex) {
  26. const x1 = this.pts[this.startIndex[chainIndex]].x
  27. const x2 = this.pts[this.startIndex[chainIndex + 1]].x
  28. return x1 < x2 ? x1 : x2
  29. }
  30. computeIntersectsForChain() {
  31. if (arguments.length === 4) {
  32. const chainIndex0 = arguments[0], mce = arguments[1], chainIndex1 = arguments[2], si = arguments[3]
  33. this.computeIntersectsForChain(this.startIndex[chainIndex0], this.startIndex[chainIndex0 + 1], mce, mce.startIndex[chainIndex1], mce.startIndex[chainIndex1 + 1], si)
  34. } else if (arguments.length === 6) {
  35. const start0 = arguments[0], end0 = arguments[1], mce = arguments[2], start1 = arguments[3], end1 = arguments[4], ei = arguments[5]
  36. if (end0 - start0 === 1 && end1 - start1 === 1) {
  37. ei.addIntersections(this.e, start0, mce.e, start1)
  38. return null
  39. }
  40. if (!this.overlaps(start0, end0, mce, start1, end1)) return null
  41. const mid0 = Math.trunc((start0 + end0) / 2)
  42. const mid1 = Math.trunc((start1 + end1) / 2)
  43. if (start0 < mid0) {
  44. if (start1 < mid1) this.computeIntersectsForChain(start0, mid0, mce, start1, mid1, ei)
  45. if (mid1 < end1) this.computeIntersectsForChain(start0, mid0, mce, mid1, end1, ei)
  46. }
  47. if (mid0 < end0) {
  48. if (start1 < mid1) this.computeIntersectsForChain(mid0, end0, mce, start1, mid1, ei)
  49. if (mid1 < end1) this.computeIntersectsForChain(mid0, end0, mce, mid1, end1, ei)
  50. }
  51. }
  52. }
  53. overlaps(start0, end0, mce, start1, end1) {
  54. return Envelope.intersects(this.pts[start0], this.pts[end0], mce.pts[start1], mce.pts[end1])
  55. }
  56. getStartIndexes() {
  57. return this.startIndex
  58. }
  59. computeIntersects(mce, si) {
  60. for (let i = 0; i < this.startIndex.length - 1; i++)
  61. for (let j = 0; j < mce.startIndex.length - 1; j++)
  62. this.computeIntersectsForChain(i, mce, j, si)
  63. }
  64. }