// $Id: Penrose.pov,v 1.16 2006/05/06 04:24:29 jon Exp $ #include "Penrose.inc" // ---------- Scene Constants ---------- // Tile area dimensions #declare tile_xlen = 32; #declare tile_zlen = 24; // Amount of space between tiles #declare tile_margin = 1/25; // Tile thickness #declare tile_height = 1/2000; // Tile decorations #declare draw_thick = yes; #declare draw_thin = yes; #declare draw_edges = no; #declare draw_kites = yes; #declare draw_darts = yes; #declare standard_curve = no; #declare ball_curve = no; #declare tourist_curve = no; // I noticed the "tourist curve" in a color plate in "The Mathmatical Tourist" by Ivars Peterson. // That image used both the standard curve and the tourist curve, so that they crossed in all the // thin tiles. All other markings I have seen use the "ball curve" and the "standard curve", // although the ball is usually a small torus instead of a sphere the way I have it here. #declare short_curve = no; #declare long_curve = no; // Short curve is the curve that goes through the short edges of kites and darts, Long curve is // the curve going through the long edges of the tiles. #declare draw_bars = no; #declare std_bend = 1/3; #declare std_rad = 1/12; #declare std_col = <1/3, 1, 1/3>; #declare ball_rad = 1/5; #declare ball_col = <1/2, 1/2, 1>; #declare tour_bend = 1/3; #declare tour_rad = 1/12; #declare tour_col = <1, 1/3, 1/3>; #declare short_bend = phi; #declare short_rad = 1/12; #declare short_col = <1/3, 1, 1/3>; #declare long_bend = 1; #declare long_rad = 1/12; #declare long_col = <1, 1/3, 1/3>; #declare bar_rad = 1/18; #declare bar_col = <1/2, 1/2, 1>; #declare edge_col = <1,1,1>; #declare ball1_rad = 1 - phi/2; #declare ball1_col = <1, 1/3, 1/3>; #declare ball2_rad = 1 - phi/2; #declare ball2_col = <1/3, 1, 1/3>; #declare convert2rhombs = no; #declare pos = <0.001,0,0.001>; #declare ang = 9; #declare max_lev = 7; #declare RND_STRM = seed(1); // ---------- Useful Macros ---------- // This is for making sure there is only one ball drawn at each location. #macro ball_init () #declare have_ball = array[2 * tile_xlen + 1][2 * tile_zlen + 1]; #declare r = 0; #while (r < 2 * tile_xlen + 1) #declare c = 0; #while (c < 2 * tile_zlen + 1) #declare have_ball[r][c] = false; #declare c = c + 1; #end #declare r = r + 1; #end #end #macro ball_present (pos) #local result = yes; #if (have_ball[floor (pos.x*phi) + tile_xlen][floor (pos.z*phi) + tile_zlen] = false) #local result = no; #end result #end #macro ball_add (pos) #declare have_ball[floor (pos.x*phi) + tile_xlen][floor (pos.z*phi) + tile_zlen] = true; #end // ---------- Rhomb Tile Macros ---------- // This macro generates a "box" for a rhomb tile. It's handy // for doing CSG operations on a tile to decorate it. #macro rhomb_tile (a, b, c, d, height, margin) #local ac = (c - a) * margin; #local bd = (d - b) * margin; #local newa = a + ac; #local newb = b + bd; #local newc = c - ac; #local newd = d - bd; prism { linear_spline -height, height, 5, , , , , } #end #macro tile_edges (a, b, c, d, edge_color) #if (draw_edges = yes) cylinder { a, b, tile_margin pigment { rgb edge_color } } cylinder { b, c, tile_margin pigment { rgb edge_color } } cylinder { c, d, tile_margin pigment { rgb edge_color } } cylinder { d, a, tile_margin pigment { rgb edge_color } } #end #end #macro PENROSE_thick (pos, ang) #macro PENROSE_object (a, b, c, d) #if (draw_thick = yes) object { rhomb_tile (a, b, c, d, tile_height, tile_margin / s72) pigment { rgb <1,1,1> - vnormalize () / 2 } } #end tile_edges (a, b, c, d, edge_col) #if (ball_curve = yes) #if (ball_present (a) = no) ball_add (a) sphere { a, ball_rad pigment { rgb ball_col } } #end #end #if (standard_curve = yes) intersection { rhomb_tile (a, b, c, d, std_rad, 0) torus { 1 - std_bend, std_rad translate c } pigment { rgb std_col } } #end #if (tourist_curve = yes) intersection { rhomb_tile (a, b, c, d, tour_rad, 0) union { torus { 1 - tour_bend, tour_rad translate a } torus { tour_bend, tour_rad translate c } } pigment { rgb tour_col } } #end #end PENROSE_thick_corners (pos, ang) #end #macro PENROSE_thin (pos, ang) #macro PENROSE_object (a, b, c, d) #if (draw_thin = yes) object { rhomb_tile (a, b, c, d, tile_height, tile_margin / s36) pigment { rgb vnormalize () / 2 } } #end tile_edges (a, b, c, d, edge_col) #if (ball_curve = yes) #if (ball_present (a) = no) ball_add (a) sphere { a, ball_rad pigment { rgb ball_col } } #end #end #if (standard_curve = yes) intersection { rhomb_tile (a, b, c, d, std_rad, 0) torus { std_bend, std_rad translate c } pigment { rgb std_col } } #end #if (tourist_curve = yes) intersection { rhomb_tile (a, b, c, d, tour_rad, 0) union { torus { tour_bend, tour_rad translate b } torus { tour_bend, tour_rad translate d } } pigment { rgb tour_col } } #end #end PENROSE_thin_corners (pos, ang) #end // ---------- Kite and Dart Tile Macros ---------- #macro kite_tile (a, b, c, d, height, margin) #local newa = a + (c - a) / (phi + 1) * margin / s36; #local newb = b + ((c - b) / (phi + 1) + (a - b) / phi) * margin / s36; #local newc = c + (a - c) / (1 + 2 * c72) * margin / s36; #local newd = d + ((c - d) / (phi + 1) + (a - d) / phi) * margin / s36; prism { linear_spline -height, height, 5, , , , , } #end #macro PENROSE_kite (pos, ang) #macro PENROSE_object (a, b, c, d) #if (draw_kites = yes) object { kite_tile (a, b, c, d, tile_height, tile_margin) pigment { rgb <1,1,1> - vnormalize () / 2 } } #end tile_edges (a, b, c, d, edge_col) #if (ball_curve = yes) #if (ball_present (a) = no) ball_add (a) sphere { a, ball1_rad pigment { rgb ball1_col } } #end #if (ball_present (b) = no) ball_add (b) sphere { b, ball2_rad pigment { rgb ball2_col } } #end #if (ball_present (c) = no) ball_add (c) sphere { c, ball1_rad pigment { rgb ball1_col } } #end #if (ball_present (d) = no) ball_add (d) sphere { d, ball2_rad pigment { rgb ball2_col } } #end #end #if (long_curve = yes) intersection { kite_tile (a, b, c, d, long_rad, 0) torus { long_bend, long_rad translate c } pigment { rgb long_col } } #end #if (short_curve = yes) intersection { kite_tile (a, b, c, d, short_rad, 0) torus { short_bend - 1, short_rad translate a } pigment { rgb short_col } } #end #if (draw_bars = yes) cylinder { (4 * a + b) / 5, (2 * (phi + 1) * c + d) / (2 * phi + 3), bar_rad pigment { rgb bar_col } } cylinder { (4 * a + d) / 5, (2 * (phi + 1) * c + b) / (2 * phi + 3), bar_rad pigment { rgb bar_col } } cylinder { (2 * (phi + 1) * c + d) / (2 * phi + 3), (2 * (phi + 1) * c + b) / (2 * phi + 3), bar_rad pigment { rgb bar_col } } #end #end #if (convert2rhombs = yes) PENROSE_kite_rhombs (pos, ang, 0) #else PENROSE_kite_corners (pos, ang) #end #end #macro dart_tile (a, b, c, d, height, margin) #local newa = a + (c - a) / phi * margin / s36; #local newb = b + ((c - b) / phi + a - b) * margin / s36; #local newc = c + (a - c) * margin / s36; #local newd = d + ((c - d) / phi + a - d) * margin / s36; prism { linear_spline -height, height, 5, , , , , } #end #macro PENROSE_dart (pos, ang) #macro PENROSE_object (a, b, c, d) #if (draw_darts = yes) object { dart_tile (a, b, c, d, tile_height, tile_margin) pigment { rgb vnormalize () / 2 } } #end tile_edges (a, b, c, d, edge_col) #if (ball_curve = yes) #if (ball_present (a) = no) ball_add (a) sphere { a, ball2_rad pigment { rgb ball2_col } } #end #if (ball_present (b) = no) ball_add (b) sphere { b, ball1_rad pigment { rgb ball1_col } } #end #if (ball_present (c) = no) ball_add (c) sphere { c, ball2_rad pigment { rgb ball2_col } } #end #if (ball_present (d) = no) ball_add (d) sphere { d, ball1_rad pigment { rgb ball1_col } } #end #end #if (long_curve = yes) intersection { dart_tile (a, b, c, d, long_rad, 0) torus { phi - long_bend, long_rad translate c } pigment { rgb long_col } } #end #if (short_curve = yes) intersection { dart_tile (a, b, c, d, short_rad, 0) torus { 2 - short_bend, short_rad translate a } pigment { rgb short_col } } #end #if (draw_bars = yes) cylinder { (a + 4 * b) / 5, (c + 2 * (phi + 1) * b) / (2 * phi + 3), bar_rad pigment { rgb bar_col } } cylinder { (a + 4 * d) / 5, (c + 2 * (phi + 1) * d) / (2 * phi + 3), bar_rad pigment { rgb bar_col } } cylinder { (c + 2 * (phi + 1) * b) / (2 * phi + 3), (c + 2 * (phi + 1) * d) / (2 * phi + 3), bar_rad pigment { rgb bar_col } } #end #end #if (convert2rhombs = yes) PENROSE_dart_rhombs (pos, ang, 0) #else PENROSE_dart_corners (pos, ang) #end #end // ---------- Scene Description ---------- inflate_init (pos.x-tile_xlen, pos.z-tile_zlen, pos.x+tile_xlen, pos.z+tile_zlen, max_lev) #declare image_number = 5; #switch (image_number) #case (0) // Rhombs with all 3 curves #declare ball_curve = yes; #declare standard_curve = yes; #declare tourist_curve = yes; ball_init () thick (pos, ang, max_lev) #break #case (1) // Kites & Darts with both curves and Ammon bars #declare long_curve = yes; #declare short_curve = yes; #declare draw_bars = yes; kite (pos, ang, max_lev) #break #case (2) // Just the Kite and Dart curves #declare long_curve = yes; #declare short_curve = yes; #declare long_bend = phi * 0.9; #declare short_bend = phi * 1.15; #declare draw_kites = no; #declare draw_darts = no; kite (pos, ang, max_lev) #break #case (3) // Kites & Darts with inflated edges overlaid union { kite (pos, ang, max_lev) scale } inflate_init (pos.x-tile_xlen, pos.z-tile_zlen, pos.x+tile_xlen, pos.z+tile_zlen, max_lev+1) #declare draw_edges = yes; #declare draw_kites = no; #declare draw_darts = no; #declare ball_curve = yes; ball_init () kite (pos, ang, max_lev+1) #break #case (4) // Kites & Darts with conversion to Rhomb edges overlaid kite (pos, ang, max_lev) inflate_init (pos.x-tile_xlen, pos.z-tile_zlen, pos.x+tile_xlen, pos.z+tile_zlen, max_lev) #declare convert2rhombs = yes; #declare draw_edges = yes; #declare draw_thick = no; #declare draw_thin = no; #declare ball_curve = yes; #declare standard_curve = yes; ball_init() kite (pos, ang, max_lev) #break #case (5) // Rhombs with inflated rhomb edges overlaid #declare draw_thin = no; union { thick (pos, ang, max_lev - 1) scale } inflate_init (pos.x-tile_xlen, pos.z-tile_zlen, pos.x+tile_xlen, pos.z+tile_zlen, max_lev) #declare draw_edges = yes; #declare draw_kites = no; #declare draw_darts = no; #declare draw_thick = no; #declare draw_thin = no; #declare standard_curve = no; #declare tourist_curve = yes; #declare tour_bend = 2 - phi; thick (pos, ang, max_lev) #break #end light_source { <0, 9, 0>, <1,1,1> * 3/2 parallel point_at <0, 0, 0> } camera { location pos + <0, 17, 0> look_at pos }