# Getting correct angles between Vector3s

I'm working on a project where you can draw lines between points. You select one point and drag the mouse onto another point and a line is drawn between them.

The line itself is a 3d object which is scaled to match the length between points. Currently you can draw lines that are horizontal or vertical. But drawing a line that starts and ends on a different level fail.

Horizontal and vertical work well. Here the lines should go like indicated by the grey lines. But it adds the Z-rotation(Up/down) to the Y-rotation(direction) - (Setting the Y-rotation by hand to match the horizontal line results the line being drawn correctly). Vector3 dir = junctionFinderHit.transform.position - startPos;  /// Direction vector
float angleY = Vector3.Angle(dir, new Vector3(1, 0, 0));
float angleZ = Vector3.Angle(dir, new Vector3(0, 1, 0));

//Debug.Log(angleY + " - " + AngleDir(new Vector3(0, 1, 0), dir, Vector3.up));

Vector3 rotationVector = new Vector3(0,0,0);

if (AngleDir(new Vector3(1, 0, 0), dir, Vector3.up) < 0)    /// 360 movement instead of 180
rotationVector.y = 360-angleY;
else
rotationVector.y = angleY;

/// -90 degrees to make it horizontal by default, negative to make it point to the right direction
rotationVector.z = (angleZ-90f)*-1;

activeStick.transform.eulerAngles = rotationVector;


What do I need to do to get the rotations correct?

• Consider using Transform.LookAt. Mar 19 '13 at 8:05
• @chaosTechnician Problem with the transform.LookAt is that it uses the forward vector(Z). A line's length is along the X-axis(ends up broadsiding), so this does not provide a solution. answers.unity3d.com/questions/22003/…
– Esa
Mar 19 '13 at 8:41
• It does if you follow the Unity standard and make your lines go along the Z axis instead of X. If you're not going to orient it that way, can you explain how you're doing it to help ensure the math is done on the correct axes? (i.e., is +Y up and +Z right?) Mar 19 '13 at 9:34
• @chaosTechnician I changed to the Unity standard and brief tests show that it now works with LookAt. Thank you! But I'm still very interested in how you'd do it with math. The axes are: Y=Left/Right and Z=Up/Down.
– Esa
Mar 19 '13 at 10:25

Using the LookAt function is probably a better practical solution.

The reason that your code doesn't work is that your angleY calculation does not just get the angle in the horizontal plane, witch is what you need, but rather get the full angle including any vertical component. Projecting the direction on the horizontal plane before the calculation should solve the problem. I'm not able to test it, but I think this will give you the desired behaviour:

float angleY = Vector3.Angle(dir-Vector3.Project(dir,new Vector3(0, 1, 0)), new Vector3(1, 0, 0));

• Using the projection made the angles just as I had planned them.
– Esa
Mar 20 '13 at 5:33

There's a simple solution. Don't use angles. Just draw the vertices for the objects starting at the start point and finishing at the end point.

I just implemented in C a way to calculate the angle between two vectors A,B, given an origin C. Look at this Wikipedia article to understand where I am coming from. Here's the pseudo-code:

/*
A dot B = |A| * |B| * cos(theta)
Therefor theta = acos (A dot B / |A||B|)
*/
double Vector3AngleBetweenTwoPoints(Vector3 p1, Vector3 p2)
{
return acos(Vector3DotProduct(p1, p2) / (Vector3Magnitude(p1) * Vector3Magnitude(p2)));
}

double Vector3AngleBetweenABWithCOrigin(Vector3 A, Vector3 B, Vector3 C)
{
return Vector3AngleBetweenTwoPoints(Vector3Subtract(A, C), Vector3Subtract(B, C));
}


It's probably not the "proper" Unity way to do it, but it should help you understand how to calculate the angle between two vectors (if that's really the question you want answered :P).