Published
Edited
Sep 22, 2020
Insert cell
Insert cell
// Create a Clifford Algebra with 2,0,1 metric.
Algebra(2,0,1,()=>{

// Upgrade to 2D PGA.
var point = (x,y)=>1e12-x*1e02+y*1e01,
line = (a,b,c)=>a*1e1+b*1e2+c*1e0,
dist_pp = (X,Y)=>(X&Y).Length,
dist_pl = (P,l)=>(P.Normalized^l.Normalized).e012,
angle = (x,y)=>Math.acos(x.Normalized<<y.Normalized),
project_pl = (P,l)=>(l<<P)*l,
project_lp = (P,l)=>(l<<P)*P,
reject_lp = (P,l)=>(l<<P);

// Make an object point
var Ox = -1.5, Oy = 0.2;
var O = point(Ox,Oy);
// Make the lens
// Define the effective center of reflection for the lens
var f = 0.5, // focal length
surf = line(1,0,0), // surface of the lens
axis = line(0,1,0), // axis of the lens
F1 = () => point(-f,0), // focal point of lens
F2 = () => point(f,0); // focal point of lens
// Make some rays
var a = () => O&F1,// from object to focal point
b = () => surf<<O,//from object perpendicular to surface
c = () => O&point(0,0); // from object to center of lens
// Intersection points
var as = () => a^surf,
bs = () => b^surf,
cs = () => c^surf;
//var testline = point(-2*f,0)&(b^surf);
// The operations for a thin lens (paraxial approx) are two reflections:
// 1. a reflection along the line from the point where the ray intersects the
// lens surface to a point on the optical axis 2f in front of the lens
// 2. a reflection across the surface of the lens
var thinlens = (r, f) =>
(surf*(point(-2*f,0)&(r^surf)))>>>r; // >>> is sandwich product
// calculate the outgoing rays and the image point
var ao = () => thinlens(a,f),
bo = () => thinlens(b,f),
co = () => thinlens(c,f);
// image point(s) These should converge if the object is close to the axis
var I1 = () => (ao^bo).Normalized,
I2 = () => (bo^co).Normalized,
I3 = () => (co^ao).Normalized;
var area = () => (0.5*(I1 & I2 & I3).s).toFixed(3);
var Iavg = () => I1 - I2 + I3; // why the signs?
// plot the lens and the rays
// 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.
return (this.graph([
"Thin lens example. Drag point O around",
0xcccccc,
[point(-2,-f/2),point(0,-f/2),point(0,f/2),point(-2,f/2)],
0xaaaaaa,
"Paraxial region", // good range
0x000000,
O, "O", // Object point
0xff0000, //red
//[O,b^surf], "b", // Render ray and label it.
[O,bs],"b",
[O,as], "a", // Render ray and label it
[O,cs], "c", // Render ray and label it.
0x888888, // change to gray
[point(0,f),point(0,-f)], "Lens", // Render lens surface and label it.
line(0,1,0), "Axis", // optical axis
point(-f,0), "F", // focal point of lens
point(f,0), "F'", // focal point of lens
//testline,
0x0000aa,
[bs,I1], "b'",
[cs,I3], "c'",
[as,I3], "a'",
0x2222ff,
[I1,I2,I3],
0x0000ff,
Iavg, "I",
//area, // avg Image points
],{grid:true}));

});
Insert cell
Algebra = require('ganja.js');
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more