ExtensionMethods.cs 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. namespace UnityEngine.U2D.Animation.TriangleNet
  2. .Geometry
  3. {
  4. using System;
  5. using Animation.TriangleNet.Meshing;
  6. internal static class ExtensionMethods
  7. {
  8. #region IPolygon extensions
  9. /// <summary>
  10. /// Triangulates a polygon.
  11. /// </summary>
  12. internal static IMesh Triangulate(this IPolygon polygon)
  13. {
  14. return (new GenericMesher()).Triangulate(polygon, null, null);
  15. }
  16. /// <summary>
  17. /// Triangulates a polygon, applying constraint options.
  18. /// </summary>
  19. /// <param name="options">Constraint options.</param>
  20. internal static IMesh Triangulate(this IPolygon polygon, ConstraintOptions options)
  21. {
  22. return (new GenericMesher()).Triangulate(polygon, options, null);
  23. }
  24. /// <summary>
  25. /// Triangulates a polygon, applying quality options.
  26. /// </summary>
  27. /// <param name="quality">Quality options.</param>
  28. internal static IMesh Triangulate(this IPolygon polygon, QualityOptions quality)
  29. {
  30. return (new GenericMesher()).Triangulate(polygon, null, quality);
  31. }
  32. /// <summary>
  33. /// Triangulates a polygon, applying quality and constraint options.
  34. /// </summary>
  35. /// <param name="options">Constraint options.</param>
  36. /// <param name="quality">Quality options.</param>
  37. internal static IMesh Triangulate(this IPolygon polygon, ConstraintOptions options, QualityOptions quality)
  38. {
  39. return (new GenericMesher()).Triangulate(polygon, options, quality);
  40. }
  41. /// <summary>
  42. /// Triangulates a polygon, applying quality and constraint options.
  43. /// </summary>
  44. /// <param name="options">Constraint options.</param>
  45. /// <param name="quality">Quality options.</param>
  46. /// <param name="triangulator">The triangulation algorithm.</param>
  47. internal static IMesh Triangulate(this IPolygon polygon, ConstraintOptions options, QualityOptions quality,
  48. ITriangulator triangulator)
  49. {
  50. return (new GenericMesher(triangulator)).Triangulate(polygon, options, quality);
  51. }
  52. #endregion
  53. #region Rectangle extensions
  54. #endregion
  55. #region ITriangle extensions
  56. /// <summary>
  57. /// Test whether a given point lies inside a triangle or not.
  58. /// </summary>
  59. /// <param name="p">Point to locate.</param>
  60. /// <returns>True, if point is inside or on the edge of this triangle.</returns>
  61. internal static bool Contains(this ITriangle triangle, Point p)
  62. {
  63. return Contains(triangle, p.X, p.Y);
  64. }
  65. /// <summary>
  66. /// Test whether a given point lies inside a triangle or not.
  67. /// </summary>
  68. /// <param name="x">Point to locate.</param>
  69. /// <param name="y">Point to locate.</param>
  70. /// <returns>True, if point is inside or on the edge of this triangle.</returns>
  71. internal static bool Contains(this ITriangle triangle, double x, double y)
  72. {
  73. var t0 = triangle.GetVertex(0);
  74. var t1 = triangle.GetVertex(1);
  75. var t2 = triangle.GetVertex(2);
  76. // TODO: no need to create new Point instances here
  77. Point d0 = new Point(t1.X - t0.X, t1.Y - t0.Y);
  78. Point d1 = new Point(t2.X - t0.X, t2.Y - t0.Y);
  79. Point d2 = new Point(x - t0.X, y - t0.Y);
  80. // crossproduct of (0, 0, 1) and d0
  81. Point c0 = new Point(-d0.Y, d0.X);
  82. // crossproduct of (0, 0, 1) and d1
  83. Point c1 = new Point(-d1.Y, d1.X);
  84. // Linear combination d2 = s * d0 + v * d1.
  85. //
  86. // Multiply both sides of the equation with c0 and c1
  87. // and solve for s and v respectively
  88. //
  89. // s = d2 * c1 / d0 * c1
  90. // v = d2 * c0 / d1 * c0
  91. double s = DotProduct(d2, c1) / DotProduct(d0, c1);
  92. double v = DotProduct(d2, c0) / DotProduct(d1, c0);
  93. if (s >= 0 && v >= 0 && ((s + v) <= 1))
  94. {
  95. // Point is inside or on the edge of this triangle.
  96. return true;
  97. }
  98. return false;
  99. }
  100. internal static Rectangle Bounds(this ITriangle triangle)
  101. {
  102. var bounds = new Rectangle();
  103. for (int i = 0; i < 3; i++)
  104. {
  105. bounds.Expand(triangle.GetVertex(i));
  106. }
  107. return bounds;
  108. }
  109. #endregion
  110. #region Helper methods
  111. internal static double DotProduct(Point p, Point q)
  112. {
  113. return p.X * q.X + p.Y * q.Y;
  114. }
  115. #endregion
  116. }
  117. }