Search code examples
unity-game-enginevectorrotationquaternions

Unity3D angle between vectors/directions on specific axis


I have two directions and i am trying to calculate the angle on a specific axis. The object from which the directions are derived is not a static object so i'm struggling to get my head round the maths to work out what i need to do.

FYI, I have the start and end points that i have used to calculate the directions if they are needed.

Here's a diagram to show what i am looking for:

The above image is from a top-down view in unity and it shows the angle i want.

The problem can be seen from the above image, which is that the directions are not on the same height so i can't use the vector3.angle function as it won't give me the correct angle value.

In essence i want to know how much would i have to rotate the red line to the left (top view) so that it would line up with the blue (top-view).

The reason i need this is as i am trying to find a way of getting the side-to-side angles of fingers from my leap motion sensor.

This a generic version of my other question: Leap Motion - Angle of proximal bone to metacarpal (side to side movement)

It will provide more specific information as to the problem if you need it and it has more specific screenshots.

**UPDATE: After re-reading my question i can see it wasn't particularly clear so here i will hopefully make it clearer. I am trying to calculate the angle of a finger from the leap motion tracking data. Specifically the angle of the finger relative to the metacarpal bone (bone is back of hand). An easy way to demonstrate what i mean would be for you to move your index finger side-to-side (i.e. towards your thumb and then far away from your thumb).

I have put two diagrams below to hopefully illustrate this. enter image description here

The blue line follows the metacarpal bone which your finger would line up with in a resting position. What i want to calculate is the angle between the blue and red lines (marked with a green line). I am unable to use Vector3.Angle as this value also takes into account the bending of the finger. I need someway of 'flattening' the finger direction out, thus essentially ignoring the bending and just looking at the side to side angle. The second diagram will hopefully show what i mean.

enter image description here

In this diagram: The blue line represents the actual direction of the finger (taken from the proximal bone - knuckle to first joint) The green line represents the metacarpal bone direction (the direction to compare to) The red line represents what i would like to 'convert' the blue line to, whilst keeping it's side to side angle (as seen in the first hand diagram).

It is also worth mentioning that i can't just always look at the x and z axis as this hand will be moving at rotating.

I hope this helps clear things up and truly appreciate the help received thus far.


Solution

  • If I understand your problem correctly, you need to project your two vectors onto a plane. The vectors might not be in that plane currently (your "bent finger" problem) and thus you need to "project" them onto the plane (think of a tree casting a shadow onto the ground; the tree is the vector and the shadow is the projection onto the "plane" of the ground).

    Luckily Unity3D provides a method for projection (though the math is not that hard). Vector3.ProjectOnPlane https://docs.unity3d.com/ScriptReference/Vector3.ProjectOnPlane.html

    Vector3 a = ...;
    Vector3 b = ...;
    Vector3 planeNormal = ...;
    Vector3 projectionA = Vector3.ProjectOnPlane(a, planeNormal);
    Vector3 projectionB = Vector3.ProjectOnPlane(b, planeNormal);
    float angle = Vector3.Angle(projectionA, projectionB);
    

    What is unclear in your problem description is what plane you need to project onto? The horizontal plane? If so planeNormal is simply the vertical. But if it is in reference to some other transform, you will need to define that first.