<p>First of all instead of taking <code>Cross(WorldUp, Front/LookAt)</code> you can use Gram-Schmidt orthogonalization to produce an orthogonal vector that's close to the WorldUp vector. Then you take the cross of this orthogonal vector and the look at to get the side vector. However as you mentioned this'd fail if the vectors are parallel.</p>

<p>Hence the usual solution is to pick another vector that's not parallel to the look at one and again use Gram-Schmidt orthogonalization to produce the orthogonal vector ( camera up) and then take the cross.</p>

<p>The maths is like this. </p>

<pre><code>CameraUp = c
WorldUp = w
LookAt = l

c = w - ( (w.l) / ||l||^2 ) * l 
</code></pre>

<p>What it does is this. We know that world up isn't pure orthogonal to the look at vector. So we take the projection of world up onto the direction of the look at vector. Subtract the parallel part of this projection from the world up vector to obtain the remaining i.e. the orthogonal part. This vector is closer to the world up but is purely orthogonal to the look at vector.</p>

CC BY-SA 3.0
2017-08-14T06:41:19.960Z
i can't get why this formula will change the bad situation. If w equals l, then c will still be zero vector? Because when these two vectors are parallel, there will only parallel part, and no orthogonal part.
ZenWu
CC BY-SA 3.0
2017-08-14T07:23:56.220Z
Yes that's why i said, you have to check for this. If that's the case then you'll have to take another arbitrary vector. For example if "j" is the world up and it's parallel with look at, take "i' or "k". What i wanted to point out is, `world up` and `front` vector won't always be orthogonal. To make an orthogonal vector close to `world up` you have to use that formula
gallickgunner
CC BY-SA 3.0
2017-08-14T07:29:23.927Z
if just switch j to i, the the RIGHT vector will probably change a lot. And cross(front, worldUp) is used to compute right vector, the worldUp don't need to be orthogonal to front, just not parallel.
ZenWu
CC BY-SA 3.0
2017-08-14T07:41:52.023Z
i think the world up needs to be orthogonal to the front, else you won't have an orthogonal basis for the camera?
gallickgunner
CC BY-SA 3.0
2017-08-14T07:45:21.660Z
for usual, figure out RIGHT by cross(front, woldUp) first, and then get real up by cross(front, right). That's why it's called world up but not camera up. Your idea make sense maybe, but i think it's not related to the problem i met here.
ZenWu
CC BY-SA 3.0
2017-08-14T08:10:41.437Z
Well from what i have read in books either you choose an arbitrary vector to solve this issue or store the starting orientation in a matrix then apply a rotation matrix to change the orientation.
gallickgunner
CC BY-SA 3.0
2017-08-12T20:34:06.070Z
2017-08-12T20:34:06.070Z
gallickgunner
<p>You can't have a camera with collinear look/front and up vectors. It doesn't make geometric sense. The whole point of the up vector is to disambiguate roll.</p>

<p>As russ says, for a "first-person" camera it's reasonable to always use world-up for the up vector and simply lock the pitch angle to within (say) 85 degrees of horizontal, to avoid degenerate cases.</p>

<p>For a CAD viewer where the user would expect to pitch the camera arbitrarily, you should rotate <strong>both</strong> the up and front vectors about the right vector when the user pitches the camera, to ensure they are always perpendicular. Beware that when you do this kind of arbitrary rotation, it's easy for the user to get stuck in unfortunate roll angles. You need to do at least one of the following to let them get themselves out:</p>

<ol>
<li>Have a "reset up" button that applies the pitch angle limits and resets the up vector to world up.</li>
<li>Give the user arbitrary control over camera roll. (This can be confusing, so it's best to offer the first option as well if you do this.)</li>
<li>Constrain the up vector so that its dot product with the world up is non-negative. That is, if the user pitches so far up or down that they are upside-down, roll the camera 180 degrees.</li>
</ol>

CC BY-SA 3.0
2017-08-11T16:05:54.240Z
2017-08-11T16:05:54.240Z
Dan Hulme
<p>Get the title problem when implementing a walkthrough camera.</p>

<p>I use normlize(cross(WorldUp, Front)) to get Right vector. And when they are collinear, I get a zero vector.</p>

<p>Is there any more robust fake version? Or do I need to store the "previous" Right vector as a backup?</p>

CC BY-SA 3.0
2017-08-11T07:06:21.977Z
Are you doing a first-person-shooter style camera? Most games that implement this kind of camera restrict the x-axis rotation so you can never look straight up or down (clamped at maybe 85 degrees) to avoid exactly this problem.
russ
CC BY-SA 3.0
2017-08-11T07:09:15.890Z
@russ its a CAD camera in my case, so it does need every view angle.
ZenWu
CC BY-SA 3.0
2017-08-11T07:19:16.197Z
hmmm ok, then i guess storing a right vector to handle the edge cases would be one way to do it. either that or use a quaternion for the camera orientation and extract the matrix from that.
russ
CC BY-SA 3.0
2017-08-11T07:24:06.873Z
@russ yeah i think quaternion is a nice solution. If i get how to do euler rotation on quaternion done, i will answer this question myself. THX
ZenWu
CC BY-SA 3.0
2017-08-11T18:15:39.527Z
An alternate to quaternions is to describe the camera's rotation in spherical coordinates: one angle represents rotation around the vertical axis (0 to 360 degrees) and another angle represents how far you are looking down or up (-90 to +90).  If going that route you may be interested in this which talks about how to transform between spherical and cartesian coordinates so you can get vectors out: https://blog.demofox.org/2013/10/12/converting-to-and-from-polar-spherical-coordinates-made-easy/
Alan Wolfe
<transformations><camera>
How to get camera Right vector when Front vector and WorldUp vector are collinear
ZenWu
# How to get camera Right vector when Front vector and WorldUp vector are collinear

(Asked by: username_0 on 2017-08-11)

Get the title problem when implementing a walkthrough camera.

I use normlize(cross(WorldUp, Front)) to get Right vector. And when they are collinear, I get a zero vector.

Is there any more robust fake version? Or do I need to store the "previous" Right vector as a backup?

**Tags:** transformations, camera

> **Comments:**
> **username_1**: Are you doing a first-person-shooter style camera? Most games that implement this kind of camera restrict the x-axis rotation so you can never look straight up or down (clamped at maybe 85 degrees) to avoid exactly this problem.  
> **username_0**: @username_1 its a CAD camera in my case, so it does need every view angle.  
> **username_1**: hmmm ok, then i guess storing a right vector to handle the edge cases would be one way to do it. either that or use a quaternion for the camera orientation and extract the matrix from that.  
> **username_0**: @username_1 yeah i think quaternion is a nice solution. If i get how to do euler rotation on quaternion done, i will answer this question myself. THX  
> **username_2**: An alternate to quaternions is to describe the camera's rotation in spherical coordinates: one angle represents rotation around the vertical axis (0 to 360 degrees) and another angle represents how far you are looking down or up (-90 to +90).  If going that route you may be interested in this which talks about how to transform between spherical and cartesian coordinates so you can get vectors out: https://blog.demofox.org/2013/10/12/converting-to-and-from-polar-spherical-coordinates-made-easy/  

---

## 2 answers

### Answer by username_3 on 2017-08-12. Score: 1

First of all instead of taking `Cross(WorldUp, Front/LookAt)` you can use Gram-Schmidt orthogonalization to produce an orthogonal vector that's close to the WorldUp vector. Then you take the cross of this orthogonal vector and the look at to get the side vector. However as you mentioned this'd fail if the vectors are parallel.

Hence the usual solution is to pick another vector that's not parallel to the look at one and again use Gram-Schmidt orthogonalization to produce the orthogonal vector ( camera up) and then take the cross.

The maths is like this.

```
CameraUp = c
WorldUp = w
LookAt = l

c = w - ( (w.l) / ||l||^2 ) * l 

```

What it does is this. We know that world up isn't pure orthogonal to the look at vector. So we take the projection of world up onto the direction of the look at vector. Subtract the parallel part of this projection from the world up vector to obtain the remaining i.e. the orthogonal part. This vector is closer to the world up but is purely orthogonal to the look at vector.

> **Comments:**
> **username_0**: i can't get why this formula will change the bad situation. If w equals l, then c will still be zero vector? Because when these two vectors are parallel, there will only parallel part, and no orthogonal part.  
> **username_3**: Yes that's why i said, you have to check for this. If that's the case then you'll have to take another arbitrary vector. For example if "j" is the world up and it's parallel with look at, take "i' or "k". What i wanted to point out is, `world up` and `front` vector won't always be orthogonal. To make an orthogonal vector close to `world up` you have to use that formula  
> **username_0**: if just switch j to i, the the RIGHT vector will probably change a lot. And cross(front, worldUp) is used to compute right vector, the worldUp don't need to be orthogonal to front, just not parallel.  
> **username_3**: i think the world up needs to be orthogonal to the front, else you won't have an orthogonal basis for the camera?  
> **username_0**: for usual, figure out RIGHT by cross(front, woldUp) first, and then get real up by cross(front, right). That's why it's called world up but not camera up. Your idea make sense maybe, but i think it's not related to the problem i met here.  
> **username_3**: Well from what i have read in books either you choose an arbitrary vector to solve this issue or store the starting orientation in a matrix then apply a rotation matrix to change the orientation.  

---

### Answer by username_4 on 2017-08-11. Score: 1

You can't have a camera with collinear look/front and up vectors. It doesn't make geometric sense. The whole point of the up vector is to disambiguate roll.

As username_1 says, for a "first-person" camera it's reasonable to always use world-up for the up vector and simply lock the pitch angle to within (say) 85 degrees of horizontal, to avoid degenerate cases.

For a CAD viewer where the user would expect to pitch the camera arbitrarily, you should rotate **both** the up and front vectors about the right vector when the user pitches the camera, to ensure they are always perpendicular. Beware that when you do this kind of arbitrary rotation, it's easy for the user to get stuck in unfortunate roll angles. You need to do at least one of the following to let them get themselves out:

1. Have a "reset up" button that applies the pitch angle limits and resets the up vector to world up.
2. Give the user arbitrary control over camera roll. (This can be confusing, so it's best to offer the first option as well if you do this.)
3. Constrain the up vector so that its dot product with the world up is non-negative. That is, if the user pitches so far up or down that they are upside-down, roll the camera 180 degrees.


---

