### Full Dynamics Simulation Setup (Alternative)
Source: https://github.com/enkimute/ganja.js/blob/master/examples/pga_dyn.html
An alternative setup for a 4D geometric algebra simulation, defining vertices, forces, and the state derivative for rendering.
```javascript
// Set the number of dimensions.
window.d = 4;
// Create a d-dimensional geometric algebra over the reals.
Algebra(d, 0, 1, ()=>{
// Create a hypercube (square in 2D, cube in 3D, ...)
// Start by defining its vertices.
var p = [...Array(2**d)]
.map((x,i)=>i.toString(2)) // [0, 1, 10, 11, 100, ...]
.map(x=>('00000'+x).slice(-d)) // [000, 001, 010, 011, ...]
.map(x=>x.split('').map(x=>x-0.5)) // [[-0.5, -0.5, -0.5], [-0.5, -0.5, 0.5], ...]
.map(x=>!(1e0 + x*[1e1,1e2,1e3,1e4])); // PGA points are dual vectors.
// Now consider all vertex pairs and create edges for those
// pairs that differ only in one coordinate.
var e = p.map((a,i)=>p.map((b,j)=> i<=j||(i^j)&(i^j-1)?0:[a,b] // note that &,^ here are bitwise ops since i,j are integer
)).flat().filter(x=>x);
// Physics state.
var state = [1, 1e12 + 1.3e13 + 0.5e24];
// Our forques
var attach = (1-0.5e02) * p[2**d-1];
var F = (M,B)=>{
var Gravity = !(~M >>> -9.81e02);
var Hooke = 12*((~M >>> attach) & p[2**d-1]);
var Damping = !(-0.25 * B);
return (Gravity + Hooke + Damping);
}
// The derivative of the state.
var dS = ([M,B])=>[ -0.5*M*B, (F(M,B) - 0.5*(B.Dual*B-B*B.Dual)).UnDual ];
// Render
return this.graph(()=>{
// Update the state
for (var i=0; i<10; ++i)
state = state + 1/600 * dS(state);
return
```
--------------------------------
### Generate Example Cards
Source: https://github.com/enkimute/ganja.js/blob/master/examples/coffeeshop.html
Dynamically creates 'card' elements for displaying examples, setting background images, and handling click events to load samples.
```javascript
var excards = examples.map(e=>{
var card = Object.assign(document.createElement('div'),{className:'card'});
if (e) card.style.backgroundImage="url('../images/"+e+".jpg')";
card.innerHTML = '
'+e.split('_').slice(1).join(' ')+'
';
card.onclick = (x)=>{
els.sample.src='example_'+e+'.html';
document.location.hash = e;
els.title.innerText = "The CoffeeShop";
els.titleInput.value = els.descriptionInput.value = "";
els.urlInput.value = document.location;
els.save.classList.remove('active');
}
(document.querySelector('.group.'+e.split('_')[0])||els.left).appendChild(card);
return card;
});
```
--------------------------------
### Ganja.js Examples List
Source: https://github.com/enkimute/ganja.js/blob/master/examples/coffeeshop.html
A list of built-in examples available in Ganja.js.
```javascript
var examples = ["complex_mandelbrot","complex_least_squares", "dual_differentiation","dual_backpropagation", "quaternion_hue","quaternion_mandelbrot", "timespace_lorentz", "ga3d_rotor_estimation", "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","pga2d_differentiation","pga2d_physics_moon","pga2d_origami", "pga2d_poncelet", "pga2d_non_euclidean","pga2d_raytrace", "pga3d_points_and_lines","pga3d_distances_and_angles","pga3d_rotors_and_translators","pga3d_icosahedron","pga3d_sampling","pga3d_slicing","pga3d_differentiation","pga3d_skinning","pga3d_animation","pga3d_physics_planets","pga3d_origami","pga3d_physics_symmetric_top","pga3d_physics_free_top","pga3d_objects","pga3d_levenberg_marquardt","pga3d_motor_orbits", "chapter11_motor_reconstruction","chapter11_motors","chapter11_tricycle", "cga2d_points_and_circles","cga2d_project_and_reject","cga2d_rotors_and_translators","cga2d_euler_line","cga2d_circle_fit","cga2d_conformal","cga2d_conformal2", "cga3d_points_circles_lines","cga3d_points_spheres_planes","cga3d_dual_spheres_planes","cga3d_intersections","cga3d_project_reject","cga3d_opns_visualizer","cga3d_opns_line_circle","cga3d_json", "mga3d_points_and_lines", "ccga3d_points_quadrics", "csga2d_opns", "qcga3d_points_and_more", "c2dga_curves", "game_wedge"];
```
--------------------------------
### PGA3D Dual Quaternion Skinning Setup
Source: https://github.com/enkimute/ganja.js/blob/master/examples/example_pga3d_skinning.html
Initializes a Clifford Algebra with a 3,0,1 metric and defines helper functions for creating points, rotors, and motors. This setup is required for the subsequent skinning demonstration.
```javascript
Algebra(3,0,1,()=>{
// We demonstrate dual quaternion skinning in the PGA3D framework, and show
// how it resolves the candywrapping artefacts known from linear blend skinning.
// Specify a point directly (trivectors specified with overloaded e-notation.)
var point = (x,y,z)=>1e123-x*1e012+y*1e013+z*1e023;
var rotor = (P,a)=>Math.cos(a/2)+Math.sin(a/2)*P;
var motor = (d,V)=>(1+d*V);
// our point and edge lists
var sides=4, points=[], points_orig, items=['',0x224488];
// vertices and edges for a square rod.
for (var i=0;i<15;i++) for (var j=0;j>>point(-0.5,-1+i/7.5,0));
for (var i=0;i<15;i++) for (var j=0;jx.slice());
// Graph the 3D items
document.body.appendChild(this.graph(()=>{
var time=performance.now()/4000;
// two bones, one at the top, one at the bottom
var b1 = rotor(-1e13,Math.PI*.6*Math.sin(time*10)) * motor(Math.sin(time),.2e01);
var b2 = rotor(1e13,Math.PI*.6*Math.sin(time*10)) * motor(Math.sin(time/2),.2e01);
// Transform all points.
for (var i in points) {
// Weights for both bones.
var w1 = (points[i].e013+1)/2, w2 = 1-w1;
// Alternate between DQS and LBS
if ((time%2)<1) {
items[0]='Dual Quaternion Skinning';
points[i].set((w1*b1+w2*b2).Normalized >>> points_orig[i]);
} else {
items[0]='Linear Blend Skinning';
points[i].set(w1*(b1>>>points_orig[i]) + w2*(b2>>>points_orig[i]));
}
}
return items;
},{animate:true, lineWidth:3, grid:1, labels:1}));
});
```
--------------------------------
### Simulate Hypercube Kinematics (Alternative Rendering)
Source: https://github.com/enkimute/ganja.js/blob/master/examples/pga_dyn.html
An alternative setup for simulating hypercube kinematics, similar to the previous example but with a different color for rendering. It also uses a 4D space and defines vertices, edges, and the state update logic.
```javascript
// Set the number of dimensions.
window.d = 4;
// Create a d-dimensional geometric algebra over the reals.
Algebra(d, 0, 1, ()=>{
// Create a hypercube (square in 2D, cube in 3D, ...)
// Start by defining its vertices.
var p = [...Array(2**d)]
.map((x,i)=>i.toString(2)) // [0, 1, 10, 11, 100, ...]
.map(x=>('00000'+x).slice(-d)) // [000, 001, 010, 011, ...]
.map(x=>x.split('').map(x=>x-0.5)) // [[-0.5, -0.5, -0.5], [-0.5, -0.5, 0.5], ...]
.map(x=>!(1e0 + x*[1e1,1e2,1e3,1e4])); // PGA points are dual vectors.
// Now consider all vertex pairs and create edges for those
// pairs that differ only in one coordinate.
var e = p.map((a,i)=>p.map((b,j)=> i<=j||(i^j)&(i^j-1)?0:[a,b] // note that &,^ here are bitwise ops since i,j are integer )).flat();
// Physics state.
var state = [Math.E**( .1e12), 1e12 + 1.3e13 + 0.5e24];
// The derivative of the state.
var dS = ([M,B])=>[ -0.5*M*B, -0.5*(B.Dual*B - B*B.Dual).UnDual ];
// Render
return this.graph(()=>{
// Update the state
for (var i=0; i<10; ++i) state = state + 1/600 * dS(state);
return [ 0x007799, ...state[0] >>> e ];
},{lineWidth:6,animate:1,scale:1.75});
})
```
--------------------------------
### Conformal 3D Algebra (C3D) Setup
Source: https://github.com/enkimute/ganja.js/blob/master/examples/galculator.html
Initializes the Conformal 3D Geometric Algebra (C3D) space, setting the algebra mode and adjusting graph opacity.
```javascript
mode=6;E(0,1,1,1,1,1); Al=Algebra(4,1,0); graph.style.opacity=0.3; hist.style.visibility='visible';title.innerHTML="C3D - C(R4,1)";
```
--------------------------------
### Install Ganja.js via npm
Source: https://github.com/enkimute/ganja.js/blob/master/README.md
Install the ganja.js library using npm for use in Node.js projects.
```bash
npm install ganja.js
```
--------------------------------
### Projective 2D Geometric Algebra Example
Source: https://github.com/enkimute/ganja.js/blob/master/examples/galculator.html
This example demonstrates solving a system of linear equations using Projective 2D Geometric Algebra. It defines the equations and the steps to find the solution.
```javascript
help:'P(R*2,0,1): Projective 2D Geometric Algebra. (euclidian plane).Solve the system of equations : x+y-0.5=0 and 2x-y=0
'
```
--------------------------------
### SVG and Global Setup
Source: https://github.com/enkimute/ganja.js/blob/master/examples/example_game_wedge.html
Initializes the SVG canvas, title, footer, and intro elements. Sets up global variables for scoring and selection management.
```javascript
var a = (x,p)=>(p||$("main")).appendChild(x), g = function(){ var i,g=c('g'); for (i in arguments) a(arguments\[i\],g); return g}, say = (x)=>{if (window.speechSynthesis) window.speechSynthesis.speak(m(new SpeechSynthesisUtterance(x.replace(/\ /g,'\n').replace(/\<.\*?\>/g,'')),{lang:'en-US'}))}; // Main setup .. SVG renderer. a(c('svg',{viewBox:"-2 -2 4 4"},{id:"main"}),document.body); a(m(document.createElement('div'),{id:"title"}),document.body); a(m(document.createElement('a'),{id:"footer",href:"https://github.com/enkimute/ganja.js",target:"blank",innerText:"Fork me on github"}),document.body); a(m(document.createElement('div'),{id:"intro",onclick:function(){this.style.display='none'; nextLevel();}}),document.body); // Scoring var score=1000, moves=0, startTime=0, dt, scoreDiv = a(m(document.createElement('div'),{id:"score",innerHTML:"1000"}),document.body); setInterval(()=>{ if (!startTime || curlevel==levels.length) return; dt = performance.now()-startTime; score = 1000 - dt/1000 - moves*10; scoreDiv.innerHTML=score|0; },1000);
```
--------------------------------
### 2D PGA Example
Source: https://github.com/enkimute/ganja.js/blob/master/examples/gav.html
Demonstrates a 2D Planar Geometric Algebra (PGA) operation.
```javascript
e(x=>no+x+.5*x.Length*ni); // 2D PGA
```
--------------------------------
### 2D CGA Setup and Primitive Definitions
Source: https://github.com/enkimute/ganja.js/blob/master/examples/example_cga2d_points_and_circles.html
Initializes a 3,1 metric CGA algebra and defines functions for creating points, lines, and circles using the null basis. This setup is essential for all subsequent CGA operations.
```javascript
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<Math.acos(!x.Normalized<p1^p2^p3, // a function so it updates live.
D = circle(1,-1,0.9);
// Define two lines, one directly, one by wedging two points and infinity.
var X=line(0,1,0),
Y=()=>p2^p3^ni;
// Create point pairs by intersecting circle(s) and a line(s).
var pp1=()=>X&C,
pp2=()=>C&D,
pp3=()=>Y&D,
p4=()=>no|(X&Y);
// Graph these items.
document.body.appendChild(this.graph([
"2D CGA - drag p1,p2,p3", "", // title
0xFF8888, C, "C", D, "D", // circles
0x44AA44, X, "X", Y, "Y", p4, // lines
0x4444FF, pp1, "pp1", pp2, "pp2", pp3, "pp3", // point pairs
0x666666, p1, "p1", p2, "p2", p3, "p3", // points
],{conformal:true,grid:true})); // conformal flag!
});
```
--------------------------------
### 2D PGA Algebra Setup
Source: https://github.com/enkimute/ganja.js/blob/master/examples/example_pga2d_rotors_and_translators.html
Initializes a 2D PGA algebra and defines basic geometric elements like points and lines.
```javascript
Algebra(2,0,1,()=>{
// The geometric elements of 2D PGA (from ex. 1)
var point = (x,y)=>!(1e0 + x*1e1 + y*1e2), line = (a,b,c)=>a*1e1 + b*1e2 + c*1e0;
```
--------------------------------
### 3D CGA Algebra Setup and Object Definition
Source: https://github.com/enkimute/ganja.js/blob/master/examples/example_cga3d_project_reject.html
Sets up a 4,1 metric algebra for 3D CGA, defines null basis vectors, and provides utility functions for upcasting points, creating spheres, and planes. This is the foundational setup for most 3D CGA operations.
```javascript
Algebra(4,1,()=>{
// We start by defining a null basis, and upcasting for points
var ni = 1e4+1e5, no = .5e5-.5e4, nino = ni^no, up = (x)=>no+x+.5*x*x*ni, sphere = (P,r)=>!(P-r**2*.5*ni), plane = (v,h=0)=>!(v-h*ni);
// Project and reject.
var project_point_on_round = (point,sphere)=>-point^ni<up(-point<point^ni<project_point_on_round(p,S), "p on S", // point on sphere
0x000000FF, ()=>project_point_on_round(~p,C), "p on C", // point on circle
0x00888800, ()=>project_point_on_flat(p,P), "p on P", // point on plane
0x00008888, ()=>project_point_on_flat(~p,L), "p on L", // point on line
0xc0FF0000, ()=>plane_through_point_tangent_to_x(p,S), // plane through p tangent to S2
0xc000FF00, ()=>plane_through_point_tangent_to_x(p,P), // plane through p tangent to P
0,L,0,C, // line and circle
0xE0008800, P, // plane
0xE0FFFFFF, S // spheres
],{conformal:true,gl:true,grid:true}));
});
```
--------------------------------
### 3D CCGA Setup and Primitives
Source: https://github.com/enkimute/ganja.js/blob/master/examples/example_ccga3d_points_quadrics.html
Initializes a 6,3 metric for 3D CCGA, defines null basis vectors, and creates functions for generating points, ellipsoids, and planes. This setup is required for all subsequent CCGA operations.
```javascript
Algebra(6,3,()=>{
// https://link.springer.com/article/10.1007/s00006-014-0442-8
// Null Basis
var plus = [1e4,1e5,1e6], min = [1e7,1e8,1e9];
var [eix,eiy,eiz] = plus+min, [eox,eoy,eoz] = .5*(min-plus);
var ei = (eix+eiy+eiz)*(1/3), eo = eox+eoy+eoz, pss = 1e123456789;
// Some primitives
var pointv = [1e1,1e2,1e3,eix,eiy,eiz,eo], point = (x,y,z)=> [x,y,z,.5*x**2,.5*y**2,.5*z**2,1]*pointv,
ellipsoidv = [1e1,1e2,1e3,ei,eox,eoy,eoz], ellipsoid = (h,k,l,a,b,c)=> [h*a**-2,k*b**-2,l*c**-2,.5*(h**2*a**-2+k**2*b**-2+l**2*c**-2-1),a**-2,b**-2,c**-2]*ellipsoidv,
plane = (x,y,z,d)=>x*1e1+y*1e2+z*1e3+d*ei;
// for viz
var upviz = point(Element.Scalar("x"),Element.Scalar("y"),Element.Scalar("z")).Vector;
// Create an ellipsoid, plane and their intersection.
var E = ellipsoid(0,0,0,2,3,2), P = plane(0.9,0.3,0.0,0.0), e = (E^P).Normalized;
// Render
document.body.appendChild(this.graph([
0xff8800, pss*E,
0x0088ff, pss*e
],{up:upviz, spin:1, animate:true}));
});
```
--------------------------------
### Setup for Math Rendering and Algebra
Source: https://github.com/enkimute/ganja.js/blob/master/examples/example_chapter11_tricycle.html
Initializes the environment for rendering mathematical expressions and setting up a Clifford Algebra with a specific metric. This code is essential for the subsequent geometric algebra operations.
```javascript
// for latex labels..
var link = document.createElement('link');
link.href = "https://cdn.jsdelivr.net/npm/katex@0.10.0/dist/katex.min.css";
link.rel = "stylesheet";
document.head.appendChild(link);
var style = document.createElement('style');
style.innerHTML="div {z-index:-100; font-size:150%}";
document.head.appendChild(style);
self.renderMathInElement = top.renderMathInElement;
self.toTex = x=>x.toString().replace(/(\[\\d \\. \\]+)e/g,(a,b)=>(1*b).toFixed(2)+'e');
```
--------------------------------
### Conformal 2D Algebra (C2D) Setup
Source: https://github.com/enkimute/ganja.js/blob/master/examples/galculator.html
Initializes the Conformal 2D Geometric Algebra (C2D) space, setting the algebra mode and updating the display title.
```javascript
mode=5;E(0,1,1,1,1,0); Al=Algebra(3,1,0); graph.style.opacity=1; hist.style.visibility='visible';title.innerHTML="C2D - C(R3,1)";
```
--------------------------------
### 2D PGA Non-Euclidean Geometry Example
Source: https://github.com/enkimute/ganja.js/blob/master/examples/example_pga2d_non_euclidean.html
This example demonstrates creating and visualizing geometric elements in 2D PGA. It supports switching between Euclidean, Hyperbolic, and Elliptic metrics. The visualization includes points, lines, and their products, with animations.
```javascript
document.body.appendChild(Object.assign( document.createElement('DIV'), {innerHTML:
bind
bind` )).onchange = function() { regenerate(this.firstChild.value|0); }
function regenerate(sig=0) {
// Create our algebra so that e0 is always the projective dimension.
Algebra({ metric:[
bindsig
bind,1,1],
basis:['1','e0','e1','e2','e01','e02','e12','e012']
}).inline((animate=1)=>{
// Create a point.
var point = (x,y)=>(1e12-x*1e02+y*1e01).Normalized;
var p = point(.5,-.5); // hyperbolic disc
var {sin,cos,PI,E} = Math;
var disc = [...Array(100)].map((x,i)=>point(sin(i/50*PI),cos(i/50*PI))).map((x,i,a)=>[
bindx
bind,a[i+1]||a[0]
bind]);
// Remove old svg when metric changes.
var old = document.querySelector('svg');
if (old) document.body.removeChild(old);
// Create new svg.
var svg=document.body.appendChild(this.graph(()=>{
// Animated line
var l = (Math.sin(Date.now()/1000)*.5e1 + 1e1 + 1e2 -.5e0).Normalized;
// Render the basic line/point products.
return [
0xffffff, p, "P",
0xffffff, l, " ℓ ",
0xff0000,l*p,"ℓ.P = -P.ℓ ",
l*p*1e012,"ℓPI",
0xff8800,(l*p*l).Grade(2)," ℓPℓ",
0x00AA88,(p*l*p).Grade(1),"PℓP",
0x0088ff,((p|l)*p).Grade(1),"(P.ℓ)P",
0x00ffff,((l|p)*l).Grade(2),"(ℓ.P)ℓ",
0xffff00, ...(1e0*1e0==-1?disc:[])
];
},{animate:1,lineWidth:2,scale:1.2,fontSize:1.6}));
Object.assign(svg.style,{backgroundColor:'black',width:'100%',height:'100%'});
})();
};
regenerate();
```
--------------------------------
### Initialize Ganja.js Algebra
Source: https://github.com/enkimute/ganja.js/blob/master/examples/galculator.html
Initializes the Ganja.js algebra with specified metric. This is a minimal setup for the calculator.
```javascript
var Al = Algebra();
var mode=0, histor='', cur='', store=false, help=false,
x1, x2, x3, x4, x5, x6, x7, x8, x9, x10;
var graph=document.getElementById('graph');
graph.style.opacity=0.3;
var hist=document.getElementById('hist');
var title=document.getElementById('title');
```
--------------------------------
### PGA 2D (2,0,1) Example
Source: https://github.com/enkimute/ganja.js/blob/master/examples/galculator.html
Demonstrates a Minkowski spacetime calculation in 2D PGA. It involves defining events and calculating their simultaneity for a moving observer.
```javascript
buttons.x1 = {
color:'purple',
label : "x1",
click : ()=>{
if (store) {
store = false;
x1=Al.inline(new Function('return '+cur))();
patch('x1='+x1.toString());
return show(cur);
}
cur += 'x1';
show(cur);
},
help:"x1 variable"
};
buttons.x2 = {
color:'purple',
label : "x2",
click : ()=>{
if (store) {
store = false;
x2=Al.inline(new Function('return '+cur))();
patch('x2='+x2.toString());
return show(cur);
}
cur += 'x2';
show(cur);
},
help:"x2 variable"
};
buttons.x3 = {
color:'purple',
label : "x3",
click : ()=>{
if (store) {
store = false;
x3=Al.inline(new Function('return '+cur))();
patch('x3='+x3.toString());
return show(cur);
}
cur += 'x3';
show(cur);
},
help:"x3 variable"
};
buttons.x6 = {
color:'purple',
label : "x6",
click : ()=>{
if (store) {
store = false;
x6=Al.inline(new Function('return '+cur))();
patch('x6='+x6.toString());
return show(cur);
}
cur += 'x6';
show(cur);
},
help:"x6 variable"
};
buttons.x7 = {
color:'purple',
label : "x7",
click : ()=>{
if (store) {
store = false;
x7=Al.inline(new Function('return '+cur))();
patch('x7='+x7.toString());
return show(cur);
}
cur += 'x7';
show(cur);
},
help:"x7 variable"
};
buttons.x8 = {
color:'purple',
label : "x8",
click : ()=>{
if (store) {
store = false;
x8=Al.inline(new Function('return '+cur))();
patch('x8='+x8.toString());
return show(cur);
}
cur += 'x8';
show(cur);
},
help:"x8 variable"
};
// Add all the buttons and install mouse and touch handlers.
var j = 0, p;
for (var i in buttons) {
// Every 8 buttons, start a new group.
if (j % 8 == 0) p = document.getElementById("calcBody").appendChild(Object.assign(document.createElement('div'), { className: 'group' }));
// Add the button to the current group.
buttons[i].el = p.appendChild(Object.assign(document.createElement('div'), { className: "numButton noselect " + (buttons[i].color || ''), innerHTML: buttons[i].label }));
// Link the handlers (function(x){ buttons[i].el.ontouchend = function(e) { this.classList.remove('active'); }
buttons[i].el.ontouchstart = buttons[i].el.onmouseup = function (e) {
e.preventDefault();
e.stopPropagation();
// Show touch response and vibrate on mobile.
if (window.TouchEvent && e instanceof TouchEvent) this.classList.add('active');
navigator.vibrate && navigator.vibrate(50);
// Show help if needed.
if (help) {
help = false;
histor = '';
return print(buttons[x].help || 'no help for this button.');
}
// Call button click handler.
buttons[x].click();
}
)(i);
j++;
}
buttons.up.el.classList.add('disabled');
buttons.dwn.el.classList.add('disabled');
// Shorthand to enable/disable buttons depending on mode.
var e = function (x0, x1, x2, x3, x4, x5) {
['Conj', 'dual', 'rev', 'pss'].forEach(x => buttons[x].el.classList[(arguments.length == 0) ? 'add' : 'remove']('disabled'));
['ori', 'inf'/*,'up','dwn'*/].forEach(x => buttons[x].el.classList[(mode == 5 || mode == 6) ? 'rem
```
--------------------------------
### Generate and Compile for a Single Language and Algebra
Source: https://github.com/enkimute/ganja.js/blob/master/codegen/README.md
This command demonstrates how to generate and compile code for a specific language and algebra, for example, generating PGA3D for Rust.
```bash
make GEN_LANG="rust" pga3d
```
--------------------------------
### 2D PGA Algebra Setup and Element Definitions
Source: https://github.com/enkimute/ganja.js/blob/master/examples/example_pga2d_points_and_lines.html
Sets up a 2D PGA algebra and defines functions for creating lines (grade-1 elements) and points (grade-2 elements using dualization).
```javascript
Algebra(2,0,1,()=>{
// in 2D PGA, grade-1 elements or vectors (e0,e1,e2) represent
// reflections AND lines (the invariant of a reflection)
// Ganja.js overloads scientific notation to specify basis blades.
var line = (a,b,c)=>a*1e1 + b*1e2 + c*1e0;
// grade-2 elements or bivectors (e01,e02,e12) represent
// rotations/translations AND points/infinite points (the invariant
// of a rotation/translation). We define them using the dualisation
// operator (!) to be independent of choice of basis (e12 vs e21)
var point = (x,y)=>!(1e0 + x*1e1 + y*1e2);
// Define 3 points in the plane.
var A = point(-1, -1), B = point(-1, 1), C = point(1, 1);
// Define the line y = 0.5 - x <=> x + y - 0.5 = 0
var L = line(1, 1, -0.5)
// A line can also be defined by JOINING (&) two points.
// We define M as a function '()=>' so it will update when C or A
// are dragged.
var M = ()=>C & A;
// Similarly a point can be defined by MEETING (^) two lines.
// Again, we define point D as a function so it will update when
// L or M change.
var D = ()=>L ^ M;
// We now use the graph function to create an SVG object that visualises
// our algebraic elements. The graph function accepts an array of items
// that it will render in order. It can render points, lines, labels,
// colors, line segments and polygons.
document.body.appendChild(this.graph([
"Drag A,B,C", // First label is used as title.
0xD0FFE1, // Numbers are colors - use hex!
[A,B,C], // render polygon ABC.
0x882288, // Set the color to purple.
[B,C], // Render line segment from B to C.
0x00AA88, // Medium green.
L, "L", M, "M", // Render and label lines.
0x224488, // Set color blue.
D, "D", // Intersection point of L and M
0x008844, // Set darker green
A, "A", // Render point A and label it.
B, "B", // Render point B and label it.
C, "C", // Render point C and label it.
],{ grid : true, // Display a grid
labels : true, // Label the grid
lineWidth : 3, // Custom lineWidth (default=1)
pointRadius : 1, // Custon point radius (default=1)
fontSize : 1, // Custom font size (default=1)
scale : 1, // Custom scale (default=1),
mousewheel: true
}));
});
```
--------------------------------
### Solve System of Equations in PGA 2D
Source: https://github.com/enkimute/ganja.js/blob/master/examples/galculator.html
Demonstrates solving a system of linear equations using PGA 2D. The example shows the conversion of equations to Ganja.js notation and the expected result.
```plaintext
* x+y-0.5=0
* 2x-1y=0
* _P2D_
* _e1__+__e2__\-__0__.__5__e0_
* _ST__x1_
* _Cl__2__e1__\-__e2_
* _ST__x2_
* _Cl__x1__∧__x2_
* _ST__x3_
* _Cl__x3__/__(\_\-__E0__●__x3__)_
* _=_
```
--------------------------------
### Full Dynamics Simulation Setup
Source: https://github.com/enkimute/ganja.js/blob/master/examples/pga_dyn.html
Sets up a 4D geometric algebra environment, defines a hypercube, and implements a physics simulation loop including gravity, Hooke's law, and damping forces.
```javascript
// Set the number of dimensions.
window.d = 4;
// Create a d-dimensional geometric algebra over the reals.
Algebra(d, 0, 1, ()=>{
// Create a hypercube (square in 2D, cube in 3D, ...)
// Start by defining its vertices.
var p = [...Array(2**d)]
.map((x,i)=>i.toString(2)) // [0, 1, 10, 11, 100, ...]
.map(x=>('00000'+x).slice(-d)) // [000, 001, 010, 011, ...]
.map(x=>x.split('').map(x=>x-0.5)) // [[-0.5, -0.5, -0.5], [-0.5, -0.5, 0.5], ...]
.map(x=>!(1e0 + x*[1e1,1e2,1e3,1e4])); // PGA points are dual vectors.
// Our forques
var attach = (1-0.5e02) >>> p[2**d-1];
var F = (M,B)=>{
var Gravity = !(~M >>> -9.81e02);
var Hooke = 12*((~M >>> attach) & p[2**d-1]);
var Damping = !(-0.5 * B);
return Gravity + Hooke + Damping;
}
// Now consider all vertex pairs and create edges for those
// pairs that differ only in one coordinate.
var e = p.map((a,i)=>p.map((b,j)=> i<=j||(i^j)&(i^j-1)?0:[a,b] // note that &,^ here are bitwise ops since i,j are integer
)).flat().filter(x=>x);
// Physics state.
var state = [1-0.5e02, 1e12 + 1.3e13 + 0.5e24]; // The derivative of the state.
var dS = ([M,B])=>[ -0.5*M*B, (F(M,B) - 0.5*(B.Dual*B-B*B.Dual)).UnDual ];
// Render
var c= this.graph(()=>{
// Update the state
for (var i=0; i<10; ++i)
state = state + 1/600 * dS(state);
return [
0x009977, ...state[0] >>> e, attach, [attach, state[0]>>>p[2**d-1]]
];
},{lineWidth:6,animate:1,scale:1.5});
c.style.background='white';
c.style.maxHeight='300px';
c.style.width = '100%';
c.onwheel = undefined
return c;
})
md(`
```
--------------------------------
### Complex Numbers Multiplication Example
Source: https://github.com/enkimute/ganja.js/blob/master/examples/galculator.html
This example demonstrates the multiplication of two complex numbers (3+2i) and (1+4i) using Ganja.js.
```javascript
help:'C: Complex Numbers.Example: calculate (3+2i)*(1+4i)
C(3+2e1)*(1+4e1)=
'
```
--------------------------------
### Calculator Initialization and Display
Source: https://github.com/enkimute/ganja.js/blob/master/examples/galculator.html
Sets up the calculator's initial state, including defining global variables and elements, and implementing functions for displaying output and history.
```javascript
var Al = Algebra(), mode=0, histor='', cur='', store=false, help=false, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10;
var graph=document.getElementById('graph');
graph.style.opacity=0.3;
var hist=document.getElementById('hist');
var title=document.getElementById('title');
var show=(x)=>{
x=x.replace(/e(\[012345\]+)/g,'e$1').replace(/&/g,'∨').replace(/\\^/g,'∧').replace(/\\<\\,'●')
document.getElementById('screen').innerHTML=x||'0';
if ((mode==3 || mode==4 || mode==5) && [x1,x2,x3,x4,x5].filter(x=>x).length){
var options={};
if (mode==5) options.conformal=true;
while(graph.firstChild) graph.removeChild(graph.firstChild);
var c=graph.appendChild(Al.graph([x1,x2,x3,x4,x5].filter(x=>x).map(x=>x.slice()),options))
c.style.width = c.style.height = '100%';
c.style.backgroundColor='transparent';
}
}
var print = (x)=>{
histor += ' '+x;
hist.innerHTML=histor.split(' ').slice(-10).join(' ');
}
var patch = (x)=>{
print((((!x.match(/=/))?cur+'=':'')+x).replace(/i/g,'e\_1').replace(/(\[^\\d\])e\_|^e\_/g,'$11e\_').replace(/e\_/g,'e').replace(/e(\[012345\]+)/g,'e$1').replace(/&/g,'∨').replace(/\\^/g,'∧').replace(/\\<\\,'●'));
return x.replace(/(\[^\\d\]*\\d*\\.\\d*\\d*\\d*\\d*)(\d*)/g,'$1').replace(/i/g,'e\_1').replace(/(\[^\\d\])e\_|^e\_/g,'$11e\_').replace(/e\_/g,'e');
}
var toHelp=(x)=>x.replace(/(\[eE\])(\\d+)/g,'$1$2').replace(/\_(\[\\+\\-\\/\\?\\(\\) \]) /g,'$1').replace(/\_\\^/g,'∧').replace(/\_\\&/g,'∨').replace(/\_\\./g,'●').replace(/\_\\*/g,'∗');
function hello() {
print(toHelp('Enki\'s GAlculator - Geometric Algebra Pocket Calculator