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]:
[ ]: