The Unity community wiki has a page of math functions that includes a very helpful procedure for this. Copied (and edited slightly) below:
public static bool LineLineIntersection(out Vector3 intersection, Vector3 linePoint1,
Vector3 lineVec1, Vector3 linePoint2, Vector3 lineVec2){
Vector3 lineVec3 = linePoint2 - linePoint1;
Vector3 crossVec1and2 = Vector3.Cross(lineVec1, lineVec2);
Vector3 crossVec3and2 = Vector3.Cross(lineVec3, lineVec2);
float planarFactor = Vector3.Dot(lineVec3, crossVec1and2);
//is coplanar, and not parallel
if( Mathf.Abs(planarFactor) < 0.0001f
&& crossVec1and2.sqrMagnitude > 0.0001f)
{
float s = Vector3.Dot(crossVec3and2, crossVec1and2) / crossVec1and2.sqrMagnitude;
intersection = linePoint1 + (lineVec1 * s);
return true;
}
else
{
intersection = Vector3.zero;
return false;
}
}
So, in your situation, you could use that, then check if the intersection point is between a1 and a2 and b1 and b2:
Vector3 intersection;
Vector3 aDiff = a2-a1;
Vector3 bDiff = b2-b1;
if (LineLineIntersection(out intersection, a1, aDiff, b1, bDiff))
{
float aSqrMagnitude = aDiff.sqrMagnitude;
float bSqrMagnitude = bDiff.sqrMagnitude;
if ( (intersection - a1).sqrMagnitude <= aSqrMagnitude
&& (intersection - a2).sqrMagnitude <= aSqrMagnitude
&& (intersection - b1).sqrMagnitude <= bSqrMagnitude
&& (intersection - b2).sqrMagnitude <= bSqrMagnitude)
{
// there is an intersection between the two segments and it is at intersection
}
}
You could also use this option if you want to dispense with the UnityEngine library:
public class V2
{
public static V2 zero = new V2(0, 0);
public readonly float x;
public readonly float y;
[JsonConstructor]
public V2(float x, float y)
{
if (
physicsLogic.debugOn &&
(float.IsNaN(x) || float.IsNaN(y) || float.IsInfinity(y) || float.IsInfinity(x)))
{
throw new Exception($"Dodgy V2 ({x},{y})");
}
this.x = x; this.y = y;
}
public FieldPoint asFlooredFieldPoint()
{
return new FieldPoint(x,0,y);
}
public static V2 operator +(V2 b, V2 a) => new V2(b.x + a.x, b.y + a.y);
public static V2 operator -(V2 b, V2 a) => new V2(b.x - a.x, b.y - a.y);
public static V2 operator /(V2 a, double b) => new V2((float)(a.x / b), (float)(a.y / b));
public static V2 operator *(V2 a, double b) => new V2((float)(a.x * b), (float)(a.y * b));
public static V2 operator *(double b, V2 a) => new V2((float)(a.x * b), (float)(a.y * b));
[JsonIgnore]
float mag = -1;
[JsonIgnore]
public float magnitude
{
get
{
if (mag < 0)
{
mag = (float)Math.Sqrt(sqrMagnitude);
}
return mag;
}
}
[JsonIgnore]
public V2 normalized
{
get
{
var mag = magnitude;
if (mag == 0)
{
return V2.zero;
}
return new V2(x / mag, y / mag);
}
}
[JsonIgnore]
float _sqrMagnitude = -1;
[JsonIgnore]
public float sqrMagnitude
{
get
{
if (_sqrMagnitude < 0)
{
_sqrMagnitude = (float)(Math.Pow(x, 2) + Math.Pow(y, 2));
}
return _sqrMagnitude;
}
}
public override string ToString()
{
return $"({x.ToString("F1")},{y.ToString("F1")})";
}
public override bool Equals(Object obj)
{
//Check for null and compare run-time types.
if ((obj == null) || !this.GetType().Equals(obj.GetType()))
{
return false;
}
else
{
V2 p = (V2)obj;
return (MathUtil.closeEnough(x, p.x, .001)) && (MathUtil.closeEnough(y, p.y, .001));
}
}
public static V2 intersectSegment(V2 goalStart, V2 goalEnd, V2 ballStart, V2 ballEnd)
{
/* Equations of straight lines 2D: Qx + Ry + S = 0
*
* The objective is to determine the equations of the straight line of each segment,
* on the one hand the goal line and on the other hand the ball line.
*
* Then I determine if the two lines intersect at a point, or on the contrary
* if they never intersect, that is, they are parallel.
*
* If the two lines intersect at a point, I determine the value of that point (P)
*
* Finally, it is checked if this point is contained in each of the segments. *
*
*
* r1: Point A (x_A, y_A); Point B (x_B, y_B) --> AB = (x_B - x_A, y_B - y_A)
* r2: Point C (x_C, y_C), Point D (x_D, y_D) --> CD = (x_D - x_C, y_D - y_C)
*
* r1: (x - x_A)/x_AB = (y - y_A)/y_AB --> r1: Q1x + R1y + S1 = 0
* r2: (x - x_C)/x_CD = (y - y_C)/y_CD --> r2: Q2x + R2y + S2 = 0
*
* ** Q1 = y_AB ; R1 = -x_AB ; S1 = x_AB*y_A - y_AB*x_A
* ** Q2 = y_CD ; R2 = -x_CD ; S2 = x_CD*y_C - y_CD*x_C
*
* | Q1 R1 |
* determinant = | Q2 R2 | = Q1*R2 - Q2*R1
*
* ** if determinant == 0 -> is parallell
* ** if determinant != 0 -> is secant line
*
* Cut-off point (P):
*
* Q2*S1 - Q1*S2
* y_P = -------------
* Q1*R2 - Q2*R1
*
* S1*(Q2*R1 - Q1*R2) + R1*Q2*(Q1 - S1)
* x_P = ------------------------------------
* Q1^2*R2 - Q1*Q2*R1
*
*
* ** if P c in AB or CD -> Intersection true
*
*/
var goalVector = goalEnd - goalStart;
var ballVector = ballEnd - ballStart;
var Q1 = goalVector.y;
var Q2 = ballVector.y;
var R1 = goalVector.x;
var R2 = ballVector.x;
var S1 = goalVector.x * goalStart.y - goalVector.y * goalStart.x;
var S2 = ballVector.x * ballStart.y - ballVector.y * ballStart.x;
var determinant = Q1 * R2 - Q2 * R1;
if (determinant != 0)
{
var x_P = (S2 * R1 - R2 * S1) / (R2 * Q1 - Q2 * R1);
var y_P = (S2 * Q1 - Q2 * S1) / (R2 * Q1 - Q2 * R1);
var intersectPoint = new V2(x_P, y_P);
if (MathUtil.PointContentInAB(goalStart, goalEnd, intersectPoint ) &&
MathUtil.PointContentInAB(ballStart, ballEnd, intersectPoint))
{
return intersectPoint;
}
}
return null;
}
public static bool findIfIntersectsInSegment(V2 goalStart, V2 goalEnd, V2 ballStart, V2 ballEnd)
{
return intersectSegment(goalStart, goalEnd, ballStart, ballEnd)!=null;
}
public static bool PointContentInAB(V2 A, V2 B, V2 P)
{
/* Equations of straight lines 2D: Qx + Ry + S = 0
*
* Point A (x_A, y_A); Point B (x_B, y_B) --> AB = (x_B - x_A, y_B - y_A)
*
* r1: (x - x_A)/x_AB = (y - y_A)/y_AB --> r1: Q1x + R1y + S1 = 0
* Q1 = y_AB ; R1 = -x_AB ; S1 = x_AB*y_A - y_AB*x_A
*
* ** if P.x <= B.x && P.x >= A.x --> Point content in AB
*/
var AB = B - A;
var P_content_in_r1 = AB.y * P.x - AB.x * P.y + (AB.x * A.y - AB.y * A.x);
if (nearzero(P_content_in_r1))
// Point content in r1
{
if (AB.x > 0f)
{
if (P.x <= B.x && P.x >= A.x)
// Point content in r1 and AB
{
if (AB.y > 0f)
{
if (P.y <= B.y && P.y >= A.y)
{
return true;
}
}
else
{
if(P.y >= B.y && P.y <= A.y)
{
return true;
}
}
}
}
else
{
if (P.x >= B.x && P.x <= A.x)
{
// Point content in r1 and AB
if (AB.y > 0f)
{
if (P.y <= B.y && P.y >= A.y)
{
return true;
}
}
else
{
if (P.y >= B.y && P.y <= A.y)
{
return true;
}
}
}
}
}
return false;
}
I hope you find it useful, best regards.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.