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
//
// 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

   //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]
}


radius = 1.5 in
distance=15 in
height=10 in
g = new graphics
g.font["SansSerif",0.1 in]
g.stroke[.02 in]

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])
      {
         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]
}

g.color[1,0,0]
g.drawEllipseCenter[0 radius,0 radius,2 radius, 2 radius]
g.show[]   

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]
}
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 17591 days, 17 hours, 37 minutes ago.