Hi Everyone, I’ve been learning GA using enkimute’s Ganja coffeeshop. I have a 2D CGA problem where the wedge of three points does not line up with the points and I wonder what is different.
With three explicit points, this works as expected. However, when one of the points is the projection of a point on a circle, then the resulting circle does not coincide with the projected point.
I wonder if this is because the projection is a point pair? I have used split() to get the correct point.
Any advice is much appreciated.
Instructions: Drag p1
and observe that circle edge
does not line up with s1
.
// Create a Clifford Algebra with 3,1 metric for 2D CGA.
Algebra(3,1,()=>{
// The conformal model adds in more element types. (circles, point-pairs)
// We no longer work in a dual space. (so ^ = join and & = meet)
// Vectors are points, Bivectors are point pairs, Trivectors are lines/circles
// We don't work directly in the e3/e4 basis, but instead rotate it so we have
// two null vectors to work with (called origin and infinite)
var ni = 1e4+1e3, // n-infinite
no = .5e4-.5e3; // n-origin
// Define points, lines, circles using the null basis.
var point = (x,y)=>no + x*1e1 + y*1e2 + 0.5*(x*x+y*y)*ni,
line = (a,b,c)=>!(a*1e1 + b*1e2 + c*ni),
circle = (x,y,r)=>!(point(x,y) - r**2/2*ni);
// Distances and Angles.
var dist=(x,y)=>(2*(x<<y).Length)**0.5,
angle=(x,y)=>Math.acos(!x.Normalized<<!y.Normalized);
// Rotator, Translator
var translate = (v)=>(1-.5*v^ni),
rotate = (P,a)=>Math.cos(a/2) - Math.sin(a/2)*(1e12-P<<1e12^ni);
// Some identities
var line_through_P_parallel_with_X = (P,X)=>(P^ni)<<X*(P^ni),
project_point_on_circle = (P,C)=>(P^ni)<<C*C,
project_point_on_line = (P,L)=>P<<L.Normalized*L.Normalized,
position = (X)=>{ X=X/(X^ni); return X/(X<<-ni); },
radius = (X)=>Math.abs(((X<<X).s/((X^ni)**2).s))**.5,
attitude = (X)=>(ni^no<<(X^ni)).Normalized,
split = (pp)=>position(pp)-radius(pp)*attitude(pp);
// FIXME?
var split_point_pair = (pp) => {
return split(pp)
}
var p1 = point(0, 1.2, 0)
var p2 = () => rotate(0, 2*Math.PI/3)>>>p1
var p3 = () => rotate(0, 2*Math.PI/3)>>>p2
var p4 = () => rotate(0, 2*Math.PI/6)>>>p1
var p5 = () => rotate(0, 2*Math.PI/3)>>>p4
var p6 = () => rotate(0, 2*Math.PI/3)>>>p5
var R = () => p1^p2^p3
var petal = (p) => !(p - 0.4**2/2*ni);
var P1 = () => petal(p1)
var P2 = () => petal(p2)
var P3 = () => petal(p3)
var P4 = () => petal(p4)
var P5 = () => petal(p5)
var P6 = () => petal(p6)
var origin = point(0, 0, 0)
var X14 = () => split_point_pair(P1 & P4);
var s1 = () => split_point_pair(project_point_on_circle(origin, P4)) // X14 + (X14 ^ ni).Normalized * 0.1
console.log("p2", p2())
console.log("s1", s1())
// FIXME: circle doesn't like s1
var e1 = () => p1 ^ p2 ^ (position(s1));
// Graph these items.
document.body.appendChild(this.graph([
"2D CGA - drag p1","", // title // circles
0x44AA44, // lines
0x4444FF, p2, "p2", p3, "p3", // points
0x6633FF, p4, "p4", p5, "p5", p6, "p6",
0xFF8888, R, "R", P1, "P1", P2, "P2", P3, "P3",
0xBB88BB, P4, "P4", P5, "P5", P6, "P6",
0x44AA44, // X14, "X14",
0x4444FF, s1, "s1",
e1, "edge", origin, "O",
0x33FF55, p1, "p1",
],{conformal:true,grid:true})); // conformal flag!
});