anamorph.frink

Download or view 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]


Download or view 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 19972 days, 0 hours, 23 minutes ago.