#macro old_clock() // An old-style clock. // The face is perpendicular to the {X} axis, centered at the origin. // The front points to {+X}. // The radius is 1.0 #local tx_brass = texture_brushed_metal( < 1.000, 0.900, 0.200 > ) #local tx_white = texture_matte( < 1.000, 0.990, 0.970 > ) #local tx_black = texture_matte( < 0.100, 0.110, 0.120 > ) #local tx_debug = texture_matte( < 1.000, 0.100, 0.800 > ) #local rad = 1.0; #local eps = 0.0001; #local nthk = 0.01; // Thickness of numbers above face plate and hands. #local bthk = 0.20; // Thickness of clock body. #local bug_rad = 1.0*nthk; // Face disk with front surface at orgin #local face_rad = rad - bthk/2; // Radius of face plate. #local face_disk = cylinder{ < 0, 0, 0 >, < -nthk, 0, 0 >, face_rad texture{ tx_white } } // Numerals, with front surface at origin: #local nums_rad = 0.7 * face_rad; // Radius of circle through digit centers. #local nums_sz = 0.3 * face_rad; // Radius of single-digit numerals. #debug concat("!! BOO = ", str(12,0,0), "\n") #local nums_obj = union{ #local h = 1; #while (h <= 12) #local ang = radians(360*h/12); // Angle in radians, clockwise from noon. #local dig_text = str(h,0,0) // Text of string. #debug concat("!! dig_text = ", dig_text, "\n") #if (h >= 10) #local dig_dy = -0.400; // Displacement to center double digit in {Y}. #else #local dig_dy = -0.200; // Displacement to center single digit in {Y}. #end #local dig_dz = -0.350; // Displacement to center numeral in {Z}. #local dig_obj = text{ ttf "arial.ttf", dig_text, 2*nthk, 0*x rotate <90,0,0> rotate <0,0,90> scale < 1.0, nums_sz, nums_sz > translate nums_sz * < 0, dig_dy, dig_dz > } union{ object{ dig_obj } // sphere{ <0,0,0>, bug_rad texture{ tx_debug } } translate nums_rad * < 0, sin(ang), cos(ang) > } #local h = h + 1; #end texture{ tx_black } } // Clock body: #local bdy_rad = rad - bthk/2; #local bdy = difference{ union{ cylinder{ < 0, 0, 0 >, < -bthk, 0, 0 >, bdy_rad } torus{ bdy_rad, bthk/2 rotate 90*z translate -bthk/2*x } } cylinder{ < +nthk, 0, 0 >, < -bthk+nthk, 0, 0 >, bdy_rad + eps } // plane{ -y,0 } texture{ tx_brass } } // Hands: #local hand_hr = 1; // Integer hour, 0..12. #local hand_mm_rad = nums_rad; // Length of minutes' hand. #local hand_mm_wd = 0.08; // Width of minutes' hand. #local hand_mm = object{ old_clock_hand(hand_mm_rad, hand_mm_wd, nthk, true, hand_hr) } #local hand_hh_rad = 0.75*nums_rad; // Length of hours' hand. #local hand_hh_wd = 0.10; // Width of hours' hand. #local hand_hh = object{ old_clock_hand(hand_hh_rad, hand_hh_wd, nthk, false, hand_hr) } #local clk = union{ object{ face_disk translate -6*nthk*x } object{ nums_obj translate -5*nthk*x } object{ hand_hh translate -3*nthk*x } object{ hand_mm translate -1*nthk*x } object{ bdy } } clk #end #macro old_clock_hand(rad,wd,thk,ismin,h) // Clock hand, // The hand will measure {rad} from axis to tip, will be {wd} wide // at the axis, and {thk} thick. // If {ismin} is true returns the minutes' hand, else the hour's hand. // The hand will be positoned as for time "{hh}:{mm}" where // {hh} is the given integer hour {h} and {mm} is computed so // that the two hands are symmetric. // If {h=12} assumes "12:00"; if {h=0} assumes "00:55". // The front face is at {X=0} with origin on axis. #local tx_black = texture_matte( < 0.100, 0.110, 0.120 > ) #local mm = 60*(12 - h)/13; // Minutes value, 0 to 60, fractional. #local tang = degrees(0.5*wd/rad); // Tapering angle. #local eps = 0.001*thk; #local hbox = box{ < 0, -wd/2, -rad/3 >, < -thk, +wd/2, +rad > } #local rang = (2*ismin - 1)*6*(60-mm); // Rotation angle. #local hand = intersection{ object{ hbox translate +eps*x rotate +tang/2*x } object{ hbox translate -eps*x rotate -tang/2*x } rotate rang*x texture{ tx_black } } hand #end