A game about forced loneliness, made by TACStudios
at master 136 lines 4.5 kB view raw
1using System; 2using UnityEngine; 3 4namespace UnityEditor.U2D.Animation 5{ 6 internal static class MathUtility 7 { 8 public static float DistanceToSegmentClamp(Vector3 p, Vector3 p1, Vector3 p2) 9 { 10 float l2 = (p2 - p1).sqrMagnitude; // i.e. |b-a|^2 - avoid a sqrt 11 if (l2 == 0.0) 12 return float.MaxValue; // a == b case 13 float t = Vector3.Dot(p - p1, p2 - p1) / l2; 14 if (t < 0.0) 15 return float.MaxValue; // Beyond the 'a' end of the segment 16 if (t > 1.0) 17 return float.MaxValue; // Beyond the 'b' end of the segment 18 Vector3 projection = p1 + t * (p2 - p1); // Projection falls on the segment 19 return (p - projection).magnitude; 20 } 21 22 public static Vector2 ClampPositionToRect(Vector2 position, Rect rect) 23 { 24 return new Vector2(Mathf.Clamp(position.x, rect.xMin, rect.xMax), Mathf.Clamp(position.y, rect.yMin, rect.yMax)); 25 } 26 27 public static Vector2 MoveRectInsideFrame(Rect rect, Rect frame, Vector2 delta) 28 { 29 if (frame.size.x <= rect.size.x) 30 delta.x = 0f; 31 32 if (frame.size.y <= rect.size.y) 33 delta.y = 0f; 34 35 Vector2 min = rect.min + delta; 36 Vector2 max = rect.max + delta; 37 Vector2 size = rect.size; 38 Vector2 position = rect.position; 39 40 max.x = Mathf.Clamp(max.x, frame.min.x, frame.max.x); 41 max.y = Mathf.Clamp(max.y, frame.min.y, frame.max.y); 42 43 min = max - size; 44 45 min.x = Mathf.Clamp(min.x, frame.min.x, frame.max.x); 46 min.y = Mathf.Clamp(min.y, frame.min.y, frame.max.y); 47 48 max = min + size; 49 50 rect.min = min; 51 rect.max = max; 52 53 delta = rect.position - position; 54 55 return delta; 56 } 57 58 public static bool SegmentIntersection(Vector2 p0, Vector2 p1, Vector2 p2, Vector2 p3, ref Vector2 point) 59 { 60 Vector2 s1 = p1 - p0; 61 Vector2 s2 = p3 - p2; 62 63 float s, t, determinant; 64 determinant = (s1.x * s2.y - s2.x * s1.y); 65 66 if (Mathf.Approximately(determinant, 0f)) 67 return false; 68 69 s = (-s1.y * (p0.x - p2.x) + s1.x * (p0.y - p2.y)) / determinant; 70 t = (s2.x * (p0.y - p2.y) - s2.y * (p0.x - p2.x)) / determinant; 71 72 if (s >= 0f && s <= 1f && t >= 0f && t <= 1f) 73 { 74 point = p0 + (t * s1); 75 return true; 76 } 77 78 return false; 79 } 80 81 //https://gamedev.stackexchange.com/a/49370 82 public static void Barycentric(Vector2 p, Vector2 a, Vector2 b, Vector2 c, out Vector3 coords) 83 { 84 Vector2 v0 = b - a, v1 = c - a, v2 = p - a; 85 float d00 = Vector2.Dot(v0, v0); 86 float d01 = Vector2.Dot(v0, v1); 87 float d11 = Vector2.Dot(v1, v1); 88 float d20 = Vector2.Dot(v2, v0); 89 float d21 = Vector2.Dot(v2, v1); 90 float invDenom = 1f / (d00 * d11 - d01 * d01); 91 coords.y = (d11 * d20 - d01 * d21) * invDenom; 92 coords.z = (d00 * d21 - d01 * d20) * invDenom; 93 coords.x = 1f - coords.y - coords.z; 94 } 95 96 public static Quaternion NormalizeQuaternion(Quaternion q) 97 { 98 Vector4 v = new Vector4(q.x, q.y, q.z, q.w).normalized; 99 return new Quaternion(v.x, v.y, v.z, v.w); 100 } 101 102 //From: https://answers.unity.com/questions/861719/a-fast-triangle-triangle-intersection-algorithm-fo.html 103 public static bool Intersect(Vector3 p1, Vector3 p2, Vector3 p3, Ray ray) 104 { 105 Vector3 e1, e2; 106 Vector3 p, q, t; 107 float det, invDet, u, v; 108 e1 = p2 - p1; 109 e2 = p3 - p1; 110 p = Vector3.Cross(ray.direction, e2); 111 det = Vector3.Dot(e1, p); 112 113 if (Mathf.Approximately(det, 0f)) 114 return false; 115 116 invDet = 1.0f / det; 117 118 t = ray.origin - p1; 119 u = Vector3.Dot(t, p) * invDet; 120 121 if (u < 0 || u > 1) 122 return false; 123 124 q = Vector3.Cross(t, e1); 125 v = Vector3.Dot(ray.direction, q) * invDet; 126 127 if (v < 0 || u + v > 1) 128 return false; 129 130 if ((Vector3.Dot(e2, q) * invDet) > 0f) 131 return true; 132 133 return false; 134 } 135 } 136}