Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[math] vector_triple_product compilation error for 2-dimensional vectors #4858

Open
flysand7 opened this issue Feb 19, 2025 · 5 comments
Open

Comments

@flysand7
Copy link
Contributor

Context

The vector triple product can be given in terms of cross-product:

triple(a,b,c) := a × b × c

In terms of the cross-product multiplication. In linear algebra, of course, the cross product can not be defined for 2-d vectors in a way that is sensible in terms of units or the rest of linear algebra (for example, if we assume the result is a constant, then what does it mean to cross-product a vector with a constant?).

I'm not good at that part of math and I'm not going to pretend that I am, however as I see it, it is possible to generalize the triple product via the property that a × b × c = (a . c)b - (a . b)c. For two-dimensional vectors the dot-product, scalar multiplication and subtraction are all well-defined operations, so it is a no-problem for generalizing triple product that way for 2-dimensional vectors.

One practical application came up when I was working on a GJK implementation for 2-dimensional polygons. There is a point where you want to obtain a vector v that is perpendicular to a in the direction of the vector b. This is where a 2-dimensional vector triple product came up. I derived a formula for it by adjoining 0 as the third dimension for both vectors and running through the algebra. I later was surprised when I saw that linalg already had a formula for triple product that took in a generic parameter. I then was disappointed when I realised the code doesn't compile for 2-dimensional vectors.

Suggested implementation

I want to suggest special-casing the vector triple product for 2-dimensional cases.

 @(require_results)
 vector_triple_product :: proc "contextless" (a, b, c: $T/[$N]$E) -> T where IS_NUMERIC(E) {
 	// a x (b x c)
 	// (a . c)b - (a . b)c
-	return cross(a, cross(b, c))
+       when E == 2 {
+		v := a.x*b.y - a.y*b.x
+		return { -v*c.y, v*c.x }
+	} else {
+		return cross(a, cross(b, c))
+	}
 }

This should be equivalent to the dot-product formula.

@gingerBill
Copy link
Member

I am not sure if I should allow it since it doesn't really make much sense in 2D. It's not really a triple cross product but a something else entirely.

@JesseRMeyer
Copy link

While the formal definition restricts to 3 3D vectors, I'll note that Rust's math implementation specializes for the 2D case too. https://docs.rs/maths-rs/latest/maths_rs/fn.vector_triple.html

@flysand7
Copy link
Contributor Author

While the formal definition restricts to 3 3D vectors, I'll note that Rust's math implementation specializes for the 2D case too. https://docs.rs/maths-rs/latest/maths_rs/fn.vector_triple.html

The formal definition via the cross product restricts it to vectors in R^n where n>=3. That is an important point, because it's common that in mathematics there are multiple ways to define a concept which influence how applicable it is to different applications.

An example of that is the exponentiation, e^x. It's possible to define it for natural numbers x, where it's just e multiplied by itself x times. For real numbers you can also take the limit (1+x)^(1/x) as x approaches infinity. You can also take the taylor expansion, and say that that formula is the definition, which makes exponentiation applicable to matrices.

For a triple product the dot-product difference (a . c)b - (a . b)c can be used as the definition of a triple product, with most of the properties being the same for 2D vectors, except for the fact that you can't really use a cross product. I guess you can also define the tripple product in terms of the outer product, but that isn't really implementable in Code.

So, mathematically speaking there should be no problem, specialising to R^2.

doesn't really make much sense in 2D

But it is useable sometimes!

@flysand7
Copy link
Contributor Author

flysand7 commented Feb 21, 2025

But one thing I can note though is that I couldn't find anyone talking about it, at least by searching google. There are generalisations for these concepts via the exterior algebra and geometric algebra (which neither of I have studied), but no one seems to be talking about vector triple product for 2d vectors specifically. There are some bits and pieces suggesting the "cross product" of 2-dimensional vectors is a scalar (which is equally dubious, since in that definition, it cannot obey some of the cross product properties).

I've seen a definition of a cross product for 2-dimensional vectors being called "perp-dot product" (a × b) = a_perp . b, or pseudo cross product (C. Ericson, Real-time collision detection, chapter 3). You can make the same argument that it is not the same as a cross product, because it outputs a scalar, not a vector and therefore.. doesn't belong in linalg?

@JesseRMeyer
Copy link

JesseRMeyer commented Feb 21, 2025

I was really just quoting Wikipedia here per the definition of three 3 dimensional vectors: https://en.wikipedia.org/wiki/Triple_product

I agree that the dot product formulation opens it up to more (preferable) generality.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants