Last active
September 21, 2016 02:10
-
-
Save samloeschen/1ac0b426c095770f6889fc87b0d42d47 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
using System.Collections; | |
using System.Collections.Generic; | |
public static class MathUtilities{ | |
public static Vector2[] LineBoxIntersect(Vector2 point1, Vector2 point2, Rect rect) { | |
List<Vector2> intersect = new List<Vector2>(); //if this is ever greater than length 2 we have encountered a black hole | |
//order is clockwise from bottom left -> left edge, top edge, right edge, bottom edge | |
Vector2[] rectP1 = { | |
new Vector2(rect.xMin, rect.yMin), //bottom left | |
new Vector2(rect.xMin, rect.yMax), //top left | |
new Vector2(rect.xMax, rect.yMax), //top right | |
new Vector2(rect.xMax, rect.yMin) // bottom right | |
}; | |
Vector2[] rectP2 = { | |
new Vector2(rect.xMin, rect.yMax), //top left | |
new Vector2(rect.xMax, rect.yMax), //top right | |
new Vector2(rect.xMax, rect.yMin), //bottom right | |
new Vector2(rect.xMin, rect.yMin) //bottom left | |
}; | |
for (int i = 0; i < 4; i++) { | |
Vector2 test; | |
if (LineIntersect(point1, point2, rectP1[i], rectP2[i], out test)) { | |
intersect.Add(test); | |
} | |
} | |
return intersect.ToArray(); | |
} | |
public static bool LineIntersect(Vector2 a0, Vector2 a1, Vector2 b0, Vector2 b1, out Vector2 intersectionPoint) { | |
intersectionPoint = Vector2.zero; | |
if (a0 == b0 || a0 == b1 || a1 == b0 || a1 == b1) | |
return false; | |
float x1 = a0.x; | |
float y1 = a0.y; | |
float x2 = a1.x; | |
float y2 = a1.y; | |
float x3 = b0.x; | |
float y3 = b0.y; | |
float x4 = b1.x; | |
float y4 = b1.y; | |
//AABB early exit | |
if (Mathf.Max(x1, x2) < Mathf.Min(x3, x4) || Mathf.Max(x3, x4) < Mathf.Min(x1, x2)) | |
return false; | |
if (Mathf.Max(y1, y2) < Mathf.Min(y3, y4) || Mathf.Max(y3, y4) < Mathf.Min(y1, y2)) | |
return false; | |
float ua = ((x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3)); | |
float ub = ((x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3)); | |
float denom = (y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1); | |
if (Mathf.Abs(denom) < Mathf.Epsilon) { | |
//Lines are too close to parallel to call | |
return false; | |
} | |
ua /= denom; | |
ub /= denom; | |
if ((0 < ua) && (ua < 1) && (0 < ub) && (ub < 1)) { | |
intersectionPoint.x = (x1 + ua * (x2 - x1)); | |
intersectionPoint.y = (y1 + ua * (y2 - y1)); | |
return true; | |
} | |
return false; | |
} | |
public static bool PointInRect(Vector2 point, Rect rect) { | |
if(point.x > rect.min.x && | |
point.x < rect.max.x && | |
point.y < rect.min.y && | |
point.y > rect.max.y) { | |
return true; | |
}else { | |
return false; | |
} | |
} | |
public static bool CircleLineCheck(Vector2 point1, Vector2 point2, Vector2 circleOrigin, float circleRadius) { | |
Vector2 localPoint1 = point1 - circleOrigin; | |
Vector2 localPoint2 = point2 - circleOrigin; | |
Vector2 lineOffset = localPoint2 - localPoint1; | |
float a = (lineOffset.x * lineOffset.x) + (lineOffset.y * lineOffset.y); | |
float b = 2f * ((lineOffset.x * localPoint1.x) + (lineOffset.y * localPoint1.y)); | |
float c = (localPoint1.x * localPoint1.x) + (localPoint1.y * localPoint1.y) - (circleRadius * circleRadius); | |
float disc = (b * b) - (4f * a * c); | |
return (disc > 0f); | |
} | |
public static Vector2[] CircleLineCheckPoints(Vector2 point1, Vector2 point2, Vector2 circleOrigin, float circleRadius) { | |
Vector2 localPoint1 = point1 - circleOrigin; | |
Vector2 localPoint2 = point2 - circleOrigin; | |
Vector2 lineOffset = localPoint2 - localPoint1; | |
float a = (lineOffset.x * lineOffset.x) + (lineOffset.y * lineOffset.y); | |
float b = 2f * ((lineOffset.x * localPoint1.x) + (lineOffset.y * localPoint1.y)); | |
float c = (localPoint1.x * localPoint1.x) + (localPoint1.y * localPoint1.y) - (circleRadius * circleRadius); | |
float disc = (b * b) - (4f * a * c); | |
if(disc > 0f) { | |
Vector2[] points; | |
disc = Mathf.Sqrt(disc); | |
float t1 = (-b - disc) / (2 * a); | |
float t2 = (-b + disc) / (2 * a); | |
if (t1 >= 0 && t2 >= 0) { | |
//total intersection, populate both points | |
points = new Vector2[2]; | |
points[0] = point1 + ((point2 - point1) * t1); | |
points[1] = point1 + ((point2 - point1) * t2); | |
} else { | |
//Only one intersected, populate one point | |
points = new Vector2[1]; | |
if (t1 >= 0) { | |
points[0] = point1 + ((point2 - point1) * t1); | |
} else if (t2 >= 0) { | |
points[0] = point1 + ((point2 - point1) * t2); | |
} | |
} | |
return points; | |
}else { | |
//no intersections | |
return null; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment