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