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.

picture

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)$

picture

(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.

picture

(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:

picture

(c13) paramplot(xl,yl,t,0,1)$

The line through the intersection of the extensions and the original point is the desired tangent!

picture

Here is a frame from a Mathematica animation of the four arbitrary points.

Anim frame

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.*π}]