- Home /
Calculate sum over all movements and rotations of object
Hello everybody,
I'd like to do a statistic for my application in which the user can move and rotate an object. In the end I would like to display how far the object has been moved overall and how much the user has rotated the objects.
For the change in position I have the straight forward approach of always adding the change in the objects position to one Vector3 holding the distance in the 3 axis overall. I do this in the Update() method:
if (transform.hasChanged){
overallMovedDist += vector3.Distance(oldPosition, transform.position);
old.position = transform.position;
transform.hasChanged = false;
}
Now for the rotation I wonder, how one would best approach such a statistic? For users it would probably be best to display the values in Eulerangles, I suppose. So after doing two full rotations around for instance the x-axis one would get something like (4*pi, 0, 0) or (2*360, 0,0) as a result: With the same approach as for the position I first tried to calculate this by always directly comparing the change in eulerangles that I got from the quaternions. However if an object is rotated around one axis too far, you get a jump in the values for the other axis as well as some point. If I am correct, this comes from the fact that Unity uses Quaternions internally and the conversion. I tried some stuff with Quaternions already which you can see beneath.
Quaternion relativeChange = Quaternion.Inverse(oldRotation) * transform.rotation; // get rotation between old and new transform.rotation
overallRotation = overallRotation * relativeChange; //add the two Quaternions
oldRotation = transform.rotation;
Debug.Log(overallRotation.ToEulerAngles());
However when I test this in my code, slowly rotate the object around an axis and watch the Log I always get the same thing printed, which is (0.0, 0.0, 0.0). But obviously this is not correct, as I have rotated the object.
Can anybody assist me with how to approach this correctly? Thank you in advance!
Answer by DenisIsDenis · Jun 30, 2021 at 03:11 AM
Why don't you use Vector3
to store the rotation already at the Euler angles. The algorithm is similar to measuring the coordinate change:
Vector3 overallRotation, oldRotation;
void Start()
{
oldRotation = transform.rotation.eulerAngles;
}
void Update()
{
if (oldRotation != transform.rotation.eulerAngles)
{
overallRotation += transform.rotation.eulerAngles - oldRotation;
oldRotation = transform.rotation.eulerAngles;
print(overallRotation);
}
}
The angle size will be between 0 and 360 (because transform.rotation.eulerAngles
has such borders).
Thank you for your response. I tried to share the issue I have with this approach in the original question, however I probably did not do a good job describing it.
However if an object is rotated around one axis too far, you get a jump in the values for the other axis as well as some point
If I use the eulerangle code, and continuously rotate the object around the same axis (like ai$$anonymous$$g to turn it 360 degrees), this is the output for the overallRotation I get at first is along the lines of:
(1.0, 0.0, 0.0) (2.0, 0.0, 0.0) (3.0, 0.0, 0.0)
But when getting for instance close to 90 degree rotation we got the following switch:
(88.0, 0.0, 0.0) (89.0, 0.0, 0.0) (90.0, 0.0, 0.0) (88.0, 180.0, 180) (87.0, 180.0, 180.0)
You can approach the issue from the other side. After all, you somehow implement object rotation for users. Then why not use this: for sure you implement rotation for each axis separately. Then you can write something like this:
// for x-axis
transform.Rotate(xAngle, 0, 0);
overallRotation.x += xAngle; // overallRotation is Vector3
For your method with Quaternion
to work, you need to initialize the overallRotation
(because simply declaring it, it contains null, and when multiplied by null, we get null):
overallRotation = Quaternion.Euler (0, 0, 0);
But, unfortunately, even with the use of Quaternions, you will get the problem you indicated (I also have it).