Skip to content

Commit

Permalink
added 3d graphing, updated graph api, updated all samples, added more…
Browse files Browse the repository at this point in the history
… 3D samples.
  • Loading branch information
enkimute committed Sep 13, 2017
1 parent 964e415 commit bd51374
Show file tree
Hide file tree
Showing 13 changed files with 147 additions and 69 deletions.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -234,8 +234,14 @@ Mandelbrot with Quaternion Hue colorisation<BR>
Quaternion color rotations<BR>
<A HREF="https://enkimute.github.io/ganja.js/examples/coffeeshop.html#quaternion_hue" TARGET="_blank" TITLE="Quaternion Hue Rotations"><IMG SRC="images/quaternion_hue.jpg"/></A>
<TD ALIGN=CENTER>
PGA3D Points and Lines<BR>
<A HREF="https://enkimute.github.io/ganja.js/examples/coffeeshop.html#pga3d_points_and_lines" TARGET="_blank" TITLE="PGA3D Points and Lines"><IMG SRC="images/pga3d_points_and_lines.jpg"/></A>
<TR><TD ALIGN=CENTER>
PGA3D Distances and Angles<BR>
<A HREF="https://enkimute.github.io/ganja.js/examples/coffeeshop.html#pga3d_distances_and_angles" TARGET="_blank" TITLE="PGA3D Distances and Angles"><IMG SRC="images/pga3d_distances_and_angles.jpg"/></A>
<TD ALIGN=CENTER>
PGA2D Distances and Angles<BR>
<A HREF="https://enkimute.github.io/ganja.js/examples/coffeeshop.html#pga3d_rotors_and_translators" TARGET="_blank" TITLE="PGA3D Rotors and Translators"><IMG SRC="images/pga3d_rotors_and_translators.jpg"/></A>
<TR><TD ALIGN=CENTER>
PGA2D Points and Lines<BR>
<A HREF="https://enkimute.github.io/ganja.js/examples/coffeeshop.html#pga2d_points_and_lines" TARGET="_blank" TITLE="PGA2D Points and Lines"><IMG SRC="images/pga2d_points_and_lines.jpg"/></A>
Expand Down
5 changes: 3 additions & 2 deletions examples/coffeeshop.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<HEAD>
<link href="https://fonts.googleapis.com/css?family=Encode+Sans+Condensed" rel="stylesheet">
<STYLE>
body { margin: 0; background-color:#EEE; position:relative; display:flex; flex-direction:column; font-family:-apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; }
body { margin: 0; background-color:#EEE; position:relative; display:flex; flex-direction:column; font-family: 'Encode Sans Condensed', sans-serif; }
#SAMPLE { width:33%; min-width: 512px; border: 0; min-height:80% }
#SOURCE { margin:0; flex-grow:1; }
#HEADER { position:relative; display:flex; flex-flow:wrap; z-index:10 }
Expand Down Expand Up @@ -58,7 +59,7 @@ <H3>The Coffeeshop<BR>
<PRE ID="SOURCE"></PRE>
</DIV>
<SCRIPT>
var examples = ["complex_mandelbrot","quaternion_hue","quaternion_mandelbrot","pga2d_points_and_lines","pga2d_distances_and_angles","pga2d_project_and_reject","pga2d_rotors_and_translators","pga2d_isometries", "pga2d_inverse_kinematics","pga2d_separating_axis","pga2d_pose_estimation","pga2d_euler_line","pga2d_desargues_theorem","pga3d_points_and_lines","pga3d_distances_and_angles","game_wedge"]
var examples = ["complex_mandelbrot","quaternion_hue","quaternion_mandelbrot","pga2d_points_and_lines","pga2d_distances_and_angles","pga2d_project_and_reject","pga2d_rotors_and_translators","pga2d_isometries", "pga2d_inverse_kinematics","pga2d_separating_axis","pga2d_pose_estimation","pga2d_euler_line","pga2d_desargues_theorem","pga3d_points_and_lines","pga3d_distances_and_angles","pga3d_rotors_and_translators","game_wedge"]

var $ = document.getElementById.bind(document);

Expand Down
3 changes: 1 addition & 2 deletions examples/example_pga2d_distances_and_angles.html
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@
0xff4444, AB, AtoB, BC, BtoC, CA, CtoA, // render edges and lengths.
0x444444, A, CAtoAB, B, ABtoBC, C, CAtoBC, // render verts and angles
0x8888ff, [B,()=>(B<<CA)*CA], BtoCA,
this.graph // tell it to animate ..
]));
],{animate:true}));
})();
</SCRIPT></BODY>
4 changes: 2 additions & 2 deletions examples/example_pga2d_pose_estimation.html
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
if (s>=2) res = res.concat([0x8888ff,CBA,CBB,CBC]);
if (s>=3) res = res.concat([0x0000ff,CBA^CAA,CBB^CAB,CBC^CAC]);
if (s>=4) res = res.concat([[CBA^CAA,CBB^CAB],[CBA^CAA,CBC^CAC]])
return res.concat(this.graph);
}));
return res;
},{animate:true}));
})();
</SCRIPT></BODY>
3 changes: 1 addition & 2 deletions examples/example_pga2d_rotors_and_translators.html
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
// Graph it
document.body.appendChild(this.graph([
"Versors", ()=>[tr>>>A,rt>>>B], ()=>tr>>>A, "tr>>>A", ()=>rt>>>B, "rt>>>B",
this.graph
]));
],{animate:true}));
})();
</SCRIPT></BODY>
2 changes: 1 addition & 1 deletion examples/example_pga2d_separating_axis.html
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,6 @@
document.body.appendChild(this.graph(()=>{
pa[4] = -0.2+(0.3-(performance.now()*0.0001%2));
var a=ngon(pa,3,0.65,pa.e01*10), b=ngon(pb,6,0.5), h=sat(b,a);
return [0xcccccc,h,h?0x88ff88:0xffaaaa,a,b,0x444444,pa,pb,this.graph]}));
return [0xcccccc,h,h?0x88ff88:0xffaaaa,a,b,0x444444,pa,pb]},{animate:true}));
})();
</SCRIPT></BODY>
70 changes: 44 additions & 26 deletions examples/example_pga3d_distances_and_angles.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,32 +3,50 @@
</HEAD>
<BODY><SCRIPT>
// Create a Clifford Algebra with 3,0,1 metric.
var d3 = Algebra(3,0,1);

// Ganja.js only supoprts native 2D graphing. So we use a projective 2D algebra and implement a camera projection that rotates around the y axis :
var d2 = Algebra(2,0,1),
project = d2.inline(P=>(P instanceof Array)?P.map(project):(P instanceof d3)?P.e01*-1e0+(P.e13)*1e1+(P.e12)*1e2+P.e012*1e02+P.e013*1e01+P.e123*1e12:P),
view = d3.inline(P=>(P instanceof Array)?P.map(view):(P instanceof d3)?((1e123+5e023)&P)^(1e1-2e0):P),
model = d3.inline(P=>(P instanceof Function)?model(P()):(P instanceof Array)?P.map(model):(P instanceof d3)?((Math.cos(performance.now()/2000)+Math.sin(performance.now()/2000)*(1e13))>>>P):P),
graph = (x)=>d2.graph(()=>[d2.graph].concat(x.map(x=>(x instanceof Function)?y=>project(view(model(x()))):project(view(model(x))))));

// Now we display some 3D points, lines and polygons.
d3.inline(()=>{

// Helper to create points.
var point = (x,y,z)=>1e123-x*1e012+y*1e013+z*1e023;
var AngleLines = (PI,EP)=>Math.acos((PI.Normalized<<EP.Normalized).Length)*180/Math.PI;
Algebra(3,0,1).inline(()=>{

// Create 5 points and some joining lines.
var A=()=>point(0,Math.sin(performance.now()/1000),0), B=point(1,1,-1), C=point(-1,1,-1), D=point(1,1,1), E=point(-1,1,1);

// Graph the 3D items
document.body.appendChild(graph(["3D PGA",
0xddaaff,()=>[A,B,C],
0xAA88FF,()=>[A,B],()=>[A,C],()=>[A,D],()=>[A,E],[B,C],[B,D],[C,E],[E,D],
0x444444,A,"A",B,"B",C,"C",D,"D",E,"E",
0x888888,B+E,[A,B+E],()=>(A&(B+E).Normalized).Length.toFixed(2),
0xFF6666,[A,B],[B,B+E],()=>[A+2*B,E+5*B],()=>(AngleLines((A&B),(B&(B+E))).toFixed(2))+"&deg;"
]));
// Specify a point directly (trivectors specified with overloaded e-notation.)
var point = (x,y,z)=>1e123-x*1e012+y*1e013+z*1e023;

// Lines can be defined using plucker coordinates
var line = (px,py,pz,dx,dy,dz)=>px*1e01+py&1e02+pz*1e03+dx*1e12+dy*1e13+dz*1e23;

// Planes can be defined directly using e0,e1,e2,e3
var plane = (a,b,c,d)=>d*1e0+a*1e1+b*1e2+c*1e3;

// Useful distances
var dist_pp = (P1,P2)=>(P1.Normalized&P2.Normalized).Length, // point to point
dist_pP = (P,p)=>(P.Normalized&p.Normalized).Length, // point to plane
dist_ll = (l1,l2)=>(!(l1.Normalized*l2.Normalized)).Length; // line to line

// Useful angles
var angle_pp = (p1,p2)=>Math.acos(p1.Normalized<<p2.Normalized)*180/Math.PI, // Angle between planes
angle_ll = (l1,l2)=>Math.acos(l1.Normalized<<l2.Normalized)*180/Math.PI; // Angle between lines

// Create 5 points.
var A=point(0,-1,0), B=point(1,1,-1), C=point(-1,1,-1), D=point(1,1,1), E=point(-1,1,1),

// Our ground plane
a=B&C&D,

// Our camera position and orientation
camera=0e0;

// Graph the 3D items
document.body.appendChild(this.graph(()=>{
var time=performance.now()/4000;
A=point(0,Math.sin(time*4),0);
camera.set(Math.cos(time)+Math.sin(time)*1e13); // rotate around Y
return [0xddaaff,[A,B,C], // graph on face
0xAA88FF,[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
0xFF8888,[A,E],dist_pp(A,E).toFixed(2), // distance A to E
0x8888FF,[A,B+E],dist_pP(A,a).toFixed(2), // distance A to a
0x44aa44,C+E,dist_ll(C&E,D&B).toFixed(2), // distance CE to DB
0x44aaff,[A+D+E,B+C+5*D+5*E,D+E],(angle_pp(A&E&D,a).toFixed(2))+"°", // angle planes.
0xff44ff,[A,2*A+D,2*A+B],(angle_ll(A&D,B&A).toFixed(2))+"°"
];
},{animate:true,camera}));

})();
</SCRIPT></BODY>
64 changes: 38 additions & 26 deletions examples/example_pga3d_points_and_lines.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,37 +3,49 @@
</HEAD>
<BODY><SCRIPT>
// Create a Clifford Algebra with 3,0,1 metric.
var d3 = Algebra(3,0,1);
Algebra(3,0,1).inline(()=>{

// We work in dual space. Our 1-blade's are dual-vectors (aka functionals of the form ax + by + cz + dw = 0).
// The four basis functionals are thus (x=0, y=0, z=0, w=0). In three dimensions these represent the yz, xz, xy and
// ideal plane.

// Specify a point directly (trivectors specified with overloaded e-notation.)
var point = (x,y,z)=>1e123-x*1e012+y*1e013+z*1e023;

// Lines can be defined using plucker coordinates
var line = (px,py,pz,dx,dy,dz)=>px*1e01+py&1e02+pz*1e03+dx*1e12+dy*1e13+dz*1e23;

// Ganja.js only supoprts native 2D graphing. So we use a projective 2D algebra and implement a camera projection that rotates around the y axis :
var d2 = Algebra(2,0,1),
project = d2.inline(P=>(P instanceof Array)?P.map(project):(P instanceof d3)?P.e01*-1e0+(P.e13)*1e1+(P.e12)*1e2+P.e012*1e02+P.e013*1e01+P.e123*1e12:P),
view = d3.inline(P=>(P instanceof Array)?P.map(view):(P instanceof d3)?((1e123+5e023)&P)^(1e1-2e0):P),
model = d3.inline(P=>(P instanceof Array)?P.map(model):(P instanceof d3)?((Math.cos(performance.now()/2000)+Math.sin(performance.now()/2000)*(1e13))>>>P):P),
graph = (x)=>d2.graph(()=>[d2.graph].concat(x.map(x=>(x instanceof Function)?y=>project(view(model(x()))):project(view(model(x))))));
// Planes can be defined directly using e0,e1,e2,e3
var plane = (a,b,c,d)=>d*1e0+a*1e1+b*1e2+c*1e3;

// Now we display some 3D points, lines and polygons.
d3.inline(()=>{
// Helper to create points.
var point = (x,y,z)=>1e123-x*1e012+y*1e013+z*1e023;
// Useful joins
var line_from_points = (P1,P2)=>P1.Normalized&P2.Normalized,
plane_from_points = (P1,P2,P3)=>P1&P2&P3,
plane_from_point_and_line = (P,L)=>P&L;

// Usefull meets
var line_from_planes = (p1,p2)=>p1^p2,
point_from_planes = (p1,p2,p3)=>p1^p2^p3,
point_from_line_and_plane = (L,P)=>L^P;

// Create 5 points and some joining lines.
var A=point(0,-1,0), B=point(1,1,-1), C=point(-1,1,-1), D=point(1,1,1), E=point(-1,1,1),
ab=A&B, bc=B&C, ca=C&A, ad=A&D, bd=B&D, cd=C&D;

// An animated plane.
var plane = ()=>Math.sin(performance.now()/1000)*1e0 + 1e2;
var A=point(0,-1,0), B=point(1,1,-1), C=point(-1,1,-1), D=point(1,1,1), E=point(-1,1,1),
centroid=A+B+C+D+E,
camera=0e0;

// Graph the 3D items
document.body.appendChild(graph(["3D PGA",
0xddaaff,ab,bc,ca,ad,bd,cd,[A,B,C], // graph some lines and one face of the pyramid
0xAA88FF,[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
0x884444,A<<(B&C&E),"A.(B&C&E)", // line throu a and the floor plane of the pyramid
0x448844,A+B+C+D+E,"G=A+B+C+D+E", // G = center of gravity
0x444488,(A+B+C+D+E)<<(A&B&C),"h=G.(A&B&C)", // line between CoG and ABC plane
0x4444ff,((A+B+C+D+E)<<(A&B&C))^(A&B&C),"I=h^(A&B&C)", // projection CoG onto ABC plane
0xaaaaff,()=>[A&B,A&C,A&E,A&D].map(x=>x^plane) // wedge with the plane
]));
document.body.appendChild(this.graph(()=>{
var time=performance.now()/4000;
camera.set(Math.cos(time)+Math.sin(time)*1e13); // rotate around Y
return [0xddaaff,[A,B,C], // graph on face
0xAA88FF,[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
0xFF8888,C+E,centroid,"sum of points",
0x8888FF,line_from_points(centroid,C+E),"line from points ..",
0x44AA44,line_from_planes(A&B&C,B&C&D),"line from planes ..",
0x4488FF,point_from_line_and_plane(line_from_points(centroid,C+E),A&D&B),"point from line and plane ..",
0xFFAA66,(B&D)+(C&E),"sum of lines"
];
},{animate:true,camera}));
})();
</SCRIPT></BODY>
43 changes: 43 additions & 0 deletions examples/example_pga3d_rotors_and_translators.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<HEAD>
<SCRIPT SRC="../ganja.js"></SCRIPT>
</HEAD>
<BODY><SCRIPT>
// Create a Clifford Algebra with 3,0,1 metric.
Algebra(3,0,1).inline(()=>{

// Specify a point directly (trivectors specified with overloaded e-notation.)
var point = (x,y,z)=>1e123-x*1e012+y*1e013+z*1e023;

// Lines can be defined using plucker coordinates
var line = (px,py,pz,dx,dy,dz)=>px*1e01+py&1e02+pz*1e03+dx*1e12+dy*1e13+dz*1e23;

// Planes can be defined directly using e0,e1,e2,e3
var plane = (a,b,c,d)=>d*1e0+a*1e1+b*1e2+c*1e3;

// Rotations can be specified through exponentiation (angle around line).
var rotor = (line,angle)=>Math.cos(angle/2) + Math.sin(angle/2)*line.Normalized;

// Translations can similarly be expressed through exponentiation.
var translator = (line,distance)=>1+0.5*distance*(line.Normalized*1e0123);

// Create 5 points.
var A=point(0,0,0), B=point(0,1,1), C=point(0,1,0), D=point(1,1,1), E=point(-1,1,1),

// Our ground plane
a=B&C&D,

// Our camera position and orientation
camera=0e0;

// Graph the 3D items
document.body.appendChild(this.graph(()=>{
var time=performance.now()/4000;
var D=rotor(A&B,time*10)>>>C;
camera.set(rotor(1e13,time)); // rotate around Y
return [A,"A",B,"B",A&B,E,
0xFF8888,[A,B,E],
0x444444,[A+0.9*B,(A+0.8*B)+2*D,A+D,D,D+B,2*D+(B+0.8*A),B+0.9*A].map(x=>translator(A&B,Math.sin(time*5))>>>x),
];
},{animate:true,camera}));
})();
</SCRIPT></BODY>
Loading

0 comments on commit bd51374

Please sign in to comment.