Rotate along outside of sphere

65 Views Asked by At

Although this is related to programming, I don't want to know the programming end of this, just the math. Based on mouse movement, I want to rotate around the origin and always face it like in Google Earth. In others words, I want to take a 2D vector from the mouse movement, then convert that to a vector that will change my position in 3D. I will always be the same distance from the origin, but my position will change. What is the math to do this?

1

There are 1 best solutions below

3
On BEST ANSWER

Okay. I am going to approach this by vectors. If you want quaternions, you will have to get it translated (you might examine the quaternion, rotation posts that appear in the "Related" section on the right). I am not comfortable enough with quaternions to do it myself.

First we start with the "frame". This is a rectangle in space that represents the screen the user sees. The plane in which this rectangle lays will have equation $\vec n \cdot \vec v = d$, where $\vec n$ is a unit vector normal to the plane, $d \ge 0$ is the distance from the origin to the plane, and $\vec v$ is any point on the plane. I will assume that the center of the frame is the projection of the origin onto this plane (the point $d\vec n$), which does not change (i.e., at all times the view will be centered on the origin). When talking about in-plane coordinates, I will take this point as the origin (not the upper left corner). You also need a unit vector $\vec u$ parallel to the plane (so $\vec u \cdot \vec n = 0$) pointing in the direction of up. The direction of "right" is determined by the vector $\vec r = \vec u \times \vec n$. As $d$ does not change, we will be concerned with the behavior of $n$ and $u$.

A point $(x, y)$ in the frame under the normal coordinate system for graphics (origin in upper left, positive y points down) corresponds to the space point $d\vec n + \left({h\over 2}-y\right)\vec u + \left(x-{w\over2}\right)\vec r$, where $h$ and $w$ are the height and width of the frame.

Let $\vec v_0$ and $\vec v_1$ be the two vectors corresponding to the first point selected by the user and the point it is dragged to, expressed as space points as above. We are only concerned with the directions here, not the points itself, so we convert them to unit vectors by dividing them by their norms: $\hat v_0 = \frac{\vec v_0}{\|\vec v_0\|}, \hat v_1 = \frac{\vec v_1}{\|\vec v_1\|}$. I am interpreting your description as wanting the rotation that carries $\hat v_0$ to $\hat v_1$. To find this, we need:

  • The cosine of the angle between them: $c = \cos \theta = \hat v_0 \cdot \hat v_1$.
  • The sine of the angle between them: $s = \sin \theta = \sqrt{1 - C^2}$ (since $0 \le \theta \le \pi$).
  • The rotation axis vector $\vec m = \hat v_0 \times \hat v_1$.
  • The tensor product of $\vec m$ with itself: $$M_T = \vec m \otimes \vec m = \left [ \begin{matrix} m_1^2 & m_1m_2 & m_1m_3 \\ m_2m_1 & m_2^2 & m_2m_3 \\ m_3m_1 & m_3m_2 & m_3^2 \end{matrix} \right ].$$
  • The "cross product matrix" for $\vec m$: $$M_P = [\vec m]_\times = \left [ \begin{matrix} 0 & -m_3 & m_2 \\ m_3 & 0 & -m_1 \\ -m_2 & m_1 & 0 \end{matrix} \right ].$$

The rotation matrix is given by $R = cI + (1 - c)M_T - sM_P$. (Normally for rotations, the final term would be added rather than subtracted, but since we are rotating the view rather than the object, we need the rotation to go the other direction.)

Finally, the vectors defining the frame are rotated by the matrix $R$: $$\vec n_1 = R\vec n, \;\; \vec u_1 = R\vec u, \;\; \vec r_1 = R\vec r$$