Getting angle from 2 lines.

+3 votes
asked Mar 17, 2016 in Programming by Skurniekto Student (370 points)

I know the origin (0,0,0 in this case), V1 and Ang1(direction in euler angles). What i need is the angle between Ang1 and the line between the origin and V1(which can be anywhere else). Also i need to know if the angle is negative (left) or positive (right) compared to Ang1. In this case the upper V1 is negative and the other is positive. 

1 Answer

+2 votes
answered Mar 17, 2016 by Bugstacker Senior (4,800 points)
selected Mar 18, 2016 by Skurniekto
 
Best answer

Given two normalized vectors v1 and v2 in R3 (3D space) the angle a in degrees between them is defined as follows:

d := dot(v1, v2) | { d | -1..1] }

a := acos(d) * 180/PI


Update (C# code expamle)

To get the signed angle you can use the signed angle method from the code below:

 

public static float SignedAngle(Vector3 v1, Vector3 v2)
{
    float a = Angle(v1, v2);
    
    return ClampAngle(a);
}

public static float Angle(Vector3 v1, Vector3 v2)
{
    float val = Dot(Normalize(v1), Normalize(v2));
    return (float)Math.Acos(Clamp(val, -1.0f, 1.0f)) * (180.0f / (float)Math.PI);
}

public static Vector3 Normalize(Vector3 value)
{
    float single = Length(value);
    return value / single;
}

public static float Length(Vector3 a)
{
    return (float)Math.Sqrt(a.x * a.x + a.y * a.y + a.z * a.z);
}

public static float Dot(Vector3 v1, Vector3 v2)
{
    return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
}

public static float ClampAngle(float a)
{
    if (a > 180.0f) { a -= 360.0f; }
    if (a < -180.0f) { a += 360.0f; }

    return a;
}
        
public static float Clamp(float value, float min, float max)
{
    return (value < min) ? min : (value > max) ? max : value;
}

 

commented Mar 17, 2016 by Gleny Student (480 points)
I think the OP wanted to see a code snippet since it's tagged as c# :)
commented Mar 17, 2016 by Bugstacker Senior (4,800 points)
@Gleny You are right. See updated answer.
commented Mar 18, 2016 by Skurniekto Student (370 points)
After a bit of research and playing around i came up with this solution which works perfectly for me:
        Vector3 cPoint = (crosshairPoint - transform.position).normalized;

        float angle = Utility.SignedAngle (transform.forward.normalized, cPoint);

        if(Vector3.Dot(cPoint, transform.right) < 0){
            angle = -angle;
        }

And thank you very much, you have been great help! :)
commented Mar 18, 2016 by Bugstacker Senior (4,800 points)
Glad I could help :)
Welcome to Bugstacker Q&A, where you can ask questions concerning Game Development, Programming and Design and receive answers from other members of the community.

Help for

...