This bugzilla service is closed. All entries have been migrated to https://gitlab.com/libeigen/eigen

Bug 1037

Summary: cross products of vectors of dimensions other than 3
Product: Eigen Reporter: Michael <mishapom>
Component: Core - matrix productsAssignee: Nobody <eigen.nobody>
Status: DECISIONNEEDED ---    
Severity: Feature Request CC: chtz, gael.guennebaud
Priority: Normal    
Version: 3.4 (development)   
Hardware: All   
OS: All   
Whiteboard:

Description Michael 2015-07-09 22:09:36 UTC
I would like to request a cross product of 2D vectors.

Eigen defines cross product only for vectors of size 3; however, cross product is defined (although under a different name) for vectors of arbitrary equal sizes. 

In particular, cross product of vectors of size 2 is very useful in computational geometry. The result should be a scalar equal to the signed area of a parallelepiped spanned by the input vectors. Or, to put it differently, cross product of (v1, v2) and (w1, w2) should be the 3rd coordinate of the cross product of (v1, v2, 0) and (w1, w2, 0).

In general, cross product of N dimensional vectors is a skew-symmetric NxN matrix with i,j-th entry equal, up to the sign, v[i]*w[j]-v[j]*w[i]. 

Since skew-symmetric 3x3 matrices have only 3 independent components (the ones above the diagonal), cross-product of 3D vectors is naturally represented as Vector3. If fact, most of literature that mentions cross-products bypasses the matrix definition and exposes only the 3D vector that naturally represents it.

Similarly, skew-symmetric 2x2 matrices have only 1 independent component; therefore the result could be treated as a scalar. 

The computations that are naturally representable as cross products of 2D vectors occur very often in computing areas and intersections and integration. Therefore it would be useful if Eigen would implement Vector2.cross as was done for Vector3.cross.

I am not confident though whether implementing cross product in full generality, for vectors of arbitrary equal sizes, would be useful.
Comment 1 Michael 2015-07-09 22:17:23 UTC
Here's a relevant wikipedia article:
https://en.wikipedia.org/wiki/Exterior_algebra
Comment 2 Christoph Hertzberg 2015-07-10 11:13:41 UTC
Ok, why not. Though probably it would be better to call it `wedge` instead of `cross`, to avoid confusion.
Decision-needed: Would it be better, to always return a skew-symmetric NxN matrix? Making special cases for 2 and 3 dims sounds a bit arbitrary, IMO. Also, if we allow wedge for dynamic-sized vectors, we could not return a scalar/vector/matrix depending on the input size.

If you only need the 2d case, an alternative would be to provide a rot90 method which rotates a 2d vector by 90 degrees. You could then write:
  a.rot90().dot(b)
to get what you want.
Comment 3 Michael 2015-07-21 22:38:04 UTC
IMHO vector output in 3D is more convenient because most people think of a cross product output as a vector rather than a matrix. Similarly, a scalar output in 2D would be more convenient.

Returning skew-matrices for general size vectors, including dynamic-sized vectors, could be done by implementing that under a different name; `wedge` that you suggested sounds like a good idea. Then wedge would be applicable for any vectors and return a matrix, and cross would be available only in 2D and 3D, returning scalar for 2D and Vector3 for 3D.
 
VectorXf a(3), b(3);
MatrixXf c = a.wedge(b); // Returns 3x3 matrix

Vector3f a, b;
Vector3f c = a.cross(b); // Returns dim 3 vector

VectorXf a(2), b(2);
MatrixXf c = a.wedge(b); // Returns 2x2 matrix

Vector2f a, b;
float c = a.cross(b); // Returns a scalar

VectorXf a(10), b(10);
MatrixXf c = a.wedge(b); // Returns 10x10 matrix

VectorXf a(3), b(3);
MatrixXf c = a.cross(b); // Error! cross defined for fixed size 2D or 3D vectors only! cross is not defined for dynamic sized vectors, even if they happen to be of the right size.

Vector4f a(10), b(10);
MatrixXf c = a.cross(b); // Error! cross defined for fixed size 2D or 3D vectors only!

VectorXf a(2), b(3);
MatrixXf c = a.wedge(b); // Error! wedge defined for vectors of the same size only!
Comment 4 Gael Guennebaud 2015-07-22 08:22:01 UTC
I'm ok to add cross for 2x2. I'm hesitating between calling it "cross" or "cross2" to make it more explicit.

For higher dimensions, I'd rather wait for a real need.
Comment 5 Michael 2015-07-23 21:58:22 UTC
How about "area" because the result is geometrically signed area of parallelogram spanned by the two vectors?
Comment 6 Gael Guennebaud 2015-07-27 09:18:09 UTC
"area" is too specific, for instance this "cross2" operator can also be used on a pair of unit vectors to get their angle' sine.
Comment 7 Michael 2015-07-27 15:53:45 UTC
Ok, cross2 sounds good.
Comment 8 Nobody 2019-12-04 14:44:50 UTC
-- GitLab Migration Automatic Message --

This bug has been migrated to gitlab.com's GitLab instance and has been closed from further activity.

You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.com/libeigen/eigen/issues/1037.