Sign in to follow this  
aviosity

Cross-Product Woes

Recommended Posts

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

Share this post


Link to post
Share on other sites
I think your cross-product code is way off.
Where v1 and v2 are two vectors, and new_v is the resulting vector
new_v.x = v1.y * v2.z - v1.z * v2.y
new_v.y = v1.z * v2.x - v1.x * v2.z
new_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.

Share this post


Link to post
Share on other sites
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]

Share this post


Link to post
Share on other sites
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();
}

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this