LineSegment2D.cs 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. namespace bbiwarg.Utility
  7. {
  8. class LineSegment2D
  9. {
  10. public Vector2D P1 { get; private set; }
  11. public Vector2D P2 { get; private set; }
  12. public Vector2D Direction { get { return Line.Direction; } }
  13. public Line2D Line { get; private set; }
  14. public float Length { get; private set; }
  15. public LineSegment2D(Vector2D p1, Vector2D p2)
  16. {
  17. //endpoints
  18. P1 = p1;
  19. P2 = p2;
  20. Line = new Line2D(P1, P2 - P1);
  21. Length = P1.getDistanceTo(P2);
  22. }
  23. public float getParallelDistanceTo(LineSegment2D line)
  24. {
  25. if (Line.onSide(line.P1) != Line.onSide(line.P2)) return 0;
  26. Vector2D a1 = Line.projectToLine(line.P1);
  27. Vector2D a2 = Line.projectToLine(line.P2);
  28. float distanceA1 = a1.getDistanceTo(line.P1);
  29. float distanceA2 = a2.getDistanceTo(line.P2);
  30. return Math.Min(distanceA1, distanceA2);
  31. }
  32. public float getVerticalDistanceTo(LineSegment2D line)
  33. {
  34. Vector2D a1 = Line.projectToLine(line.P1);
  35. Vector2D a2 = Line.projectToLine(line.P2);
  36. if (P1.isInBox(a1, a2) || P2.isInBox(a1, a2)) return 0;
  37. float distanceP1A1 = P1.getDistanceTo(a1);
  38. float distanceP1A2 = P1.getDistanceTo(a2);
  39. float distanceP2A1 = P2.getDistanceTo(a1);
  40. float distanceP2A2 = P2.getDistanceTo(a2);
  41. return Math.Min(Math.Min(distanceP1A1, distanceP1A2), Math.Min(distanceP2A1, distanceP2A2));
  42. }
  43. public float getDistanceTo(Vector2D point)
  44. {
  45. // http://stackoverflow.com/questions/849211/shortest-distance-between-a-point-and-a-line-segment
  46. float l2 = (P1 - P2).dotProduct(P1 - P2); // i.e. |w-v|^2 - avoid a sqrt
  47. if (l2 == 0.0)
  48. return point.getDistanceTo(P1); // v == w case
  49. // Consider the line extending the segment, parameterized as v + t (w - v).
  50. // We find projection of point p onto the line.
  51. // It falls where t = [(p-v) . (w-v)] / |w-v|^2
  52. float t = (point - P1).dotProduct(P2 - P1) / l2;
  53. if (t < 0.0)
  54. return point.getDistanceTo(P1); // Beyond the 'v' end of the segment
  55. else if (t > 1.0)
  56. return point.getDistanceTo(P2); // Beyond the 'w' end of the segment
  57. Vector2D projection = P1 + t * (P2 - P1); // Projection falls on the segment
  58. return point.getDistanceTo(projection);
  59. }
  60. public override string ToString()
  61. {
  62. return (int)P1.X + "|" + (int)P1.Y + " --- " + (int)P2.X + "|" + (int)P2.Y;
  63. }
  64. }
  65. }