LineSegment.cs 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. using Microsoft.Xna.Framework;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Text;
  5. namespace MonoGame.Extended.Triangulation
  6. {
  7. /// <summary>
  8. /// MIT Licensed: https://github.com/nickgravelyn/Triangulator
  9. /// </summary>
  10. struct LineSegment
  11. {
  12. public Vertex A;
  13. public Vertex B;
  14. public LineSegment(Vertex a, Vertex b)
  15. {
  16. A = a;
  17. B = b;
  18. }
  19. public float? IntersectsWithRay(Vector2 origin, Vector2 direction)
  20. {
  21. float largestDistance = MathHelper.Max(A.Position.X - origin.X, B.Position.X - origin.X) * 2f;
  22. LineSegment raySegment = new LineSegment(new Vertex(origin, 0), new Vertex(origin + (direction * largestDistance), 0));
  23. Vector2? intersection = FindIntersection(this, raySegment);
  24. float? value = null;
  25. if (intersection != null)
  26. value = Vector2.Distance(origin, intersection.Value);
  27. return value;
  28. }
  29. public static Vector2? FindIntersection(LineSegment a, LineSegment b)
  30. {
  31. float x1 = a.A.Position.X;
  32. float y1 = a.A.Position.Y;
  33. float x2 = a.B.Position.X;
  34. float y2 = a.B.Position.Y;
  35. float x3 = b.A.Position.X;
  36. float y3 = b.A.Position.Y;
  37. float x4 = b.B.Position.X;
  38. float y4 = b.B.Position.Y;
  39. float denom = (y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1);
  40. float uaNum = (x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3);
  41. float ubNum = (x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3);
  42. float ua = uaNum / denom;
  43. float ub = ubNum / denom;
  44. if (MathHelper.Clamp(ua, 0f, 1f) != ua || MathHelper.Clamp(ub, 0f, 1f) != ub)
  45. return null;
  46. return a.A.Position + (a.B.Position - a.A.Position) * ua;
  47. }
  48. }
  49. }