biVector forum

Extracting Euclidean Points from Conformal Points

Using CGA2D as an example, it seems that extracting euclidean points from conformal points stored in the grade 2/bivectors isn’t all that straightforward.

If I intersect a line and circle I end up with the following CGA2D object (from the coffeeshop CGA2D example #1, translated into Python):

1 0.000
e1 0.000   e2 0.000   e3 0.000   e4 0.000
e12 -1.500  e13 2.595  e14 1.595  e23 -0.690 e24 1.310 e34 -3.000
e123 0.000 e124 0.000 e134 -0.000 e234 0.000
e1234 0.000

What is the most elegant way getting X, Y (and in CGA3D, Z) points that I can then feed into my CAD software?

I’m guessing that I need to find e1 and e2?

Kind Regards,
Joel

In CGA if you have a bivector of the form P=A\wedge B
Then you can extract the point A via:

A \propto \left[ -1 + \frac{P}{\sqrt{-P\tilde{P}}} \right] (P \cdot n_\infty)

and B by feeding in \tilde{P}.

If you look in section (4.1.1) of A Covariant Approach To Geometry Using Geometric Algebra (essential reference for CGA in general) you will find a bit of dicussion of why this works :slight_smile:. If you are using the Clifford library then you can use the built in function in the tools section.

To summarise, here is code to do the decomposition in python in 2D CGA:

from clifford.g2c import *
import numpy as np

def split_point_pair(P):
    denonimator = (np.sqrt(-(P*~P)[0]))
    A = (-1 + P/denonimator)*(P|einf) 
    # Note that B is equivalent to A but with ~P rather than P
    # as P is a bivector ~P == -P
    B = (1 + P/denonimator)*(P|einf) 
    return A, B

P = e12*-1.500  + e13*2.595 + e14*1.595  + e23*-0.690 + e24*1.310 + e34*-3.000

A, B = split_point_pair(P)

print((A^B).normal())
print(P.normal())

print()
print(A) 
print(B)

Remember that the points that come out are not normalised so you might want to post process them to make sure that A\cdot n_\infty == -1

Here is the equivalent in 3DCGA, along with the library function:

from clifford.g3c import *
from clifford.tools.g3c import point_pair_to_end_points, \
                        normalise_n_minus_1
import numpy as np

# We will try out the same function
def split_point_pair(P):
    denonimator = (np.sqrt(-(P*~P)[0]))
    A = (-1 + P/denonimator)*(P|einf)
    B = (1 + P/denonimator)*(P|einf)
    return A, B

# Translate the same point pair into 3DCGA
P = e12*-1.500  + e14*2.595 + e15*1.595  + e24*-0.690 + e25*1.310 + e45*-3.000

# This is the same as we had before
A, B = split_point_pair(P)
print(normalise_n_minus_1(A))
print(normalise_n_minus_1(B))

# Now use the one from the tools section
# The points come out pre-normalised this time
A2, B2 = point_pair_to_end_points(P)
print(A2)
print(B2)

Hope that is helpful,
Hugo

1 Like

Just spotted you are also keen to get the X, Y, Z values of the points too, not just the conformal points. To do this just call `down’ on the points and pull out the corresponding coefficients. Eg. in 3DCGA:

from clifford.g3c import *

a = 3.14*e1 + 4*e2 - 7.5*e3

A = up(a)
adown = down(A)

print(adown[e1])
print(adown[e2])
print(adown[e3])
1 Like