Compassless construction of the tangent to a circle at a given point
(c1) block([equalscale:true,plot_style:White_space2D],demo("c:\\rwg\\climax\\tan.dem"))$
First, we have to tell Macsyma how to intersect two lines, given the coordinates of two points on each:
(c2)
interseg(x1,y1,x2,y2,x3,y3,x4,y4):=
[ ((x2-x1)*(x3*y4-x4*y3)-(x4-x3)*(x1*y2-x2*y1)),
-((y2-y1)*(y3*x4-y4*x3)-(y4-y3)*(y1*x2-y2*x1))]/((x2-x1)*(y4-y3)-(x4-x3)*(y2-y1))$
But for some simplification, this could be derived as
(c2)
define(interseg(x1,y1,x2,y2,x3,y3,x4,y4),
('[x,y],subst(linsolve([area_polygon([x1,y1],%%,[x2,y2]),area_polygon([x3,y3],%%,[x4,y4])],%%),%%)))$
(I.e., find the [x,y] that degenerates the two triangles. Computer Algebra lets you compute your programs.)
(c3) xl:[cos(2*%pi*t),cos(1.)]$
(c4) yl:[sin(2*%pi*t),sin(1.)+t*.05]$
(c5) paramplot(xl,yl,t,0,1)$
This draws our circle, with the target point marked by an up-tick at about 1 o'clock.
Now we begin the construction. Choose at random four more points on the circle, marked by horizontal ticks.
(c6) xl:append(xl,[cos(3.),cos(.5),cos(-.7),cos(-2.)]+.05*t)$
(c7) yl:append(yl,[sin(3.),sin(.5),sin(-.7),sin(-2.)])$
(c8) paramplot(xl,yl,t,0,1)$
(There's a faint yellow one at about 4 o'clock. Click to clarify.)
(c9)
xl:append([cos(1.)*(1-t)+t*cos(-.7),cos(-.7)*(1-t)+t*cos(3.),cos(3.)*(1-1.5*t)+1.5*t*cos(.5),
cos(.5)*(1-t)+t*cos(-2.),cos(-2.)*(1-t)+t*cos(1.)],
xl)$
(c10)
yl:append([sin(1.)*(1-t)+t*sin(-.7),sin(-.7)*(1-t)+t*sin(3.),sin(3.)*(1-1.5*t)+1.5*t*sin(.5),
sin(.5)*(1-t)+t*sin(-2.),sin(-2.)*(1-t)+t*sin(1.)],
yl)$
(c11) paramplot(xl,yl,t,0,1)$
Connect the five points in a pentagram, extending the side shown.
(c12)
block([p1:interseg(cos(1.),sin(1.),cos(-.7),sin(-.7),cos(.5),sin(.5),cos(-2.),sin(-2.)),
p2:interseg(cos(-.7),sin(-.7),cos(3.),sin(3.),cos(-2.),sin(-2.),cos(1.),sin(1.)),
p3],
push(p2[1]*(1-2*t)+2*t*p1[1],xl),
push(p2[2]*(1-2*t)+2*t*p1[2],yl),
paramplot(xl,yl,t,0,1),
p3:interseg(p1[1],p1[2],p2[1],p2[2],cos(3.),sin(3.),cos(.5),sin(.5)),
push(p3[1]*(1-2*t)+2*t*cos(1.),xl),
push(p3[2]*(1-2*t)+2*t*sin(1.),yl))$
Join the two intersections as shown, and extend to the extended side:
(c13) paramplot(xl,yl,t,0,1)$
The line through the intersection of the extensions and the original point is the desired tangent!
Here is a frame from a Mathematica animation of the four arbitrary points.
The Mathematica code for this animation is <\P>
Interseg[{x1_, y1_}, {x2_, y2_}, {x3_, y3_}, {x4_, y4_}] := {((x2 - x1)*(x3*y4 - x4*y3) - (x4 - x3)*(x1*y2 - x2*y1)), -((y2 - y1)*(y3*x4 - y4*x3) - (y4 - y3)*(y1*x2 - y2*x1))}/((x2 - x1)*(y4 - y3) - (x4 - x3)*(y2 - y1)) Animate[Block[{pts = {Cos[#], Sin[#]} & /@ {Pi/2, -8*Pi/12 + Sin[u]/2, 3*Pi/10 + Sin[2*u]/3, 5*Pi/5 - Sin[2*u]/3 + Sin[3*u]/4, -Pi/4 + Sin[4*u]/1.5}, p, r}, p = Interseg[pts[[1]], pts[[2]], pts[[4]], pts[[5]]]; r = Interseg[p, Interseg[pts[[2]], pts[[3]], pts[[5]], pts[[1]]], pts[[3]], pts[[4]]]; Graphics[{Line[{pts[[1]], r}], Red, Line[{p, r, pts[[4]]}], Opacity[.5], Polygon[pts], Yellow, Disk[]}]], {u, 0, 2*Pi}]
Interseg is much slicker using complex numbers, even with reversion to ordered pairs required by Graphics:
Interseg[z1_, z2_, z3_, z4_] := Block[{z12 = z1 - z2, z34 = z3 - z4}, {Re[#], Im[#]}&@(z34*Im[z2*z1*] + z12*Im[z3*z4*])/Im[z34*z12*]] Animate[Block[{pts = E^(I*{π/2, Sin[u]/2 - 8*π/12, 3*π/10 + Sin[2*u]/3, 5*π/5 - Sin[2*u]/3 + Sin[3*u]/4, Sin[4*u]/1.5 - π/4}), p, r}, p = Interseg @@ pts[[{1, 2, 4, 5}]]; r = Interseg[p.{1, I}, Interseg @@ pts[[{2, 3, 5, 1}]].{1, I}, pts[[3]], pts[[4]]]; pts = {Re[#], Im[#]} & /@ pts; Graphics[{Line[{pts[[1]], r}], Red, Line[{p, r, pts[[4]]}], Opacity[.5], Polygon[pts], Yellow, Disk[]}]], {u, 0, 2.*π}]