home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 14 / CDACTUAL.iso / cdactual / demobin / share / w95 / povwin3 / PYRAMID.ZIP / PYRAMID.INC next >
Encoding:
Text File  |  1996-10-20  |  7.0 KB  |  200 lines

  1. //
  2. // pyramid.inc version 1.0
  3. // Create multi-sided pyramid objects using a variety of parameters.
  4. //
  5. // Donated to the public domain
  6. //
  7. // Written by Michael D Johnson
  8. //         mdjohnson@voyager.net or redbeard@quark.gmi.edu
  9. //         http://quark.gmi.edu/~redbeard
  10. //
  11. // Most recent version is available at
  12. //     http://quark.gmi.edu/~redbeard/raytrace/POVRay-Util.html
  13. //
  14. //
  15. // Variables
  16. // ---------
  17. // Only one of each set of indented variables need be set, as determined
  18. // by the variable immediately preceeding each set.  Values in brackets []
  19. // are default values.  Note that once the routine is called, there can be
  20. // no defaults assumed, although the values from the last call are still in
  21. // effect, since defaults are assigned only to undefined variables.
  22. // 
  23. // Sides    [4]    Number of sides
  24. // HeightMode    [0]    Method for determining height of pyramid.
  25. //             0 - Height, 1 - SideAngle, 2 - SideHeight, 3 - Edge.
  26. //             All values are calculated.
  27. //  Height    [0.5]    Height to make pyramid
  28. //  SideAngle    [55]    Angle from base plane of the sides.
  29. //  SideHeight    [1]    The "height" of a side of the pyramid.  Actually, the
  30. //             distance from the center of a base edge to the apex
  31. //             of the pyramid
  32. //  Edge    [1]    Length of an edge other than a base.
  33. // BaseMode    [0]    Method of choosing length of base.  0 - Use Base
  34. //             1 - Use Radius, 2 - use IRadius/  File calculates all.
  35. //  Base    [1]    Length of one side of the base
  36. //  Radius    [1]    Radius of circumscibed circle
  37. //  IRadius    [1]    Radius of an inscribed circle
  38. // 
  39. // DEBUG    [na]    If DEBUG is declared to a true value, then some
  40. //             debugging output is created.  If DEBUG is
  41. //             undefined or false, then this output is bypassed.
  42. // 
  43. // Return Values
  44. // -------------
  45. // These variables are set in addition to the above variables.
  46. // 
  47. // IAngle        Angle between two edges of the base
  48. // CAngle        Angle formed at center between two adjacent base
  49. //            verticies.  In other words, the angle that
  50. //             the pyramid can be rotated (about y axis) and 
  51. //             maintain apparent orientation.  There is probably
  52. //             a simpler way to say this, but I cant think of it.
  53. // 
  54. // Pyramid is centered at origin, with base on y=0 plane.  Height is measured
  55. // in positive y direction.  One edge lies parallel to the x axis in the
  56. // positive z direction.
  57. // 
  58. // Use:
  59. // ----
  60. // 1 Set appropriate variables
  61. // 2 Use a line similar to:
  62. //   object { #include "pyramid.inc" }
  63. // 
  64. // Side note:
  65. // ----------
  66. // The bounding box used within the intersection reduces trace time by
  67. // roughly 75%.  Always use bounding_boxes of you can for intersections and
  68. // differences.
  69. // 
  70.  
  71. #ifndef (Sides) #declare Sides = 4 #end
  72. #ifndef (HeightMode) #declare HeightMode = 0 #end
  73. #ifndef (Height) #declare Height = 0.5 #end
  74. #ifndef (SideAngle) #declare SideAngle = 55 #end
  75. #ifndef (SideHeight) #declare SideHeight = 1 #end
  76. #ifndef (Edge) #declare Edge = 1 #end
  77. #ifndef (BaseMode) #declare BaseMode = 0 #end
  78. #ifndef (Base) #declare Base = 1 #end
  79. #ifndef (Radius) #declare Radius = 1 #end
  80.  
  81. #if (Sides < 3) #error "Must have at least 3 Sides." #end
  82. #declare CAngle = 360 / Sides    // Degrees of rotation between sides
  83. #declare _pyramid_cr = radians(CAngle)
  84. #declare IAngle = 180 - CAngle    // Internal angles of base
  85. #declare _pyramid_ir = radians(IAngle)
  86.  
  87. // The _pyramid_*s below are to permit the entry of each equation used only
  88. // once, simplifying debugging.
  89. #switch (int(BaseMode))
  90.   #case (0)    // Know the length of an edge of the base.
  91.     #declare _pyramid_r = false
  92.     #declare _pyramid_i = false
  93.   #break
  94.   #case (1)    // Know the radius of a circumscribed circle
  95.     #declare Base = 2 * Radius * sin(_pyramid_cr / 2)
  96.     #declare _pyramid_r = true
  97.     #declare _pyramid_i = false
  98.   #break
  99.   #case (2)    // Know the radius of an inscribed circle
  100.     #declare Base = IRadius * 2 / tan(_pyramid_ir / 2)
  101.     #declare _pyramid_r = false
  102.     #declare _pyramid_i = true
  103.   #break
  104. #else
  105.   #error "Invalid value for BaseMode."
  106. #end
  107.  
  108. // If a value is not known, calculate it.
  109. #if (!_pyramid_r) #declare Radius = Base / (2 * sin(_pyramid_cr / 2)) #end
  110. #if (!_pyramid_i) #declare IRadius = Base * tan(_pyramid_ir / 2) / 2 #end
  111.  
  112. // Same thing as for the base.
  113. #switch (int(HeightMode))
  114.   #case (0)    // Know the height
  115.     #declare SideAngle = degrees(atan2(Height, IRadius))
  116.     #declare _pyramid_s = false
  117.     #declare _pyramid_d = false
  118.     #declare _pyramid_h = true
  119.     #declare _pyramid_a = true
  120.   #break
  121.   #case (1)    // Know the angle from the base to a side
  122.     #declare _pyramid_a = true
  123.     #declare _pyramid_h = false
  124.     #declare _pyramid_s = false
  125.     #declare _pyramid_d = false
  126.   #break
  127.   #case (2)    // Know the "height" of a side
  128.     #declare _pyramid_a = false
  129.     #declare _pyramid_h = false
  130.     #declare _pyramid_s = true
  131.     #declare _pyramid_d = false
  132.   #break
  133.   #case (3)    // Know the length of an edge of a side
  134.     #declare SideHeight = pow(Edge, 2) - pow(Base / 2, 2)
  135.     #declare _pyramid_a = false
  136.     #declare _pyramid_h = false
  137.     #declare _pyramid_s = true
  138.     #declare _pyramid_d = true
  139.   #break
  140. #else
  141.   #error "Invalid value for HeightMode."
  142. #end
  143.  
  144. #if (_pyramid_s & (!_pyramid_a))
  145.   #declare SideAngle = degrees(acos(IRadius / SideHeight))
  146.   #declare _pyramid_a = true
  147. #end
  148.  
  149. // This error is only generated if something has been improperly changed
  150. #if (!_pyramid_a) #error "Internal error." #end
  151.  
  152. // Calculate the values if needed.
  153. #if (!_pyramid_h) #declare Height = IRadius * tan(radians(SideAngle)) #end
  154. #if (!_pyramid_s)
  155.   #declare SideHeight = IRadius / cos(radians(SideAngle)) 
  156. #end
  157. #if (!_pyramid_d)
  158.   #declare Edge = sqrt(pow(Base / 2, 2) + pow(SideHeight, 2))
  159. #end
  160.  
  161. // Build the pyramid.  It is the intersection of a base plane and planes
  162. // forming the sides.  It is bounded by a cone (since that is the closet
  163. // thing to it that bounds it)
  164. intersection
  165. {
  166.     plane { -y, 0 }
  167.     #declare IRadiusoop = 0
  168.     #while (IRadiusoop < Sides)
  169.       plane
  170.       {
  171.       y, 0
  172.       rotate x * SideAngle
  173.       translate z * IRadius
  174.       rotate y * IRadiusoop * CAngle
  175.       }
  176.       #declare IRadiusoop = IRadiusoop + 1
  177.     #end
  178.     bounded_by { cone { 0, Radius, y * Height, 0 } }
  179. }
  180.  
  181. // Display the various calculated values on the debug stream.
  182. #ifdef (DEBUG)
  183.   #if (DEBUG)    
  184.     #debug "Values from pyramid.inc:"
  185.     #debug concat("\n  Sides:      ", str(Sides, 0, 0))
  186.     #debug concat("\n  HeightMode: ", str(HeightMode, 0, 0))
  187.     #debug concat("\n    Height:     ", str(Height, 0,-1))
  188.     #debug concat("\n    SideAngle:  ", str(SideAngle, 0,-1))
  189.     #debug concat("\n    SideHeight: ", str(SideHeight, 0,-1))
  190.     #debug concat("\n    Edge:       ", str(Edge, 0,-1))
  191.     #debug concat("\n  BaseMode:   ", str(BaseMode, 0, 0))
  192.     #debug concat("\n    Base:       ", str(Base, 0,-1))
  193.     #debug concat("\n    Radius:     ", str(Radius, 0,-1))
  194.     #debug concat("\n  CAngle:     ", str(CAngle, 0,-1))
  195.     #debug concat("\n  IAngle:    ", str(IAngle, 0,-1))
  196.     #debug concat("\n  IRadius: ", str(IRadius, 0,-1), "\n\n")
  197.   #end
  198. #end
  199.   
  200.