sk-client/Assets/LuaFramework/Scripts/OwnTools/SpriteDeformerTool/code/MedvedyaMath.cs

212 lines
7.4 KiB
C#
Raw Permalink Normal View History

2024-07-03 18:38:10 +08:00
using UnityEngine;
namespace Game.GeometryMath
{
public struct Plane3d
{
public Vector3 position;
public Vector3 normal;
public Vector3 upAxis;
public Vector3 rightAxis;
public Plane3d(Vector3 position, Quaternion rotation)
{
this.position = position;
this.normal = rotation * Vector3.forward;
this.upAxis = rotation * Vector3.up;
this.rightAxis = rotation * Vector3.right;
}
public Vector3 rayCast(Ray ray)
{
float t = -Vector3.Dot(ray.origin - position, normal) / Vector3.Dot(ray.direction, normal);
return ray.origin + ray.direction * t;
}
public Vector3 globalToLocal(Vector3 globalPosition)
{
Vector3 p = globalPosition - position;
return new Vector3(Vector3.Dot(p, rightAxis), Vector3.Dot(p, upAxis), Vector3.Dot(p, normal));
}
}
public struct Triangle
{
static float Q(Vector2 a, Vector2 b, Vector2 t)
{
return t.x * (b.y - a.y) + t.y * (a.x - b.x) + a.y * b.x - a.x * b.y;
}
public static bool isBelongOriantByClock(Vector2 f1, Vector2 f2, Vector2 f3, Vector2 f)
{
return (Q(f1, f2, f) >= 0) && (Q(f2, f3, f) >= 0) && (Q(f3, f1, f) >= 0);
}
//wasnt tested
public static bool isBelong(Vector2 f1, Vector2 f2, Vector2 f3, Vector2 f)
{
float q1 = Q(f1, f2, f2);
float q2 = Q(f2, f3, f);
float q3 = Q(f3, f1, f);
return ((q1 >= 0f) && (q2 >= 0f) && (q3 >= 0f)) || ((q1 < 0f) && (q2 < 0f) && (q3 < 0f));
}
public static float area(Vector2 p1, Vector2 p2, Vector2 p3)
{
Vector2 v1 = p1 - p3;
Vector2 v2 = p2 - p3;
return (v1.x * v2.y - v1.y * v2.x) / 2;
}
public static Vector3 getBarycentric(Vector2 v1, Vector2 v2, Vector2 v3, Vector2 p)
{
Vector3 B = new Vector3();
B.x = ((v2.y - v3.y) * (p.x - v3.x) + (v3.x - v2.x) * (p.y - v3.y)) /
((v2.y - v3.y) * (v1.x - v3.x) + (v3.x - v2.x) * (v1.y - v3.y));
B.y = ((v3.y - v1.y) * (p.x - v3.x) + (v1.x - v3.x) * (p.y - v3.y)) /
((v3.y - v1.y) * (v2.x - v3.x) + (v1.x - v3.x) * (v2.y - v3.y));
B.z = 1 - B.x - B.y;
return B;
}
}
public class Line3d
{
public static Vector3 closestPointInLine(Vector3 point, Vector3 lineStart, Vector3 lineEnd)
{
Vector3 line = lineEnd - lineStart;
float t = Vector3.Dot(point - lineStart, line);
return lineStart + line * t;
}
public static Vector3 closestPointInSegment(Vector3 point, Vector3 lineStart, Vector3 lineEnd)
{
Vector3 line = lineEnd - lineStart;
float t = Mathf.Clamp01(Vector3.Dot(point - lineStart, line));
return lineStart + line * t;
}
}
public static class Vector2Utillites
{
public static float AngleFromTo(Vector2 from, Vector2 to)
{
float ang = Vector2.Angle(from, to);
Vector3 cross = Vector3.Cross(from, to);
if (cross.z > 0)
ang = 360 - ang;
return ang;
}
}
public class Polygon
{
public static bool isBelong(Vector2[] polyPoints, Vector2 point)
{
int npol = polyPoints.Length;
int j = npol - 1;
bool c = false;
for (int i = 0; i < npol; i++)
{
if ((((polyPoints[i].y <= point.y) && (point.y < polyPoints[j].y)) || ((polyPoints[j].y <= point.y) && (point.y < polyPoints[i].y))) &&
(point.x > (polyPoints[j].x - polyPoints[i].x) * (point.y - polyPoints[i].y) / (polyPoints[j].y - polyPoints[i].y) + polyPoints[i].x))
{
c = !c;
}
j = i;
}
return c;
}
}
public struct Line
{
public Vector2 p0;
public Vector2 p1;
Line(Vector2 p0, Vector2 p1)
{
this.p0 = p0;
this.p1 = p1;
}
public static float distanceFromPointToSegment(Vector2 lineA, Vector2 lineB, Vector2 point)
{
return Vector2.Distance(ClosestPointOnSegment(lineA, lineB, point), point);
}
public static Vector2 ClosestPointOnLine(Vector2 lineA, Vector2 lineB, Vector2 point)
{
Vector2 p2 = lineB - lineA;
float something = p2.x * p2.x + p2.y * p2.y;
float u = (((point.x - lineA.x) * p2.x + (point.y - lineA.y) * p2.y) / something);
//closest point
return lineA + u * p2;
}
public static Vector2 ClosestPointOnSegment(Vector2 segA, Vector2 segB, Vector2 point)
{
Vector2 p2 = segB - segA;
float something = p2.x * p2.x + p2.y * p2.y;
float u = Mathf.Clamp01(((point.x - segA.x) * p2.x + (point.y - segA.y) * p2.y) / something);
//closest point
return segA + u * p2;
}
public static Vector2 ClosestPointOnSegment(Line line, Vector2 point)
{
return ClosestPointOnSegment(line.p0, line.p1, point);
}
public Vector2 closestPointOnSegment(Vector2 point)
{
return ClosestPointOnSegment(this, point);
}
public static bool isIntersection(Line line1, Line line2)
{
return isIntersection(line1.p0, line1.p1, line2.p0, line2.p1);
}
public static bool isIntersection(Vector2 a1, Vector2 a2, Vector2 b1, Vector2 b2)
{
float v1, v2, v3, v4;
v1 = (b2.x - b1.x) * (a1.y - b1.y) - (b2.y - b1.y) * (a1.x - b1.x);
v2 = (b2.x - b1.x) * (a2.y - b1.y) - (b2.y - b1.y) * (a2.x - b1.x);
v3 = (a2.x - a1.x) * (b1.y - a1.y) - (a2.y - a1.y) * (b1.x - a1.x);
v4 = (a2.x - a1.x) * (b2.y - a1.y) - (a2.y - a1.y) * (b2.x - a1.x);
return (v1 * v2 < 0) && (v3 * v4 < 0);
}
public static bool intersection(Vector2 a1, Vector2 a2, Vector2 b1, Vector2 b2, out Vector2 point)
{
point = Vector2.zero;
float x1 = a1.x;
float y1 = a1.y;
float x2 = a2.x;
float y2 = a2.y;
float x3 = b1.x;
float y3 = b1.y;
float x4 = b2.x;
float y4 = b2.y;
float t = 0;
float xa = 0;
float ya = 0;
if (Mathf.Abs((x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4)) < 0.0001)
{
return false;
}
else
{
t = ((y3 - y1) * (x3 - x4) - (x3 - x1) * (y3 - y4)) / ((x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4));
if ((t >= 0) && (t <= 1))
{
xa = x1 + t * (x2 - x1);
ya = y1 + t * (y2 - y1);
if (((x3 - xa) * (x4 - xa) <= 0) && ((y3 - ya) * (y4 - ya) <= 0))
{
point = new Vector2(xa, ya);
return true;
}
else
{
return false;
}
}
else
{
return false;
}
}
}
}
}