68 lines
2.3 KiB
C#
68 lines
2.3 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
|
|
using Syntriax.Engine.Core;
|
|
using Syntriax.Engine.Physics2D.Primitives;
|
|
|
|
namespace Syntriax.Engine.Physics2D;
|
|
|
|
public static class PhysicsMath
|
|
{
|
|
|
|
|
|
// Given three collinear points p, q, r, the function checks if
|
|
// point q lies on line segment 'pr'
|
|
public static bool OnSegment(Vector2D p, Vector2D q, Vector2D r)
|
|
{
|
|
if (q.X <= MathF.Max(p.X, r.X) && q.X >= MathF.Min(p.X, r.X) &&
|
|
q.Y <= MathF.Max(p.Y, r.Y) && q.Y >= MathF.Min(p.Y, r.Y))
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
// To find orientation of ordered triplet (p, q, r).
|
|
// The function returns following values
|
|
// 0 --> p, q and r are collinear
|
|
// 1 --> Clockwise
|
|
// 2 --> Counterclockwise
|
|
public static int Orientation(Vector2D p, Vector2D q, Vector2D r)
|
|
{
|
|
// See https://www.geeksforgeeks.org/orientation-3-ordered-points/
|
|
// for details of below formula.
|
|
float val = (q.Y - p.Y) * (r.X - q.X) -
|
|
(q.X - p.X) * (r.Y - q.Y);
|
|
|
|
if (val == 0) return 0; // collinear
|
|
|
|
return (val > 0) ? 1 : 2; // clock or counterclock wise
|
|
}
|
|
|
|
public static float IntersectionParameterT(Vector2D p0, Vector2D p1, Vector2D q0, Vector2D q1)
|
|
=> ((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));
|
|
|
|
|
|
public static bool ApproximatelyEquals(this float a, float b)
|
|
=> ApproximatelyEquals(a, b, float.Epsilon);
|
|
public static bool ApproximatelyEquals(this Vector2D a, Vector2D b)
|
|
=> ApproximatelyEquals(a, b, float.Epsilon);
|
|
public static bool ApproximatelyEquals(this Vector2D a, Vector2D b, float epsilon)
|
|
=> ApproximatelyEquals(a.X, b.X, epsilon) && ApproximatelyEquals(a.Y, b.Y, epsilon);
|
|
public static bool ApproximatelyEquals(this float a, float b, float epsilon)
|
|
{
|
|
if (a == b)
|
|
return true;
|
|
|
|
const float floatNormal = (1 << 23) * float.Epsilon;
|
|
float absA = MathF.Abs(a);
|
|
float absB = MathF.Abs(b);
|
|
float diff = MathF.Abs(a - b);
|
|
|
|
if (a == 0.0f || b == 0.0f || diff < floatNormal)
|
|
return diff < (epsilon * floatNormal);
|
|
|
|
return diff / MathF.Min(absA + absB, float.MaxValue) < epsilon;
|
|
}
|
|
}
|