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 . 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