Algebra(2,0,1,()=>{
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);
var Ox = -1.5, Oy = 0.2;
var O = point(Ox,Oy);
var f = 0.5,
surf = line(1,0,0),
axis = line(0,1,0),
F1 = () => point(-f,0),
F2 = () => point(f,0);
var a = () => O&F1,
b = () => surf<<O,
c = () => O&point(0,0);
var as = () => a^surf,
bs = () => b^surf,
cs = () => c^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}));
});