views:

394

answers:

6

I have the following piece of pseudo-C/Java/C# code:

int a[]= { 30, 20 };
int b[] = { 40, 50 };
int c[] = {12, 12};

How do I compute the cross-product ABxAC?

+2  A: 

The cross product is a vector, it doesn't have "a sign".

Do you mean the scalar (dot) product? If you do, then that is computed as for a pair of vectors [a,b,c]•[d,e,f] as ad + be + cf, so the sign of that expression is the sign of the dot product.

Figuring out the sign without doing the multiplications and adds is probably not faster than just doing them.

unwind
@unwind: My bad, I thought dot "product" and cross-product were identical but, yes, indeed I'm after the "dot product", which is also the "scalar product": http://en.wikipedia.org/wiki/Dot_product
Webinator
No you were right in the first place, you are not looking for the dot product, it will not give you whether your point is to the left or the right of your line.
Harald Scheirich
+2  A: 

Since all three points have just two components, I'll assume that the z-component for all three is zero. That means that the vectors AB and BC are in the xy-plane, so the cross-product is a vector that points in the z-direction, with its x and y components equal to zero.

If by "sign" you mean whether it points in the positive or negative z-direction, the computation will tell you that.

In your case, the two vectors are AB = (10, 30, 0) and AC = (-18, -8, 0). If I take the cross-product of those two, I get vector AB X AC = (0, 0, 460). Do you mean to say that this has a positive sign because the z-component is positive? If yes, that's your answer.

UPDATE: If it's the scalar product you want, it's negative in this case:

AB dot AC = -180 -240 + 0 = -420.

duffymo
Correct answer.. Unfortunately he changed the question :).
svens
That's what my update addresses. I have both covered.
duffymo
A: 

From reading the question you linked, it seems you want the sign of the z-component of the cross-product (assuming 0 z-value for AB and AC); to indicate which side of the line AB the point C lies.
Assuming that's the case, all you need is the sign of the determinant of the matrix with AB and AC as its rows.

xAB = b[0] - a[0]
yAB = b[1] - a[1]
xAC = c[0] - a[0]
yAC = c[1] - a[1]
detABxAC = (xAB * yAC) - (yAB * xAC)
if (detABxAC < 0) 
  // sign is negative
elif (detABxAC > 0) 
  // sign is positive
else 
  // sign is 0, i.e. C is collinear with A, B
tzaman
@tzaman: +1 to all, thanks
Webinator
@Donal: nope, that's the case for a dot-product (which this isn't).@WizardOfOdds: You're welcome. Note that if this is what you want, it isn't actually the dot-product you're after, but the sign of one component of the cross-product.
tzaman
@tzaman: I misread what you wrote and assumed that it was an answer for the question. Turned out the questioner didn't originally know the difference between dot and cross products, which is somewhat important, but by the time I read the question it had already been corrected/clarified. It was all just a mixup.
Donal Fellows
@Donal: I figured as much; no worries. :)
tzaman
+1  A: 

Dot product:

a   d
b * e = a*d + b*e + c*f
c   f

Checking if it's positive/zero/negative is trivial.

Georg
+2  A: 

The solution that was given to you in your last question basically adds a Z=0 for all your points. Over the so extended vectors you calculate your cross product. Geometrically the cross product produces a vector that is orthogonal to the two vectors used for the calculation, as both of your vectors lie in the XY plane the result will only have a Z component. The Sign of that z component denotes wether that vector is looking up or down on the XY plane. That sign is dependend on AB being in clockwise or counter clockwise order from each other. That in turn means that the sign of z component shows you if the point you are looking at lies to the left or the right of the line that is on AB.

So with the crossproduct of two vectors A and B being the vector

AxB = (AyBz − AzBy, AzBx − AxBz, AxBy − AyBx)

with Az and Bz being zero you are left with the third component of that vector

AxBy - AyBx

With A being the vector from point a to b, and B being the vector from point a to c means

Ax = (b[x]-a[x])
Ay = (b[y]-a[y])
Bx = (c[x]-a[x])
By = (c[y]-a[y])

giving

AxBy - AyBx = (b[x]-a[x])*(c[y]-a[y])-(b[y]-a[y])*(c[x]-a[x])

which is a scalar, the sign of that scalar will tell you wether point c lies to the left or right of vector ab

Aternatively you can look at stack overflow or gamedev

Harald Scheirich
@Harald Scheirich: thanks for detailed explanation and great links. You meant *"with Az and Bz being zero..."* ? (I don't dare to edit your answer)
Webinator
@Harald Scheirich: isn't this exactly the same code as the one tzaman gave? (I don't know who voted him down)
Webinator
@Wizard Yes that is the same calculation, the voting down might have started with the title and subject of this question being changed (dunoo who did that)
Harald Scheirich
+1  A: 

Assuming whether you're asking whether the angle between AB and AC is acute or obtuse, you want this:

int a[]= { 30, 20 };
int b[] = { 40, 50 };
int c[] = {12, 12};

int ab_x = b[0] - a[0];
int ab_y = b[1] - a[1];
int ac_x = c[0] - a[0];
int ac_x = c[1] - a[1];

int dot = ab_x*ac_x + ab_y*ac_y;
boolean signABxAC = dot > 0; // pick your preferred comparison here
Donal Fellows