<p>Alright, using ArcBall in SharpGL.SceneGraph.Core for my mouse controlled rotations fixed the problem. </p>

<p>Just had to edit the following</p>

<pre><code>if (length &gt; 1.0f)
        {
            //  Get normalising factor.
            float norm = 1.0f / (float)Math.Sqrt(length);

            //  Return normalised vector, a point on the sphere.
            newVector = new Vertex(scaledX * norm, scaledY * norm, 0);
        }
        else
        {
            //  Return a vector to a point mapped inside the sphere.
            newVector = new Vertex(scaledX, scaledY, (float)Math.Sqrt(1.0f - length));
        }
</code></pre>

<p>in ArcBall.MapToSphere so side movements rotate the object around the y axis instead of the z axis. Works as intended now.</p>

CC BY-SA 3.0
2015-12-09T12:11:36.917Z
2015-12-09T12:11:36.917Z
Patrick
<p>Transformations, and especially rotations, may have different visual effects, depending on the order they are applied to the target object. For example, using a rotation $M_R$ and a translation $M_T$ to the object's vertices $v_i$, $M_R \cdot M_T \cdot v_i$ will usually<sup>1</sup> result in a different pose than $M_T \cdot M_R \cdot v_i$ does.</p>

<p><a href="https://i.sstatic.net/lE2zn.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/lE2zn.png" alt="rotation and translation"></a></p>

<p><sub><sup>90 degree rotation and translation along the x axis applied to the box. Left: translation first ($M_R \cdot M_T \cdot v_i$). Right: rotation first ($M_T \cdot M_R \cdot v_i$).</sup></sub></p>

<p>The key here is to keep in mind to which coordinate system the transformation is applied. Assuming that your to be rotated object initially is in the origin without transformations applied, the first rotation will always yield the desired effect. This is because you're applying the first transformation to the object.</p>

<p>But once your object is already transformed (rotated, translated, whatever) by $M_1$, technically you can already apply the next transformation $M_2$ in two places. Namely, </p>

<ol>
<li>$M_1 \cdot M_2 \cdot v_i$ or </li>
<li>$M_2 \cdot M_1 \cdot v_i$</li>
</ol>

<p>You describe that </p>

<blockquote>
  <p>so if I rotate the object around the x axis by 180° and then move my mouse left, the object will rotate to the right instead of left (since the y axis is now inverted).</p>
</blockquote>

<p>This is, because the second rotation is applied to the object itself, which is case 1 of the above. But you want to have the second case, so you need to apply the rotations the other way around. That way, the new rotation will be applied to the already rotated object, i.e. the outer coordinate system.</p>

<p>Ideally, as long as the user holds the mouse button down you adjust that transformation $M_2$. Calculate the distance the mouse moved from the point the user pressed the button, recalculate the whole rotation ($M_2$) and drop whatever you calculated in the time between the mouse-down event and the previous frame. So for the ongoing rotation, pretend that the user moved the mouse instantly from the start to the current position.</p>

<p>Once the mouse button is released, you can finalize the transformation and multiply it into $M_1$, which is the identity matrix in the beginning. (Assuming you always want to rotate around the world's center.)</p>

<hr>

<p><sub><sup>1</sup> There are some special cases where the result is the same, e.g. if the translation direction matches the rotation axis.</sub></p>

CC BY-SA 3.0
2015-12-09T05:59:02.037Z
Ok this does answer the question. Hovewer, the explanation probably reqjires one to knpw the answer before understanding. Yould you drop down the abstraction a bit.
joojaa
CC BY-SA 3.0
2015-12-09T07:00:28.523Z
The theory is clear, but how would one go about implementing it? The 2 rotations I used in my example could be done without releasing the mouse inbetween, so there isn't really a clear cut line between them. The user may even go crazy and rotate up left down left which could yield something like cameraRotation.X = 0 cameraRotation.Y = 200, which says nothing about the actual ordner in which the transformations happened.
Patrick
CC BY-SA 3.0
2015-12-09T21:50:46.807Z
@Patrick Moving the mouse back without releasing the mouse button while rotating an object usually leads to the same result as if the mouse had not been moved e.g. up and back down at all. I added a few words about this (pretend the mouse moved instantly to the current position).
Nero
CC BY-SA 3.0
2015-12-08T22:46:58.063Z
2015-12-09T21:44:33.037Z
2015-12-09T21:44:33.037Z
Nero
<p>In my SharpGL application I do a very simple, mouse controlled rotation of the scene.</p>

<pre><code>gl.Rotate(cameraRotation.X, cameraRotation.Y, 0.0f);
</code></pre>

<p>where</p>

<pre><code>cameraRotation.Y += MousePosition.X - previousMousePositionX;
cameraRotation.X += MousePosition.Y - previousMousePositionY;
</code></pre>

<p>The problem with this is that the x rotation always comes first, so if I rotate the object around the x axis by 180° and then move my mouse left, the object will rotate to the right instead of left (since the y axis is now inverted). Is there a way to change this so that the object always rotates into the mouse movement direction, regardless of its current position? (like netfabb does it for example)</p>

<opengl>
Always rotate in the direction of mouse movement
Patrick
# Always rotate in the direction of mouse movement

(Asked by: username_0 on 2015-12-07)

In my SharpGL application I do a very simple, mouse controlled rotation of the scene.

```
gl.Rotate(cameraRotation.X, cameraRotation.Y, 0.0f);

```

where

```
cameraRotation.Y += MousePosition.X - previousMousePositionX;
cameraRotation.X += MousePosition.Y - previousMousePositionY;

```

The problem with this is that the x rotation always comes first, so if I rotate the object around the x axis by 180° and then move my mouse left, the object will rotate to the right instead of left (since the y axis is now inverted). Is there a way to change this so that the object always rotates into the mouse movement direction, regardless of its current position? (like netfabb does it for example)

**Tags:** opengl


---

## 2 answers

### Answer by username_0 on 2015-12-09. Score: 0 | Accepted answer

Alright, using ArcBall in SharpGL.SceneGraph.Core for my mouse controlled rotations fixed the problem.

Just had to edit the following

```
if (length > 1.0f)
        {
            //  Get normalising factor.
            float norm = 1.0f / (float)Math.Sqrt(length);

            //  Return normalised vector, a point on the sphere.
            newVector = new Vertex(scaledX * norm, scaledY * norm, 0);
        }
        else
        {
            //  Return a vector to a point mapped inside the sphere.
            newVector = new Vertex(scaledX, scaledY, (float)Math.Sqrt(1.0f - length));
        }

```

in ArcBall.MapToSphere so side movements rotate the object around the y axis instead of the z axis. Works as intended now.


---

### Answer by username_1 on 2015-12-08. Score: 1

Transformations, and especially rotations, may have different visual effects, depending on the order they are applied to the target object. For example, using a rotation $M\_R$ and a translation $M\_T$ to the object's vertices $v\_i$, $M\_R \cdot M\_T \cdot v\_i$ will usually1 result in a different pose than $M\_T \cdot M\_R \cdot v\_i$ does.

[![rotation and translation](https://i.sstatic.net/lE2zn.png)](https://i.sstatic.net/lE2zn.png)

90 degree rotation and translation along the x axis applied to the box. Left: translation first ($M\_R \cdot M\_T \cdot v\_i$). Right: rotation first ($M\_T \cdot M\_R \cdot v\_i$).

The key here is to keep in mind to which coordinate system the transformation is applied. Assuming that your to be rotated object initially is in the origin without transformations applied, the first rotation will always yield the desired effect. This is because you're applying the first transformation to the object.

But once your object is already transformed (rotated, translated, whatever) by $M\_1$, technically you can already apply the next transformation $M\_2$ in two places. Namely,

1. $M\_1 \cdot M\_2 \cdot v\_i$ or
2. $M\_2 \cdot M\_1 \cdot v\_i$

You describe that

> so if I rotate the object around the x axis by 180° and then move my mouse left, the object will rotate to the right instead of left (since the y axis is now inverted).

This is, because the second rotation is applied to the object itself, which is case 1 of the above. But you want to have the second case, so you need to apply the rotations the other way around. That way, the new rotation will be applied to the already rotated object, i.e. the outer coordinate system.

Ideally, as long as the user holds the mouse button down you adjust that transformation $M\_2$. Calculate the distance the mouse moved from the point the user pressed the button, recalculate the whole rotation ($M\_2$) and drop whatever you calculated in the time between the mouse-down event and the previous frame. So for the ongoing rotation, pretend that the user moved the mouse instantly from the start to the current position.

Once the mouse button is released, you can finalize the transformation and multiply it into $M\_1$, which is the identity matrix in the beginning. (Assuming you always want to rotate around the world's center.)

---

1 There are some special cases where the result is the same, e.g. if the translation direction matches the rotation axis.

> **Comments:**
> **username_2**: Ok this does answer the question. Hovewer, the explanation probably reqjires one to knpw the answer before understanding. Yould you drop down the abstraction a bit.  
> **username_0**: The theory is clear, but how would one go about implementing it? The 2 rotations I used in my example could be done without releasing the mouse inbetween, so there isn't really a clear cut line between them. The user may even go crazy and rotate up left down left which could yield something like cameraRotation.X = 0 cameraRotation.Y = 200, which says nothing about the actual ordner in which the transformations happened.  
> **username_1**: @username_0 Moving the mouse back without releasing the mouse button while rotating an object usually leads to the same result as if the mouse had not been moved e.g. up and back down at all. I added a few words about this (pretend the mouse moved instantly to the current position).  

---

