Wednesday, March 8, 2017

quaternion - How to express and verify euler rotation limits in Unity


I need to find a way to set min and max angles for each Euler component and check whether transform.localEulerAngles falls within those limits.


My current code looks like this:


class JointLimit : MonoBehaviour
{
[SerializeField]
[Range(-180f, 180f)]
private float minX = -180f;
[SerializeField]
[Range(-180f, 180f)]

private float maxX = 180f;
[SerializeField]
[Range(-180f, 180f)]
private float minY = -180f;
[SerializeField]
[Range(-180f, 180f)]
private float maxY = 180f;
[SerializeField]
[Range(-180f, 180f)]
private float minZ = -180f;

[SerializeField]
[Range(-180f, 180f)]
private float maxZ = 180f;

public float Error
{
get
{
Vector3 localEuler = transform.localEulerAngles;
Vector3 signedLocalEuler = new Vector3(Mathf.DeltaAngle(localEuler.x, 0), Mathf.DeltaAngle(localEuler.y, 0), Mathf.DeltaAngle(localEuler.z, 0));


float error = 0;
error += Mathf.Max(0, minX - signedLocalEuler.x);
error += Mathf.Max(0, signedLocalEuler.x - maxX);
error += Mathf.Max(0, minY - signedLocalEuler.y);
error += Mathf.Max(0, signedLocalEuler.y - maxY);
error += Mathf.Max(0, minZ - signedLocalEuler.z);
error += Mathf.Max(0, signedLocalEuler.z - maxZ);
return error;
}

}
}

This basically checks whether the Euler components fall within the specified range and sums the exceeding angles up to an error.


The problem is that Unity internally stores rotations as Quaternions and that there can be several euler representations for a single Quaternion, like Euler 123f, 17f, 235f and Euler 57f, 197f, 55f are the same thing.


Is there any way I can bring an Euler representation into some kind of normalized form that allows me to reliably check it against my limits?




No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...