- Home /

# Quaternions not exact

Hello , sooo i am new to quaternion and i've been trying hard to understand them ... I want to smoothly rotate a cube a 90 degrees so I did the following :

using UnityEngine; using System.Collections;

public class TriggerRotator : MonoBehaviour {

```
private GameObject cube;
private bool startRotation;
float counter = 0;
public Quaternion from;
public Quaternion to;
// Use this for initialization
void Awake() {
cube = GameObject.FindGameObjectWithTag("Plateform");
//from = new Quaternion(0, 0, 0, 1);
//to = new Quaternion(0, 0, 0, 1);
//from.SetEulerAngles(0, 0, 0);
//to.SetEulerAngles(1f, 0, 0);
from = new Quaternion(0, 0, 0, 1);
to = new Quaternion(1.0f, 0, 0, 1);
//from.SetEulerAngles(0, 0, 0);
//to.SetEulerAngles(1f, 0, 0);
//this
}
// Update is called once per frame
void Update () {
Debug.Log(from.eulerAngles);
if(startRotation)
{
cube.transform.rotation = Quaternion.Slerp(from, to, counter);
counter += 0.01f;
}
}
void OnTriggerEnter(Collider other)
{
if(other.gameObject.tag=="Player")
{
Debug.Log("entered");
startRotation = true;
// cube.transform.Rotate(40, 0, 0);
}
}
```

}

the code is running but the cube reaches only 89.981 degrees How can i do to make it a sharp 90 degrees ? Thanks for all

does counter reach exactly one ?

also, i'm not sure that's how you want to construct the quaternion. that form initializes the x,y,z,w components of the quaternion, which are not the same as axis, angle. per the docs, "don't modify this unless you know quaternions inside out".

i'd suggest constructing your quaternions with Quaternion.AngleAxis or Quaternion.Euler.

**Answer** by Bunny83
·
Jan 12, 2017 at 06:03 AM

Your quaternion is not normalized. As elenzil said you usually use either the Euler, AngleAxis, FromToRotation or LookRotation method to construct a quaternion. However if you want to create it manually you should know how it works under the hood.

So if you want to rotate around a given vector "v" by the angle of "a" you would do:

```
float radians = a * Mathf.Deg2Rad;
v = v.normalized * Mathf.Sin(radians / 2);
Quaternion q = new Quaternion(v.x, v.y, v.z, Mathf.Cos(radians / 2));
```

This does exactly the same as `Quaternion.AngleAxis(a, v);`

So as an example with numbers if you want to rotate around the **x axis** by an angle of **90°** you would get

```
new Quaternion(0.70710678f, 0f, 0f, 0.70710678f);
```

`0.70710678f`

is sin(45°) or "1 / sqrt(2)"

As you can see the resulting quaternion is always normalized as it's "length" is `1.0`

at all times. In this example since "0.70710678f" is the inverse of the square root of 2 when you square it you get "0.5". 0.5 + 0 + 0 + 0.5 == 1.0.

Hello , thanks for replying . In the case of Quaternion.AngleAxis(a, v); I looked up Unity Scripting API and i got this : public static Quaternion AngleAxis(float angle, Vector3 axis); so it takes an angle (perhaps 90 degrees in my case ) and a vector3 axis (which might be x , y or z axis) my question now is : how do I rotate it over a certain amount of time ? (for example rotate 90 degrees in 10 seconds)

your original use of slerp() was fine.

all you need to do is construct `from`

and `to`

using AngleAxis() or one of the other methods Bunny83 mentioned. I'd recommend AngleAxis() or Euler(), whichever looks more comfortable to you.

Yes, like elenzil said you can use slerp just fine as long as you use proper absolute rotations. Another way is to do relative rotations. when you deal with Transforms Unity has several helpers which do that for you like Rotate or RotateAround. However you can also do it "manually" by rotating only a fraction each frame

```
void Update()
{
Quaternion q = Quaternion.AngleAxis(90f * Time.deltaTime / 10f, yourAxis);
cube.transform.rotation = q * cube.transform.rotation;
}
```

This would rotate the cube by 90° around "yourAxis" within 10 seconds. Of course this would never "stop" rotating as you do a relative rotation each frame at a rotational speed of 9° per second.

Technically it's also possible to use Vector3.RotateTowards and rotate the current object space to a target space. However keep in mind that you need at least two linear independent vectors to specify a coordinate space. Usually Unity uses the forward vector "z" and the up vector "y" (like the parameters for LookRotation).

There's no "best way" to do rotations as it depends entirely on your usecase.

I'm sorry for disturbing , I also just tried it out

```
if(startRotation)
{
cube.transform.rotation = Quaternion.AngleAxis(90, Vector3.up);
}
```

it gave me a 90.000001

90.000001 is about as close to 90 as you can expect to get. it's a fundamental aspect of doing math with floating-point numbers.

:) So you complain about an error of "one millionth" of a degree? Unity stores rotations as quaternions and not in euler angles representation. Euler angles give you way too many problems. The (euler) angles you see in the inspector are calculated from the internal quaternion rotation.

### Your answer

### Welcome to Unity Answers

The best place to ask and answer questions about development with Unity.

To help users navigate the site we have posted a site navigation guide.

If you are a new user to Unity Answers, check out our FAQ for more information.

Make sure to check out our Knowledge Base for commonly asked Unity questions.

If you are a moderator, see our Moderator Guidelines page.

We are making improvements to UA, see the list of changes.

### Follow this Question

### Related Questions

Error: NullReferenceException: Object reference not set to an instance of an object 1 Answer

Problem lerping between two rotations with mouselook 0 Answers

LookTo Rotation Mouse Drag 2 Answers

transform.Rotate not working beyond 90 / 270 degs with RigidBodies (bug?) 2 Answers

Having trouble instantiating a gameobject with rotation 0 Answers