Updated Physics Methods

This commit is contained in:
Syntriax 2023-12-06 11:24:49 +03:00
parent 8a2e15e6f0
commit 21b7a0b2f6
1 changed files with 36 additions and 15 deletions

View File

@ -7,6 +7,7 @@ using Microsoft.Xna.Framework;
namespace Syntriax.Engine.Physics2D; namespace Syntriax.Engine.Physics2D;
public record Line(Vector2 From, Vector2 To); public record Line(Vector2 From, Vector2 To);
public record LineEquation(float Slope, float OffsetY);
public record Triangle(Vector2 A, Vector2 B, Vector2 C); public record Triangle(Vector2 A, Vector2 B, Vector2 C);
public record Circle(Vector2 Center, double Radius); public record Circle(Vector2 Center, double Radius);
@ -16,14 +17,14 @@ public static class PhysicsMath
=> ((q0.X - p0.X) * (p1.Y - p0.Y) - (q0.Y - p0.Y) * (p1.X - p0.X)) / => ((q0.X - p0.X) * (p1.Y - p0.Y) - (q0.Y - p0.Y) * (p1.X - p0.X)) /
((q1.Y - q0.Y) * (p1.X - p0.X) - (q1.X - q0.X) * (p1.Y - p0.Y)); ((q1.Y - q0.Y) * (p1.X - p0.X) - (q1.X - q0.X) * (p1.Y - p0.Y));
public static float IntersectionParameterT(Line l1, Line l2) public static float IntersectionParameterT(this Line l1, Line l2)
=> ((l2.From.X - l1.From.X) * (l1.To.Y - l1.From.Y) - (l2.From.Y - l1.From.Y) * (l1.To.X - l1.From.X)) / => ((l2.From.X - l1.From.X) * (l1.To.Y - l1.From.Y) - (l2.From.Y - l1.From.Y) * (l1.To.X - l1.From.X)) /
((l2.To.Y - l2.From.Y) * (l1.To.X - l1.From.X) - (l2.To.X - l2.From.X) * (l1.To.Y - l1.From.Y)); ((l2.To.Y - l2.From.Y) * (l1.To.X - l1.From.X) - (l2.To.X - l2.From.X) * (l1.To.Y - l1.From.Y));
public static Vector2 GetIntersectionPoint(Line l1, Line l2) public static Vector2 IntersectionPoint(this Line l1, Line l2)
=> Vector2.Lerp(l1.From, l1.To, IntersectionParameterT(l1, l2)); => Vector2.Lerp(l1.From, l1.To, IntersectionParameterT(l1, l2));
public static Vector2 ClosestPointOnLine(Vector2 point, Line line) public static Vector2 ClosestPointTo(this Line line, Vector2 point)
{ {
// Convert edge points to vectors // Convert edge points to vectors
var edgeVector = new Vector2(line.To.X - line.From.X, line.To.Y - line.From.Y); var edgeVector = new Vector2(line.To.X - line.From.X, line.To.Y - line.From.Y);
@ -42,14 +43,14 @@ public static class PhysicsMath
return new Vector2((float)closestX, (float)closestY); return new Vector2((float)closestX, (float)closestY);
} }
public static double GetArea(Triangle triangle) public static double GetArea(this Triangle triangle)
{ {
return Math.Abs((triangle.A.X * (triangle.B.Y - triangle.C.Y) + return Math.Abs((triangle.A.X * (triangle.B.Y - triangle.C.Y) +
triangle.B.X * (triangle.C.Y - triangle.A.Y) + triangle.B.X * (triangle.C.Y - triangle.A.Y) +
triangle.C.X * (triangle.A.Y - triangle.B.Y)) * .5f); triangle.C.X * (triangle.A.Y - triangle.B.Y)) * .5f);
} }
public static bool IsInTriangle(Vector2 point, Triangle triangle) public static bool IsPointInside(this Triangle triangle, Vector2 point)
{ {
double A = GetArea(triangle); double A = GetArea(triangle);
/* Calculate area of triangle ABC */ /* Calculate area of triangle ABC */
@ -99,7 +100,7 @@ public static class PhysicsMath
return (val > 0) ? 1 : 2; // clock or counterclock wise return (val > 0) ? 1 : 2; // clock or counterclock wise
} }
public static bool DoIntersect(Line l1, Line l2) public static bool Intersects(this Line l1, Line l2)
{ {
int o1 = Orientation(l1.From, l1.To, l2.From); int o1 = Orientation(l1.From, l1.To, l2.From);
int o2 = Orientation(l1.From, l1.To, l2.To); int o2 = Orientation(l1.From, l1.To, l2.To);
@ -117,19 +118,19 @@ public static class PhysicsMath
return false; return false;
} }
public static bool DoIntersect(Line l1, Line l2, [NotNullWhen(returnValue: true)] out Vector2? point) public static bool Intersects(this Line l1, Line l2, [NotNullWhen(returnValue: true)] out Vector2? point)
{ {
point = null; point = null;
bool result = DoIntersect(l1, l2); bool result = Intersects(l1, l2);
if (result) if (result)
point = GetIntersectionPoint(l1, l2); point = IntersectionPoint(l1, l2);
return result; return result;
} }
public static Circle GetCircumCircle(Triangle triangle) public static Circle ToCircumCircle(this Triangle triangle)
{ {
Vector2 midAB = (triangle.A + triangle.B) / 2; Vector2 midAB = (triangle.A + triangle.B) / 2;
Vector2 midBC = (triangle.B + triangle.C) / 2; Vector2 midBC = (triangle.B + triangle.C) / 2;
@ -150,7 +151,7 @@ public static class PhysicsMath
return new(center, Vector2.Distance(center, triangle.A)); return new(center, Vector2.Distance(center, triangle.A));
} }
public static Triangle GetSuperTriangle(IList<Vector2> vertices) public static Triangle ToSuperTriangle(IList<Vector2> vertices)
{ {
double minX = double.MaxValue, minY = double.MaxValue; double minX = double.MaxValue, minY = double.MaxValue;
double maxX = double.MinValue, maxY = double.MinValue; double maxX = double.MinValue, maxY = double.MinValue;
@ -176,14 +177,14 @@ public static class PhysicsMath
return new Triangle(p1, p2, p3); return new Triangle(p1, p2, p3);
} }
public static List<Line> GetLines(IList<Vector2> vertices) public static List<Line> ToLines(IList<Vector2> vertices)
{ {
List<Line> lines = new List<Line>(vertices.Count - 1); List<Line> lines = new List<Line>(vertices.Count - 1);
GetLines(vertices, lines); ToLines(vertices, lines);
return lines; return lines;
} }
public static void GetLines(IList<Vector2> vertices, IList<Line> lines) public static void ToLines(IList<Vector2> vertices, IList<Line> lines)
{ {
lines.Clear(); lines.Clear();
for (int i = 0; i < vertices.Count - 1; i++) for (int i = 0; i < vertices.Count - 1; i++)
@ -191,7 +192,7 @@ public static class PhysicsMath
lines.Add(new(vertices[^1], vertices[0])); lines.Add(new(vertices[^1], vertices[0]));
} }
public static bool DoesLineExistInVertices(Line lineToCheck, List<Vector2> vertices) public static bool ExistIn(Line lineToCheck, List<Vector2> vertices)
{ {
for (int i = 0; i < vertices.Count - 1; i++) for (int i = 0; i < vertices.Count - 1; i++)
{ {
@ -207,4 +208,24 @@ public static class PhysicsMath
if (lineToCheck.From == vertexLast && lineToCheck.To == vertexFirst) return true; if (lineToCheck.From == vertexLast && lineToCheck.To == vertexFirst) return true;
return false; return false;
} }
public static bool LaysOn(this Vector2 point, Line line)
{
LineEquation lineEquation = line.ToLineEquation();
// y = mx + b
float y = lineEquation.Slope * point.X + lineEquation.OffsetY;
return y == point.Y;
}
public static LineEquation ToLineEquation(this Line line)
{
Vector2 slopeVector = line.To - line.From;
float slope = slopeVector.Y / slopeVector.X;
float yOffset = line.From.Y - (slope * line.From.X);
return new LineEquation(slope, yOffset);
}
} }