user802599
user802599

Reputation: 828

C# intersect a line bettween 2 Vector3 point on a plane

I have a line going bettween two Vector3 points and I want to find when the line is intersected at a height along the Z axis.

I am trying to write a function to calculate the intersection point.

void Main()
{
    Vector3 A = new Vector3(2.0f,  2.0f, 2.0f);
    Vector3 B = new Vector3(7.0f, 10.0f, 6.0f);
    float Z = 3.0f;

    Vector3 C = getIntersectingPoint(A, B, Z);
    //C should be X=3.25, Y=4.0, Z=3.0
} 

But trying to figure out how to do the math to handle possible negative numbers correctly is really starting to confuse me.

This is what I have and the moment, but this isn't correct.

public static Vector3 getIntersectingPoint(Vector3 A, Vector3 B, float Z)
{
    // Assume z is bettween A and B and we don't need to validate
    // Get ratio of triangle hight, height Z divided by (Za to Zb)  
    ("absolute value: " + Math.Abs(A.Z-B.Z)).Dump();
    ("z offset: " + (Math.Abs(Z-B.Z)<Math.Abs(A.Z-Z)?Math.Abs(Z-B.Z):Math.Abs(A.Z-Z))).Dump();
    float ratio = (Math.Abs(Z-B.Z)<Math.Abs(A.Z-Z)?Math.Abs(Z-B.Z):Math.Abs(A.Z-Z))/Math.Abs(A.Z-B.Z);
    ("ratio: " + ratio.ToString()).Dump();
    float difX = ratio*Math.Abs(A.X-B.X);//this still needs to be added to or taken from the zero point offset
    ("difX: " + difX.ToString()).Dump();
    float difY = ratio*Math.Abs(A.Y-B.Y);//this still needs to be added to or taken from the zero point offset
    ("difY: " + difY.ToString()).Dump();

    float X = difX + (A.X<B.X?A.X:B.X);
    ("X: " + X).Dump();
    float Y = difY + (A.Y<B.Y?A.Y:B.Y);
    ("Y: " + Y).Dump();
    return new Vector3(X,Y,Z);
}

Does anyone know if there are any Math libraries that will already do this or examples that show how to do this that I can follow?

Upvotes: 0

Views: 923

Answers (1)

Jim Mischel
Jim Mischel

Reputation: 133995

You have the starting (2.0f) and ending (6.0f) Z coordinates. The Z distance between the two points is 4.0f. You want to know the X and Y coordinates at the point where Z is 3.0f.

Remember that Z changes linearly along the segment. The segment is 4 units long, The point you're interested in is 1 unit from the start, or 1/4 of the length of the segment.

The X distance of the entire segment is 7.0 - 2.0, or 5 units. 1/4 of 5 is 1.25, so the X coordinate at the intersection is 3.25.

The Y distance of the entire segment is 8. 1/4 of 8 is 2. So the Y coordinate of the intersection point is 6.0.

The intersection point is (3.25f, 6.0f, 3.0f).

How to compute:

// start is the starting point
// end is the ending point
// target is the point you're looking for.
// It's pre-filled with the Z coordinate.
zDist = Math.Abs(end.z - start.z);
zDiff = Math.Abs(target.z - start.z);
ratio = zDiff / zDist;

xDist = Math.Abs(end.x - start.x);
xDiff = xDist * ratio;
xSign = (start.x < end.x) ? 1 : -1;
target.x = start.x + (xDiff * xSign);

yDist = Math.Abs(end.y - start.y);
yDiff = yDist * ratio;
ySign = (start.y < end.y) ? 1 : -1;
target.y = start.y + (yDiff * ySign);

Come to think of it, the whole sign thing shouldn't be necessary. Consider this, when end.x = 10 and start.x = 18:

xDist = end.x - start.x;      // xDist = -8
xDiff = xDist * ratio;        // xDiff = -2
target.x = start.x + xDiff;   // target.x = 18 + (-2) = 16

Yeah, no need for sign silliness.

Also no need for the calls to Math.Abs when computing the ratio. We know that zDist and zDiff will both have the same sign, so ratio will always be positive.

Upvotes: 1

Related Questions