My Haskell PGA 2D library, help?

So, I’ve implemented a GA library, and a 2,0,1 PGA library, but i’ve got some oddities in the way it’s built (it works, I swear, there’s a test suite!), and one real oddity in the math.

standard disclaimer: I am no mathematician, and probably not a very good haskell developer. :slight_smile:


so, to start with, i’ll go with the “oddity”. from time to time, I got paticularly desperate working on some of my implementations while i worked out my form of inner and outer product (see like, unlike, and reductive operators). specifically, I am writing a slicer, and i needed a way to tell whether a line, when compared to a second line, pointed to the left side of the second line, or the right side. I found a value that fit my goal, returning +cos when the line pointed to the left, and -cos when pointing to the right. you can find it on line 87 of PGA.hs (the ‘dualAngle’ function)

specifically, when i take two lines, and multiply their unlike components (think wedge without eliminating the e0e0s), i have a value:

e0e0e1e2

that is useful for the task. is there a similarly useful product elsewhere in PGA 2,0,1 for this task?

So I took this apart and figured out what it’s doing.

The unlike operator takes two multivectors and returns the sum of the product of element pairs with non-matching basis vectors. For example, it would take x^e0+y^e1 and z^e2+w^e1 and return xz^e02+xw^e01+yz^e12 (yw gets discarded because of the matching basis vector e1).

In this case, it’s being fed a pair of duals of projective lines. The lines themselves are of the form a^e1+b^e2+c^e0 corresponding to the line ax+by+c=0. The dual of such a line is the projective point a^e02+b^e01+c^e12. So we perform unlike(dual(L1),dual(L2)) and pick out the resulting element with the basis vector e0e0e1e2.

Working this out on paper this is equivalent to the scalar product a1*b2-b2*a1 where a1, a2 and b1,b2 are the e1 and e2 components of the original two lines. In other words, ignore the y-intercept of the lines and look at the relation between their slopes. This will cause issues with lines where the e1 and e2 components are equal or opposite, such as lines with +45 and -45 degree slope where e1=e2 or e1=-e2. The normalized slope is related to the cosine of the angle. This can be calculated more efficiently without the strange unlike operator and without the dual by just calculating a1*b2-b1*a2 directly.

What I propose instead is to take the normalized intersection point P of the two lines, translate it along the perpendicular of one line with P'=m*P*~m where m=1+L1*e012 and then look at L2^P'. The result will be a pseudoscalar with a signed magnitude. The sign will tell you which side of the line the other line points.