Cross-Product Woes

Started by
3 comments, last by aviosity 18 years, 4 months ago
Hey all, My camera operates in the Position,View,Up Vector manner; has a vector for position, a vector that it's looking at, and an up vector perpendicular to both vectors. To calculate the up vector, I use the cross product. I wrote my own Vector class today to help cement my understanding of vectors, and thought everything worked fine, until I tried to navigate in 3D with my camera implementation, which is limited to the x/z plane. The cross product as I initially wrote it gave an up vector that was perpendicular to the y and z planes, resulting in the world looking like it was turned on its side. Here's my original cross-product code (where vectors have an x, y, and z float, and calcMagnitude() merely uses pythagorean methods and stores the mag in a global variable):

void Vector::crossProduct(Vector v1, Vector v2)
{
	x =  (v1.y*v2.z + v2.y*v1.z)*1.0f-(v1.x*v2.z + v2.x*v1.z)*0.0f+(v1.x*v2.y + v2.x*v1.y)*0.0f;
	y =  (v1.y*v2.z + v2.y*v1.z)*0.0f-(v1.x*v2.z + v2.x*v1.z)*1.0f+(v1.x*v2.y + v2.x*v1.y)*0.0f;
	z =  (v1.y*v2.z + v2.y*v1.z)*0.0f-(v1.x*v2.z + v2.x*v1.z)*0.0f+(v1.x*v2.y + v2.x*v1.y)*1.0f;

	calcMagnitude();
}

However, I've discovered through tinkering around that reversing the x and z assignments results in what appears to be a normal camera view, like so:

void Vector::crossProduct(Vector v1, Vector v2)
{
	z =  (v1.y*v2.z + v2.y*v1.z)*1.0f-(v1.x*v2.z + v2.x*v1.z)*0.0f+(v1.x*v2.y + v2.x*v1.y)*0.0f;
	y =  (v1.y*v2.z + v2.y*v1.z)*0.0f-(v1.x*v2.z + v2.x*v1.z)*1.0f+(v1.x*v2.y + v2.x*v1.y)*0.0f;
	x =  (v1.y*v2.z + v2.y*v1.z)*0.0f-(v1.x*v2.z + v2.x*v1.z)*0.0f+(v1.x*v2.y + v2.x*v1.y)*1.0f;

	calcMagnitude();
}

Does anybody have any idea why this might be happening? Really sorry if it's something obvious, I've been at this for about 12 hours straight so far and am not thinking as clearly as I should be. Thanks so much, Aviosity
Advertisement
I think your cross-product code is way off.
Where v1 and v2 are two vectors, and new_v is the resulting vectornew_v.x = v1.y * v2.z - v1.z * v2.ynew_v.y = v1.z * v2.x - v1.x * v2.znew_v.z = v1.x * v2.y - v1.y * v2.x
I'm not sure if you're doing camera-specific things, but the above is the correct cross-product for two vectors.

Hope that helps.
[ search: google ][ programming: msdn | boost | opengl ][ languages: nihongo ]
As just mentioned, your maths are wrong.

The cross product can be considered as the expansion of the determinant:
| i  j  k  || Ux Uy Uz || Vx Vy Vz |


Your code should be changed to:

void Vector::crossProduct(Vector v1, Vector v2){	x =  (v1.y*v2.z - v2.y*v1.z)*1.0f-(v1.x*v2.z - v2.x*v1.z)*0.0f+(v1.x*v2.y - v2.x*v1.y)*0.0f;	y =  (v1.y*v2.z - v2.y*v1.z)*0.0f-(v1.x*v2.z - v2.x*v1.z)*1.0f+(v1.x*v2.y - v2.x*v1.y)*0.0f;	z =  (v1.y*v2.z - v2.y*v1.z)*0.0f-(v1.x*v2.z - v2.x*v1.z)*0.0f+(v1.x*v2.y - v2.x*v1.y)*1.0f;}

Notice the minus signs instead of the plus signs in the brackets.

However, that can be decomposed into what _goat wrote, as all those multiplies by zero are pointless.

As for using this in a camera, I refer you to another post of mine on the topic.

[Edited by - python_regious on December 4, 2005 10:34:41 AM]
If at first you don't succeed, redefine success.
Your design is off as well. As written, you need to instantiate some non-meaningful Vector first, and then set it equal to the cross product of two others.

It makes more sense either to create and return a Vector that represents the cross product, or to define the operator "cross-product myself with the supplied Vector). Either of these ways, you don't produce the 'meaningless' Vector.

The first way might look like this:

friend Vector crossProduct(const Vector& v1, const Vector& v2) {  int x = // as before  int y = // as before  int z = // as before  return Vector(x, y, z);   // you should have the appropriate constructor defined, yes? The   // calcMagnitude() logic would take place there.}


The second way would be like:

void Vector::crossMultiplyBy(const Vector& other) {  x = // as before, except the current object plays the role of v1  y = // and so on.  z = // yadda yadda yadda...  calcMagnitude();}

Thanks to all of you for catching my ignorant math errors...couldn't find the problem all night...still plowing through this math stuff, the goal is to teach myself the math. Thanks again!

Aviosity

This topic is closed to new replies.

Advertisement