using UnityEngine; namespace BrainFailProductions.PolyFew.AsImpL.MathUtil { /// /// Collection of useful mathematical methods. /// public static class MathUtility { /// /// Clamp list indices. /// /// Index to be clamped. /// Size of the list. /// /// /// Will even work if index is larger/smaller than listSize, so can loop multiple times /// From https://www.habrador.com/tutorials/math/9-useful-algorithms/ /// public static int ClampListIndex(int index, int listSize) { index = ((index % listSize) + listSize) % listSize; return index; } //p is the testpoint, and the other points are corners in the triangle /// /// Check if a point is inside a triangle. /// /// First corner in the triangle. /// Second corner in the triangle. /// Third corner in the triangle. /// Test point /// The result is true if the test point is inside the triangle. /// /// From https://www.habrador.com/tutorials/math/9-useful-algorithms/ /// http://totologic.blogspot.se/2014/01/accurate-point-in-triangle-test.html /// public static bool IsPointInTriangle(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p) { bool isWithinTriangle = false; //Based on Barycentric coordinates float denominator = ((p2.y - p3.y) * (p1.x - p3.x) + (p3.x - p2.x) * (p1.y - p3.y)); float a = ((p2.y - p3.y) * (p.x - p3.x) + (p3.x - p2.x) * (p.y - p3.y)) / denominator; float b = ((p3.y - p1.y) * (p.x - p3.x) + (p1.x - p3.x) * (p.y - p3.y)) / denominator; float c = 1 - a - b; //The point is within the triangle if (a > 0f && a < 1f && b > 0f && b < 1f && c > 0f && c < 1f) { isWithinTriangle = true; } return isWithinTriangle; } /// /// Check if a triangle oriented clockwise or counter-clockwise. /// /// First vectex in 2D /// Second vectex in 2D /// Third vectex in 2D /// True if the triangle is oriented clockwise. /// /// This comes from: /// https://www.habrador.com/tutorials/math/9-useful-algorithms/ /// https://math.stackexchange.com/questions/1324179/how-to-tell-if-3-connected-points-are-connected-clockwise-or-counter-clockwise /// https://en.wikipedia.org/wiki/Curve_orientation /// public static bool IsTriangleOrientedClockwise(Vector2 v1, Vector2 v2, Vector2 v3) { float determinant = v1.x * v2.y + v3.x * v1.y + v2.x * v3.y - v1.x * v3.y - v3.x * v2.y - v2.x * v1.y; bool isClockWise = determinant > 0f; return isClockWise; } /// /// Compute the normal of a vertex of a triangle defined by its 3 vertices. /// /// Vertex of the triangle where the normal is coputed. /// Next vertex (counter-clockwise) /// Previous vertex (counter-clockwise) /// The computed normal. public static Vector3 ComputeNormal(Vector3 vert, Vector3 vNext, Vector3 vPrev) { Vector3 n = Vector3.Cross(vPrev - vert, vNext - vert); n.Normalize(); return n; } } }