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.
Solved! Go to Solution.
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));
public double angle3D(TxVector v1, TxVector v2)
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;
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.
thats not wat you asked for originaly, but basically it's like.
directionalVector = new txvector(vector2.x-vector1.x, vector2.y-vector1.y, vector2.z-vector1.z);
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]):
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):
|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
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)
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)