Files
bansonic_beta_main/Assets/openFracture/OpenFracture-main/Runtime/Scripts/Utilities/MathUtils.cs
T

129 lines
5.5 KiB
C#

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public static class MathUtils
{
/// <summary>
/// Returns true if the quad specified by the two diagonals a1->a2 and b1->b2 is convex
/// Quad is convex if a1->a2 and b1->b2 intersect each other
/// </summary>
/// <param name="a1">Start point of diagonal A</param>
/// <param name="a2">End point of diagonal A</param>
/// <param name="b1">Start point of diagonal B</param>
/// <param name="b2">End point of diagonal B</param>
/// <returns></returns>
public static bool IsQuadConvex(Vector2 a1, Vector2 a2, Vector2 b1, Vector2 b2)
{
return LinesIntersectInternal(a1, a2, b1, b2, true);
}
/// <summary>
/// Returns true lines a1->a2 and b1->b2 is intersect
/// </summary>
/// <param name="a1">Start point of line A</param>
/// <param name="a2">End point of line A</param>
/// <param name="b1">Start point of line B</param>
/// <param name="b2">End point of line B</param>
/// <returns></returns>
public static bool LinesIntersect(Vector2 a1, Vector2 a2, Vector2 b1, Vector2 b2)
{
return LinesIntersectInternal(a1, a2, b1, b2, false);
}
/// <summary>
/// Returns true lines a1->a2 and b1->b2 is intersect
/// </summary>
/// <param name="a1">Start point of line A</param>
/// <param name="a2">End point of line A</param>
/// <param name="b1">Start point of line B</param>
/// <param name="b2">End point of line B</param>
/// <returns></returns>
private static bool LinesIntersectInternal(Vector2 a1, Vector2 a2, Vector2 b1, Vector2 b2, bool includeSharedEndpoints)
{
Vector2 a12 = new Vector2(a2.x - a1.x, a2.y - a1.y);
Vector2 b12 = new Vector2(b2.x - b1.x, b2.y - b1.y);
// If any of the vertices are shared between the two diagonals,
// the quad collapses into a triangle and is convex by default.
if (a1 == b1 || a1 == b2 || a2 == b1 || a2 == b2)
{
return includeSharedEndpoints;
}
else
{
// Compute cross product between each point and the opposite diagonal
// Look at sign of the Z component to see which side of line point is on
float a1xb = (a1.x - b1.x) * b12.y - (a1.y - b1.y) * b12.x;
float a2xb = (a2.x - b1.x) * b12.y - (a2.y - b1.y) * b12.x;
float b1xa = (b1.x - a1.x) * a12.y - (b1.y - a1.y) * a12.x;
float b2xa = (b2.x - a1.x) * a12.y - (b2.y - a1.y) * a12.x;
// Check that the points for each diagonal lie on opposite sides of the other
// diagonal. Quad is also convex if a1/a2 lie on b1->b2 (and vice versa) since
// the shape collapses into a triangle (hence >= instead of >)
return ((a1xb >= 0 && a2xb <= 0) || (a1xb <= 0 && a2xb >= 0)) &&
((b1xa >= 0 && b2xa <= 0) || (b1xa <= 0 && b2xa >= 0));
}
}
/// <summary>
/// Determines the intersection between the line segment a->b and the plane defined by the specified normal and origin point. If an intersection point exists, it is returned via the out parameter `intersection`. The parameter `s` is defined below and is used to properly interpolate normals/uvs for intersection vertices.
/// </summary>
/// <param name="a">Start point of line</param>
/// <param name="b">End point of line</param>
/// <param name="n">Plane normal</param>
/// <param name="p0">Plane origin</param>
/// <param name="x">If intersection exists, intersection point return as out parameter.</param>
/// <param name="s">Returns the parameterization of the intersection where x = a + (b - a) * s</param>
/// <returns></returns>
public static bool LinePlaneIntersection(Vector3 a,
Vector3 b,
Vector3 n,
Vector3 p0,
out Vector3 x,
out float s)
{
// Initialize out params
s = 0;
x = Vector3.zero;
// Handle degenerate cases
if (a == b)
{
return false;
}
else if (n == Vector3.zero)
{
return false;
}
// `s` is the parameter for the line segment a -> b where 0.0 <= s <= 1.0
s = Vector3.Dot(p0 - a, n) / Vector3.Dot(b - a, n);
if (s >= 0 && s <= 1)
{
x = a + (b - a) * s;
return true;
}
return false;
}
/// <summary>
/// Returns true of the point `p` is on the left side of the directed line segment `i` -> `j`
/// Use for checking if a point is inside of a triangle. Since triangle vertices oriented
/// CCW, a point on the left side of a triangle edge is "inside" that edge of the triangle.
/// </summary>
/// <param name="p">Index of test point in `points` array</param>
/// <param name="i">Index of first vertex of the edge in the `points` array</param>
/// /// <param name="j">Index of second vertex of the edge in the `points` array</param>
/// <returns>True if the point `p` is on the left side of the line `i`->`j`</returns>
public static bool IsPointOnRightSideOfLine(Vector2 a, Vector2 b, Vector2 c)
{
// The <= is essential; if it is <, the whole thing falls apart
return ((b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x)) <= 0;
}
}