<p>It is likely that your specific problem arises from a singularity in <code>atan</code> when <code>m_position.z</code> goes to 0. Rather than try to debug that, I'll point out that you don't need to transform your camera position into an angle to then modify it: rather, just create a rotation from your <code>newPhi</code> and <code>newTheta</code> angles, in the form of a rotation matrix or quaternion, and then apply it to your vector, directly rotating it without doing the perilous round-trip to an angle.</p>

CC BY-SA 3.0
2015-08-25T07:53:23.183Z
or use atan2 which is there to deal with all quadrants correctly
ratchet freak
CC BY-SA 3.0
2015-08-25T10:06:14.517Z
@ratchetfreak Yes, but in general, solution that avoid trigonometry or angles tend to be more robust and elegant.
yuriks
CC BY-SA 3.0
2015-08-25T05:04:30.273Z
2015-08-25T05:04:30.273Z
yuriks
<p>I am implementing a trackball, i.e. a camera orbiting about a fixed point, in my case the origin. When I do left click with the mouse and start moving it, I compute delta values for the angles of a sphere centered at the origin given the displacement in x and y directions of the mouse. My implementation is as follows</p>

<pre><code>void SimplePerspectiveCamera::
mouseMove(const double&amp; mouseX, const double&amp; mouseY)
{
    if(m_setPan)
    {
        float sensitivity = 0.0075f;
        float newX = (mouseX - m_prevX) * sensitivity;
        float newY = (mouseY - m_prevY) * sensitivity;
        // TODO: Understand if it is necessary to reset the up vector to (0,1,0)
        m_up = Vector(0.0f, 1.0f, 0.0f);
        setLookAt(m_lookAt + Vector(-newX, newY, 0.0f));
        setPosition(m_position + Vector(-newX, newY, 0.0f));
        m_prevX = mouseX;
        m_prevY = mouseY;
    }
    if(m_setRotate)
    {
        float sensitivity = 0.005f;
        float newPhi = (mouseX - m_prevX) * sensitivity;
        float newTheta = (mouseY - m_prevY) * sensitivity;
        // Transform to spherical coordinates to use mouse move as deltas for
        // the angles.
        float r = m_position.norm();
        float theta = std::acos(m_position.y / r);
        float phi = std::atan(m_position.x / m_position.z);

        theta += newTheta;
        phi += newPhi;

        m_up = Vector(0.0f, 1.0f, 0.0f);
        Vector newPosition(r*std::sin(theta)*std::sin(phi), r*std::cos(theta),
                r*std::sin(theta)*std::cos(phi));
        setPosition(newPosition);
        m_prevX = mouseX;
        m_prevY = mouseY;
    }
}
</code></pre>

<p>What I was expecting is to be able to rotate the camera around the cube in the scene so that I can see all around it. My code almost achieves this, but I don't understand why after rotating a certain amount the camera jumps to the exact opposite side of the cube.</p>

<p>You can check what weird swap I am talking about <a href="https://vimeo.com/137210181" rel="nofollow">this link</a></p>

<p>What am I missing so that the rotation around the object goes all the way around it?</p>

CC BY-SA 3.0
2015-08-25T04:39:10.677Z
The question lacks some basic explanation about what is being asked. What exactly are you trying to do? From your video, what seems to be happening is that when the rotation crosses a certain point, the rotation instantly snaps back/forward by 180 degrees. (That is, the colors aren't being swapped, you're seeing the back of the cube instead.)
yuriks
CC BY-SA 3.0
2015-08-25T04:49:56.480Z
I assume that the `m_setPan` path isn't used here? Also, why does your rotation code modify position? (And I don't see it setting a rotation anywhere.)
yuriks
CC BY-SA 3.0
2015-08-25T04:53:57.070Z
You assume correct. What I'm doing is to orbit the camera over a sphere centered at the origin, therefore given the displacement in (x,y) of the mouse, I compute the spherical coords of the position of the camera on that sphere, once I have placed the camera I update the view-matrix (done inside `setPosition()`)
BRabbit27
CC BY-SA 3.0
2015-08-25T05:06:13.067Z
Just as a note, this is the kind of thing that can be most easily debugged by printing the `m_position`, `theta` and `phi` values to the screen on every update and observing their values as you drag the cube around. This should make it easy to observe any singularities or abnormalities that could be causing the problem.
yuriks
<transformations><trackball>
Why is the color in the cube being weirdly swapped?
BRabbit27
# Why is the color in the cube being weirdly swapped?

(Asked by: username_0 on 2015-08-25)

I am implementing a trackball, i.e. a camera orbiting about a fixed point, in my case the origin. When I do left click with the mouse and start moving it, I compute delta values for the angles of a sphere centered at the origin given the displacement in x and y directions of the mouse. My implementation is as follows

```
void SimplePerspectiveCamera::
mouseMove(const double& mouseX, const double& mouseY)
{
    if(m_setPan)
    {
        float sensitivity = 0.0075f;
        float newX = (mouseX - m_prevX) * sensitivity;
        float newY = (mouseY - m_prevY) * sensitivity;
        // TODO: Understand if it is necessary to reset the up vector to (0,1,0)
        m_up = Vector(0.0f, 1.0f, 0.0f);
        setLookAt(m_lookAt + Vector(-newX, newY, 0.0f));
        setPosition(m_position + Vector(-newX, newY, 0.0f));
        m_prevX = mouseX;
        m_prevY = mouseY;
    }
    if(m_setRotate)
    {
        float sensitivity = 0.005f;
        float newPhi = (mouseX - m_prevX) * sensitivity;
        float newTheta = (mouseY - m_prevY) * sensitivity;
        // Transform to spherical coordinates to use mouse move as deltas for
        // the angles.
        float r = m_position.norm();
        float theta = std::acos(m_position.y / r);
        float phi = std::atan(m_position.x / m_position.z);

        theta += newTheta;
        phi += newPhi;

        m_up = Vector(0.0f, 1.0f, 0.0f);
        Vector newPosition(r*std::sin(theta)*std::sin(phi), r*std::cos(theta),
                r*std::sin(theta)*std::cos(phi));
        setPosition(newPosition);
        m_prevX = mouseX;
        m_prevY = mouseY;
    }
}

```

What I was expecting is to be able to rotate the camera around the cube in the scene so that I can see all around it. My code almost achieves this, but I don't understand why after rotating a certain amount the camera jumps to the exact opposite side of the cube.

You can check what weird swap I am talking about [this link](https://vimeo.com/137210181)

What am I missing so that the rotation around the object goes all the way around it?

**Tags:** transformations, trackball

> **Comments:**
> **username_1**: The question lacks some basic explanation about what is being asked. What exactly are you trying to do? From your video, what seems to be happening is that when the rotation crosses a certain point, the rotation instantly snaps back/forward by 180 degrees. (That is, the colors aren't being swapped, you're seeing the back of the cube instead.)  
> **username_1**: I assume that the `m_setPan` path isn't used here? Also, why does your rotation code modify position? (And I don't see it setting a rotation anywhere.)  
> **username_0**: You assume correct. What I'm doing is to orbit the camera over a sphere centered at the origin, therefore given the displacement in (x,y) of the mouse, I compute the spherical coords of the position of the camera on that sphere, once I have placed the camera I update the view-matrix (done inside `setPosition()`)  
> **username_1**: Just as a note, this is the kind of thing that can be most easily debugged by printing the `m_position`, `theta` and `phi` values to the screen on every update and observing their values as you drag the cube around. This should make it easy to observe any singularities or abnormalities that could be causing the problem.  

---

## 1 answers

### Answer by username_1 on 2015-08-25. Score: 6 | Accepted answer

It is likely that your specific problem arises from a singularity in `atan` when `m_position.z` goes to 0. Rather than try to debug that, I'll point out that you don't need to transform your camera position into an angle to then modify it: rather, just create a rotation from your `newPhi` and `newTheta` angles, in the form of a rotation matrix or quaternion, and then apply it to your vector, directly rotating it without doing the perilous round-trip to an angle.

> **Comments:**
> **username_2**: or use atan2 which is there to deal with all quadrants correctly  
> **username_1**: @username_2 Yes, but in general, solution that avoid trigonometry or angles tend to be more robust and elegant.  

---

