Cancel
Showing results for 
Search instead for 
Did you mean: 

How to obtain angle between axes from two frames

Phenom
Phenom

Hello All!

 

So, my need is simple but I still haven't found a (easy) solution for that. An example of what I need:

 

1 - I have two different frames at same location and with same rotation values;

2 - I apply a rotation of 5 degrees in Rx and then 5 degrees in Ry;

3 - Z axis from original frame and new rotated one will define an angle (Weld Quality Report gives me an "off normal" value of 7.067 degrees when comparing two locations with same rotation offset, which I'm assuming to be that angle, right?);

4 - My need: Compute the angle (in the case above, 7.067 degrees) between both Z axis.

 

I'm trying to use trigonometry, but still have not found a solution for that. Also, I assume, as always, that there's an easier solution. 

 

Regards!

 

 

 

 

 

11 REPLIES

Re: How to obtain angle between axes from two frames

Pioneer
Pioneer

try:

 

        public float GetAngleBetween(TxVector A, TxVector B)
        {
            float result = 0;
            Help_Mather mh = new Help_Mather();
            double DotProd = TxVector.DotProduct(A, B);
            double Length = mh.LengthVector(A) * mh.LengthVector(B);

            result = (float)mh.RadToDeg((float)Math.Acos(DotProd / Length));

            result = Convert.ToSingle(Math.Acos(DotProd / Length));
            return result;
        }

Re: How to obtain angle between axes from two frames

Pioneer
Pioneer

or

 

        public double angle3D(TxVector v1, TxVector v2)
        {
            //http://www.mathe-online.at/materialien/Andreas.Pester/files/Vectors/winkel_zwischen_vektoren.htm
            double result = 0;
            double zaehler = v1.X * v2.X + v1.Y * v2.Y + v1.Z * v2.Z;
            double nenner = (Math.Sqrt(Math.Pow(v1.X, 2) + Math.Pow(v1.Y, 2) + Math.Pow(v1.Z, 2))) * (Math.Sqrt(Math.Pow(v2.X, 2) + Math.Pow(v2.Y, 2) + Math.Pow(v2.Z, 2)));

            result = zaehler / nenner;

            return result;
        }

Re: How to obtain angle between axes from two frames

Phenom
Phenom

Hello @Titaniser

 

Thanks for the reply. 

 

How do I get the TxVector as directional vector (and not the rotation angle inside Process Simulate) to use your formula? I was trying to avoid converting rotation angles to directional vector, but of course, this is one way of doing it.

 

Regards

Re: How to obtain angle between axes from two frames

Pioneer
Pioneer

thats not wat you asked for originaly, but basically it's like.

 

pseudocode:

var vector1

var vector2

directionalVector = new txvector(vector2.x-vector1.x, vector2.y-vector1.y, vector2.z-vector1.z);

https://stackoverflow.com/questions/5483937/direction-of-two-points

Re: How to obtain angle between axes from two frames

Phenom
Phenom

So, I'm here to share the solution I found for further help:

 

To find the angle between two vectors I'm using the expression below (where a and b are two directional vectors [x y z]):

 

2018_07_03_09_56_03_Angle_between_two_vectors.png

 

To calculate the vector after a rotation, I'm using Rotation Matrix for 3D space. There are a lot of conventions for rotation matrix (if the rotation axis is fixed or not, right-hand rule for rotation signs, etc...), and I found out this to be hopefully the correct Rotation Matrix for my PS scenario (where a = rotation in x, b = rotation in y and c = rotation in z):

 

  R(xyz) = 

 

 |cos(b)*cos(c)      cos(c)*sen(a)*sen(b) - cos(a)*sen(c)        cos(a)*cos(c)*sen(b) + sen(a)*sen(c)|
 |cos(b)*sen(c)      cos(a)*cos(c) + sen(a)*sen(b)*sen(c)        cos(a)*sen(b)*sen(c) - cos(c)*sen(a)|
 | -sen(b)                              cos(b)*sen(a)                                                                           cos(a)*cos(b) |

 

With this matrix we can compute the rotation of a vector (in my case [0 0 1] -> pointing to Z direction) when we apply a specific rotation vector and then compute the angle between them (which in my case is going to be the angle between the vector and Z axis). So:

 

R(xyz) x [0 0 1]' = [x' y' z']'  -> Matrix multiplication, notice the [0 0 1] vector is transposed!

 

This will result in:

 

                    |cos(a)*cos(c)*sen(b) + sen(a)*sen(c)|
[x' y' z']' =  |cos(a)*sen(b)*sen(c) - cos(c)*sen(a) |
                   |                    cos(a)*cos(b)                     |

 

 

Now using the first expression to compute the angle between two vectors:

 

cos(teta) = [0 0 1] . [x' y' z'] / 1   -> Divided by one because we're using unit vectors, so their modules are 1

cos(teta) = cos(a)*cos(b)

 

And finally testing this value with the results I've found earlier in Weld Quality Report (I tested with additional values and they all resulted to correct results):

 

cost(teta) = cos(5)*cos(5)

cos(teta) = 0.9924

teta = 7.0665 

 

 

Re: How to obtain angle between axes from two frames

Pioneer
Pioneer

seems to be plausible. Smiley Happy

 

it would be nice, if you can share some code of your function.

Re: How to obtain angle between axes from two frames

Phenom
Phenom

@Titaniser

 

I still have not implemented the code, but now it should be easy! I can share when implement it. Thanks for the help! Smiley Very Happy

 

Regards

Re: How to obtain angle between axes from two frames

Valued Contributor
Valued Contributor

Titanizer,

 

something like this:

'Angles in grad.

Dim angleX As Double = 0R

Dim angleY As Double = 12.0R

Dim angleZ As Double = 15.0R

Dim originalPosition As New TxTransformation() 'Hier you can use any transformation.

Dim xAxisVector As New TxVector(1.0R, 0R, 0R)

Dim originalXAxis As TxVector = originalPosition.Transform(xAxisVector)

Dim transformation As New TxTransformation With

 

{

.RotationRPY_XYZ = New TxVector(Math.PI * angleX / 180.0R, Math.PI * angleY / 180.0R, Math.PI * angleZ / 180.0R)

 

}

Dim targetPosition As TxTransformation = originalPosition * transformation

Dim targetXAxis As TxVector = targetPosition.Transform(xAxisVector)

Dim cosinus As Double = (originalXAxis.X * targetXAxis.X + originalXAxis.Y * targetXAxis.Y + originalXAxis.Z * targetXAxis.Z) /

Math.Sqrt(originalXAxis.X * originalXAxis.X + originalXAxis.Y * originalXAxis.Y + originalXAxis.Z * originalXAxis.Z) /

Math.Sqrt(targetXAxis.X * targetXAxis.X + targetXAxis.Y * targetXAxis.Y + targetXAxis.Z * targetXAxis.Z)

Dim angle As Double = Math.Acos(cosinus)

 

Re: How to obtain angle between axes from two frames

Valued Contributor
Valued Contributor

Public Function getZAxisAngle(frame1 As TxFrame, frame2 As TxFrame) As Double

   Dim zAxisVector As New TxVector(0R, 0R, 1.0R)

   Dim originalZAxisVector As TxVector = frame1.AbsoluteLocation.Transform(zAxisVector)

   Dim targetZAxisVector As TxVector = frame2.AbsoluteLocation.Transform(zAxisVector)

   Dim cosinus As Double = TxVector.DotProduct(originalZAxisVector, targetZAxisVector) /

        Math.Sqrt(originalZAxisVector.X * originalZAxisVector.X + originalZAxisVector.Y * originalZAxisVector.Y

                  + originalZAxisVector.Z * originalZAxisVector.Z) /

        Math.Sqrt(targetZAxisVector.X * targetZAxisVector.Z + targetZAxisVector.Y * targetZAxisVector.Y

                  + targetZAxisVector.Z * targetZAxisVector.Z)

   Return Math.Acos(cosinus)

End Function