anamorph.frink

View or download anamorph.frink in plain text format


// This performs anamorphic projections of coordinates.
//
// See:
// Anamorphic images, J. L. Hunt, B. G. Nickel, and Christian Gigault
// Am. J. Phys., Vol. 68, No.3, March 2000
//
// https://web.archive.org/web/20110220054127/http://www.physics.uoguelph.ca/phyjlh/morph/Anamorph.pdf
//

projectCylindrical[x1, y1, radius, distance, height] :=
{
   if x1 conforms radius
      x = x1 / radius
   else
      x = x1

   if y1 conforms radius
      y = y1 / radius
   else
      y = y1
   
   d = distance / radius
   h = height / radius
   alpha = arctan[h,d]

   // Planar projections
   yp = (y/sin[alpha])/(1-(y/h)cos[alpha])  // Eq. 2
   xp = x/sqrt[h^2 + d^2 + y^2] * sqrt[h^2+(d+yp)^2]   // Eq. 3, rearranged

   //println["xp,yp=$xp,$yp"]
   
   // Eq.6
   cospsi = (d xp^2+(d+yp) sqrt[d^2 (1-xp^2) + 2 d yp + xp^2 + yp^2]) / ((d+yp)^2 + xp^2)

   xpp = xp + 2xp / (d+yp) (cospsi + yp)(d cospsi - 1)  // Eq. 7
   ypp = -yp + 2 cospsi (cospsi + yp)((d cospsi-1)/(d-cospsi)) // Eq. 8
   //println["xpp,ypp=$xpp,$ypp"]

   if x1 conforms radius
      xpp = xpp * radius

   if y1 conforms radius
      ypp = ypp * radius

   return[xpp, ypp]
}


// Draw a coordinate system, not viewed from an infinite distance, with
// the following parameters.
radius = 1.5 in
distance=15 in
height=10 in

g = new graphics
g.font["SansSerif",0.1 in]
g.stroke[.02 in]
g.color[0,0,0,.2]

for x=-radius to radius step radius/20
{
   p = new polyline
   for y = -2 in to 4 in step .1 in
   {
      [xpp, ypp] = projectCylindrical[x,y,radius,distance,height]
      if ! (isComplex[xpp] or isComplex[ypp] or (xpp^2 + ypp^2 < radius^2))
      {
//         g.text["$x,$y",xpp,ypp]
         p.addPoint[xpp,ypp]
      }
   }
   g.add[p]
}

for y = -2 in to 4 in step .1 in
{
   p = new polyline
   for x=-radius to radius step radius/20
   {
      [xpp, ypp] = projectCylindrical[x,y,radius,distance,height]
      if ! (isComplex[xpp] or isComplex[ypp])
         p.addPoint[xpp,ypp]
   }
   g.add[p]
}

// Draw where the cylinder goes
g.color[1,0,0]
g.drawEllipseCenter[0 radius,0 radius,2 radius, 2 radius]
g.show[]
// g.print[]


// Draw a spiral.
g = new graphics
radius = 1.5 in
distance = 15 in
height = 10 in
turns = 5

p = new polyline
for angle = 0 degrees to circle turns step 1 degree
{
   [xpp, ypp] = projectCylindrical[.9 cos[angle] radius (angle/(circle turns)), .9 (sin[angle]) radius (angle/(circle turns)) + 1 in, radius, distance, height]
   p.addPoint[xpp,ypp]
}

// Draw the cylinder's location
g.stroke[1 cm]
g.add[p]
g.color[1,0,0]
g.drawEllipseCenter[0 radius,0 radius,2 radius, 2 radius]
g.show[]
//g.printTiled[2,2]


View or download anamorph.frink in plain text format


This is a program written in the programming language Frink.
For more information, view the Frink Documentation or see More Sample Frink Programs.

Alan Eliasen was born 17989 days, 12 hours, 22 minutes ago.