Given two vectors, how can I rotate the second vector around the first to get the resulting vector where Y = 0?

I have two vectors that represent the end points of a line. I want to rotate the end vector around the first until Y = 0.

Imagine a length of wood/pipe. The first end (V1) is fixed in position, and the other end (V2) is free to rotate in any direction. The length of the wood/pipe does not change.

The Y position of V2 is currently above 0 - How can I find the values of V2 when the wood/pipe is rotated down until Y is equal to 0?

The X/Z direction from V1 to V2 must not change (I only want to rotate around a single axis).


  1. Vector1 = { x: 5, y: 4, z:7 }
  2. Vector2 = { x: 9, y: 10, z:20 }
  3. Vector3 = { x: ?, y: 0, z:? }

I can work out the distance between V1 and V2 using Vector3.Distance(). Now I want to work out V3

What is the easiest way to do this? The direction from {V1.X,V1.Z} to {V2.X,V2.Z} should be the same as {V1.X,V1.Z} to {V3.X,V3.Z}.

Use the Pythagorean Theorem:

alt text

You know b, the height of V1 above 0, and c, the length of the pipe. Now you can find a using the theorem.

var a = Mathf.Sqrt (c*c - b*b);

Then just do:

var V2new = V2; // Start with original V2
V2new.y = 0; // Discard y component
V2new.Normalize (); // Set length to 1
V2new *= a; // multiply by the length we found using the Pythagorean Theorem

You're done!

It might be possible to optimize this a bit, but unless you find out that this code is a bottleneck for performance, it would just be premature optimization.

This is pretty simple linear algebra (projecting a vector onto a plane and rescaling it, but since the plane is dead simple we'll just cheat a bit)..

Two points.

var pFixed : Vector3;
var pFree : Vector3;

The distance between them:

var d : float = Vectors3:Distance(pFixed, pFree);

Make a new vector that goes between them A vector from A to B is B - A:

var between : Vector3 = pFree - pFixed;

Constrain that vector to the XZ plane (hopefully it isn't pointing straight up..)

between.y = 0;

Now scale it to the length we found before.

between.Normalize() *= d;

Now our new "free" point is:

var pFreely : Vector3 = pFixed + between;