3DPGA: Distances and AnglesΒΆ

[1]:
from kingdon import Algebra
import math

alg = Algebra(3, 0, 1)
[2]:
point = lambda x, y, z: alg.vector(e0=1, e1=x, e2=y, e3=z).dual()
plane = lambda a, b, c, d: alg.vector(e1=a, e2=b, e3=c, e0=d)

Useful distances formulea:

[3]:
def dist_pp(P1, P2) -> float:  # point to point
    return (P1.normalized() & P2.normalized()).norm().e

def dist_pP(P, p) -> float:  # point to plane
    return (P.normalized() & p.normalized()).norm().e

def dist_ll(l1,l2) -> float:  # line to line
    return (l1.normalized() * l2.normalized()).dual().norm().e

Useful angle formulea; notice that they are identical:

[4]:
def angle_pp(p1,p2):  # Angle between planes
    return math.acos((p1.normalized() | p2.normalized()).e) * 180 / math.pi

def angle_ll(l1,l2):  # Angle between lines
    return math.acos((l1.normalized() | l2.normalized()).e) * 180 / math.pi
[ ]:

[5]:
# Create 5 points.
A = point(0,.8,0)
B = point(.8,-1,-.8)
C = point(-.8,-1,-.8)
D = point(.8,-1,.8)
E = point(-.8,-1,.8)

# Our ground plane
a = B & C & D

# Our camera position and orientation.
camera = alg.evenmv(e=1, e13=1).normalized()
[6]:
from timeit import default_timer

def graph_func():
    time = default_timer() / 5
    A = point(0, math.sin(time*4), 0)
    # camera = (math.cos(time) + math.sin(time)*alg.blades.e13)                     # rotate around Y
    return [
        0xD0FFE1,[A,B,C],                                            # graph on face
        0x00AA88,[A,B],[A,C],[A,D],[B,C],[B,D],[C,E],[A,E],[E,D],    # graph all edges
        0x444444,A,"A",B,"B",C,"C",D,"D",E,"E",                      # graph all vertices
        0xFF8844,[A,E], f"{dist_pp(A,E):.2f}",                      # distance A to E
        0x224488,[A,B+E], f"{dist_pP(A,a):.2f}",                    # distance A to a
        0x44aa44,C+E, f"{dist_ll(C&E,D&B):.2f}",                    # distance CE to DB
        0x44aaff,[A+D+E,B+C+5*D+5*E,D+E], f"{angle_pp(A&E&D, a):.2f}"+"°",   # angle planes.
        0x884488,[A,2*A+D,2*A+B],f"{angle_ll(A&D, B&A):.2f}"+"°"
    ]

alg.graph(
    graph_func,
    animate=True, grid=True, labels=True, lineWidth=3,
    # camera=camera,
)
[6]:
[ ]: