Distance.js 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. import IllegalArgumentException from '../../../../java/lang/IllegalArgumentException'
  2. import MathUtil from '../math/MathUtil'
  3. import Envelope from '../geom/Envelope'
  4. export default class Distance {
  5. static segmentToSegment(A, B, C, D) {
  6. if (A.equals(B)) return Distance.pointToSegment(A, C, D)
  7. if (C.equals(D)) return Distance.pointToSegment(D, A, B)
  8. let noIntersection = false
  9. if (!Envelope.intersects(A, B, C, D)) {
  10. noIntersection = true
  11. } else {
  12. const denom = (B.x - A.x) * (D.y - C.y) - (B.y - A.y) * (D.x - C.x)
  13. if (denom === 0) {
  14. noIntersection = true
  15. } else {
  16. const r_num = (A.y - C.y) * (D.x - C.x) - (A.x - C.x) * (D.y - C.y)
  17. const s_num = (A.y - C.y) * (B.x - A.x) - (A.x - C.x) * (B.y - A.y)
  18. const s = s_num / denom
  19. const r = r_num / denom
  20. if (r < 0 || r > 1 || s < 0 || s > 1)
  21. noIntersection = true
  22. }
  23. }
  24. if (noIntersection)
  25. return MathUtil.min(Distance.pointToSegment(A, C, D), Distance.pointToSegment(B, C, D), Distance.pointToSegment(C, A, B), Distance.pointToSegment(D, A, B))
  26. return 0.0
  27. }
  28. static pointToSegment(p, A, B) {
  29. if (A.x === B.x && A.y === B.y) return p.distance(A)
  30. const len2 = (B.x - A.x) * (B.x - A.x) + (B.y - A.y) * (B.y - A.y)
  31. const r = ((p.x - A.x) * (B.x - A.x) + (p.y - A.y) * (B.y - A.y)) / len2
  32. if (r <= 0.0) return p.distance(A)
  33. if (r >= 1.0) return p.distance(B)
  34. const s = ((A.y - p.y) * (B.x - A.x) - (A.x - p.x) * (B.y - A.y)) / len2
  35. return Math.abs(s) * Math.sqrt(len2)
  36. }
  37. static pointToLinePerpendicular(p, A, B) {
  38. const len2 = (B.x - A.x) * (B.x - A.x) + (B.y - A.y) * (B.y - A.y)
  39. const s = ((A.y - p.y) * (B.x - A.x) - (A.x - p.x) * (B.y - A.y)) / len2
  40. return Math.abs(s) * Math.sqrt(len2)
  41. }
  42. static pointToSegmentString(p, line) {
  43. if (line.length === 0) throw new IllegalArgumentException('Line array must contain at least one vertex')
  44. let minDistance = p.distance(line[0])
  45. for (let i = 0; i < line.length - 1; i++) {
  46. const dist = Distance.pointToSegment(p, line[i], line[i + 1])
  47. if (dist < minDistance)
  48. minDistance = dist
  49. }
  50. return minDistance
  51. }
  52. }