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;
}
}
}