ren.fun 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. #import std
  2. #import nat
  3. #import flo
  4. #import plo
  5. #comment -[
  6. These are some functions for rendering functions of two variables as a
  7. surface.
  8. The main one is the rendering function, which takes an argument of the
  9. form ((observer,eccentricty),visualization) to a rendering of the
  10. surface expressed in a LaTeX picture enviornment with pstricks
  11. commands.
  12. The observer can be a list of floating point numbers <x,y,z> giving
  13. the coordinates of the focal point for the image, using a coordinate
  14. system wherein the surface is inscribed in the cube in the first
  15. octant bounded by the origin and <1,1,1>. Alternatively, the observer
  16. can be a string of the form (i|o)(l|m|h)(e|n|w|s)(+|-) specifying the
  17. distance (in or out), the elevation (low, medium or high), and the
  18. azimuth (north, south, east or west, with + or - for a slight positive
  19. or negative angular displacement, respectively) assuming the north
  20. direction coincides with the positive y axis and east with the
  21. positive x axis.
  22. The eccentricity can be empty or can be a pair of floating point
  23. numbers (x,y) specifying an elongation in the x and y directions of
  24. the cube in 3-space in which the surface is inscribed. Equal values
  25. greater than one specify a pizza box shape, and less than one specify
  26. a tower. Unequal values specify a rectangular prism. Observer
  27. coordinates are automatically displaced consistently with the
  28. eccentricity.
  29. The visualization contains a family of curves specifying the surface,
  30. with equally many points on each one. The peg fields and pegaxis
  31. should be initialized with the y values and the abscissa with the x
  32. values. True perspective is obtained only when a square picture frame
  33. or at least a square viewport are specified, but the image will be
  34. scaled to fit any given viewport. Displacements and rotations may
  35. be specified for the axis labels and are supported.
  36. Another useful function in this module is drafts, which takes an
  37. eccentricity and a visualization, as above, and generates 48 different
  38. views in a free standing LaTeX document.
  39. Copyright (C) 2007-2010 Dennis Furey]-
  40. ----------------------------------------------------- constants -------------------------------------------------------------
  41. corners = %eLLPk ~&r?(1.!,0.!)** zipp0^*D(~&y,iota) 8
  42. diffusion = 25. # determines light attenuation with distance; set to 0 for a point source or infinity for an overcast sky
  43. low_horizon = 20. # vertical angular displacements used for recommended observation points
  44. mid_horizon = 35.
  45. hi_horizon = 50.
  46. plus_angle = 35. # horizontal angular displacements used for recommended observation points
  47. minus_angle = 55.
  48. #library+
  49. recommended_observers = # a list of pairs (c,<x,y,z>) where c is a string of the form (i|o)(l|m|h)(e|n|w|s)(+|-)
  50. (\/~&H ~&/<low_horizon,mid_horizon,hi_horizon> plus* ~&rlDSL <plus_angle,minus_angle>-* ari4/0. 270.) -+
  51. ~&TblrDlrlPCrrPXS2O+ ~&bbI/(`i,`o)+ ~~ ~&p/*'lmh'; //~&plrDSrlPlCrrPXSSL block2 'e+n-n+w-w+s-s+e-',
  52. %eLLLWMk+ plus/***$.5+ ^(times/***2.,times/***3.5)+ * *-; * ^T\~&lt times*+ ~&lhPrD,
  53. -*+ ~* times/pi; div\180.; ^lrNCC/cos sin+-
  54. #library-
  55. ------------------------------------------------ geometric functions --------------------------------------------------------
  56. #optimize+
  57. observer = -:~& recommended_observers
  58. coterminal = %eLWWMk; ~&G; either ~&rlG; either ==
  59. unit = vid^*D\~& sqrt+ plus:-0.+ times*+ ~&iiXS
  60. edges = %eLMk; %eLWSMk+ ~&hthPXSs+ -<&*+ ~&lrNCCS+ ~&plrEZFitZB*~+ ~&HiiK0\corners+ *+ times*++ //~&p+ div\*.5
  61. far_corners = # takes (observer,center) to (near corner,far corner)
  62. %eLWMk; %eLWMk+ -+
  63. ~&bl+ (^ ^($-,$^) fleq+ ~&br)+ * ^/~&r iprod+ ~&iiX+ minus*+ ~&p,
  64. ^D/~&l ~&H\corners+ *+ times*++ //~&p+ div\*.5+ ~&r+-
  65. view = # takes (observer,center) to a perspective map to the unit square
  66. %eLWMk; %fMk+ -+
  67. (("f","g","h"). <."g"+ ~&h,"h"+ ~&th>+ "f")^/~&r -+
  68. ^G(bus~~; lesser not fleq,~&bl); ~~ ("s","l"). div\"s"+ minus\"l",
  69. ^(fleq$-,fleq$^)^~HhSthPSX(*+ ~&r,~&H\corners+ *+ times*++ //~&p+ div\*.5+ ~&l)+-,
  70. ^/~&r -+
  71. ("o","u","r","l"). vid^*D(iprod/"l",<.iprod/"r",iprod/"u">)+ minus*+ ~&p\"o",
  72. ^/~&l ^(unit+ oprod,~&)^(unit+ oprod\<0.,0.,1.>,~&)+ minus*+ ~&rlp+-+-
  73. left_light = # takes (observer,center) and selects a light source over the observer's left shoulder
  74. plus^*p/~&r minus*p; ^lrNCT(
  75. ~&lrNCC+ ~&thPhX; times^~G/math..hypot ^(cos,sin)+ math..atan2; //plus div\180. times/pi -60.,
  76. times/1.2+ abs+ ~&z)
  77. right_light = # takes (observer,center) and selects a light source over the observer's right shoulder
  78. plus^*p/~&r minus*p; ^lrNCT(
  79. ~&lrNCC+ ~&thPhX; times^~G/math..hypot ^(cos,sin)+ math..atan2; //plus div\180. times/pi 60.,
  80. times/1.2+ abs+ ~&z)
  81. back_light = # selects a light source position facing the observer slightly from the left and closer to the horizon
  82. plus^*p/~&r minus*p; ^lrNCT(
  83. ~&lrNCC+ ~&thPhX; times^~G/math..hypot ^(cos,sin)+ math..atan2; //plus div\180. times/pi -120.,
  84. times/.75+ abs+ ~&z)
  85. --------------------------------------------------- axis rendering functions ------------------------------------------------
  86. rear_edges = # takes (observer,center) and a viewport
  87. :/'% rear edges'+ ^H(~&r,coterminal~|^\edges+~&lr ~&rrX+ far_corners+ ~&l)^/~&l -+
  88. *+ //+ '\psline[linestyle=dotted,linewidth=0.9pt,linecolor=black,fillstyle=none]{-}'--+ --,
  89. ~~+ (:/`(+ --')'+ ^T/~&h :/`,+ ~&th)++ printf/*'%6.2f'++ +^\view+~&l <..~&h;+ //times+ ~&rl,~&th;+ //times+ ~&rr>+-
  90. side_edges = # takes observer location and a viewport
  91. :/'% side edges'+ ^H(~&r,(not coterminal)~|^\edges+~&lr far_corners+ ~&l)^/~&l -+
  92. *+ //+ '\psline[linestyle=dotted,linewidth=0.9pt,linecolor=black,fillstyle=none]{-}'--+ --,
  93. ~~+ (:/`(+ --')'+ ^T/~&h :/`,+ ~&th)++ printf/*'%6.2f'++ +^\view+~&l <..~&h;+ //times+ ~&rl,~&th;+ //times+ ~&rr>+-
  94. front_edges = # takes observer location and a viewport
  95. :/'% front edges'+ ^H(~&r,coterminal~|^\edges+~&lr ~&llX+ far_corners+ ~&l)^/~&l -+
  96. *+ //+ '\psline[linestyle=dotted,linewidth=0.9pt,linecolor=black,fillstyle=none]{-}'--+ --,
  97. ~~+ (:/`(+ --')'+ ^T/~&h :/`,+ ~&th)++ printf/*'%6.2f'++ +^\view+~&l <..~&h;+ //times+ ~&rl,~&th;+ //times+ ~&rr>+-
  98. axes = # takes ((observer,center),viewport,<x axis,y axis,z axis>)
  99. _axis%LeLWweWwXXMk; -+
  100. ~&pL/<'% x axis','% y axis','% z axis'>+ * -+
  101. %sLMk+ ^lrNCT(
  102. ~&lrtPD; *= _axis%seseLWXXXXMk; %sLMk+ ^lrNCC(
  103. '\put'--+ ^T(
  104. :/`(+ --')'+ ^T(~&h,:/`,+ ~&th)+ printf/*'%6.2f'+ ~&rrrrr,
  105. :/`{+ --'}'+ '\begin{rotate}'--+ --'\end{rotate}'+ ^T(
  106. :/`{+ --'}'+ printf/'%0.3f'+ _axis%seseLWXXXXMk; -+
  107. div\pi+ times/180.+ math..atan2+ (both fleq\0.)?/abs~~ fleq\0.?r/negative~~ ~&,
  108. ~&thPhX+ minus*+ ~&rrrrlrp+-,
  109. ^T/('\makebox(0,0)['--+ --']'+ ~&rl) :/`{+ --'}'+ ^T(
  110. '\scalebox{'--+ --'}'+ printf/'%0.3f'+ ~&rrl,
  111. :/`{+ --'}'+ ~&rrrl))),
  112. '\put('--+ --'){\pscircle*{1.5pt}}'+ ^T(~&h,:/`,+ ~&th)+ printf/*'%6.2f'+ ~&rrrrl),
  113. '\put'--+ ^|T(:/`(+ --')',:/`{+ --'}')^(
  114. ^T(~&l,:/`,+ ~&r)+ printf/$'%6.2f'+ plus^~lhPrlPXlth2rrPXX\~&l.alias plus^*p(~&rl,times*+ ~&lrrPD)^(
  115. times/.4+ sqrt+ iprod+ ~&iiX+ minus*+ ~&p+ ~&rthzXbrrrl,
  116. ~&rhrrr; ^/~&l unit+ minus*+ ~&rlp),
  117. '\begin{rotate}'--+ --'\end{rotate}'+ ^T(
  118. :/`{+ --'}'+ printf/'%0.3f'+ ~&l.rotation,
  119. ^T('\makebox(0,0)['--+ --']'+ ~&rhl,:/`{+ --'}'+ ~&rhrrl)))),
  120. _axis%seseLWXXXLXMk^/~&l ~&r; ^D\~& ~&lzrr+ (fleq+~&lrlPX)~-+ -+
  121. -*+ \/~& ~&p\<'l','lb','rb','r','rt','lt','l'> :/-180. ari6/-150. 150.,
  122. div\pi+ times/180.+ math..atan2+ ~&thPhX+ minus*+ ~&p+ mean~*+ ~&rrPSlSrSXbiK7+-+-,
  123. _axis%eseLWXXLXLMk^p/~&rr -+
  124. %eseLWXXLLMk+ (-*; * ^\~&rr div+~&lrlPX)^*D\~& fleq$-+ ~&lSSL,
  125. %eseLWXXLLLMk; %eseLWXXLLMk+ $^ fleq+ ~~ ~&thPzXSbrrr3S; fleq$-+ * iprod+ ~&iiX+ minus*+ ~&p,
  126. * -*; * -*; * %fOWseWLXXMk; %eseLWXXMk+ ^/~&llPrrrS2H ^/~&rl ^H/~&lr ~&rr; ^\~&rS * ~&l,
  127. ^D/^(~&ll; sqrt++ iprod++ ~&iiX++ minus*++ //~&p,~~+ +^\view+~&l <..~&h;+ //times+ ~&rll,~&th;+ //times+ ~&rlr>) -+
  128. * -*; * ~&lrrSPK7iK1SPXrD; -+
  129. * ^/~&rl ~&llPlrPrrPpD; * ~&rl?\~&rrrX ^/~&rr ~&rrPlX; fleq/eps?l/plus minus,
  130. %eWtLXseLXXLMk; %etLXseLXXLMk+ ~&hllrPrXPrXPtlllPrXPrXSPC+-,
  131. ^D/(^(~&,times/8.)+ div/10.+ ~&rl; div\2.+ plus) -+
  132. %seLXLLLMk+ * ~&p; * ^lrK7p/~&llS ~&lrSPrlrpPD; * ~&rlrE?/~&rlPlDlS ~&l,
  133. %seXLLeLWLXLMk^D(
  134. ~&lrPrrPp; * :^(~/&r.variable &l,^p/~&r.hats ^H/ari+length+~&r.hats ~&/0.+ times/2.+ ~&l),
  135. ~&l; -+
  136. %eLWLLMk; * ~&x+ -< leql+ ~~ ==-~+ ~&p,
  137. (coterminal|=*tttPB)*~+ choices\3+ (not coterminal)~|^\edges+~&r far_corners+-)+-+-+-+-
  138. ------------------------------------------- surface rendering functions -----------------------------------------------------
  139. surface = # takes ((observer,center),light source,visualization), simulates attenuation due to distance and angle of incidence
  140. _visualization%eLWweLwXXMk; :/'% surface'+ -+
  141. :/'\psset{fillstyle=solid,linewidth=0.2pt,linecolor=darkgray}',
  142. ^T/(~&rr.curves; ~attributes*=; ~&i&& ~&s; |=hS&n; ~&iNC+ '\psset{'--+ --'}'+ mat`,+ * ^|T/~& :/`=) -+
  143. * ^|T('\newgray{shade}{'--+ --'}\psset{fillcolor=shade}','\pspolygon'--)^|(
  144. printf/'%0.4f'+ times^/~&l minus/1.+ div\pi+ math..acos+ ~&r,
  145. printf/**'%6.2f'; ~&thPhttPCC; *= :/`(+ --')'+ ^T/~&h :/`,+ ~&th),
  146. ((^\~&rr ^\~&rlr div+ ~&rll2lX)^*D\~& fleq$^+ ~&llPS)+ * ^\~&rr ^(
  147. div/1.+ plus/diffusion+ iprod+ ~&iiX+ minus*+ ~&lrlh2p,
  148. iprod+ unit^~/minus*+~&lrlh2p oprod+ minus~*+ ~&blrpPrlthththPXPG3O),
  149. ^D/~&rl -+
  150. %eLLWLMk+ ~&xrS+ fleq-<&l+ * ^\~&r iprod+ ~&iiX+ minus*+ ~&lrlh2p,
  151. ^D/~&ll %eLLWLMk+ ^(:^\~&l mean*+ ~&lK7,~&r)^*HytpSK7ytpSLllPlrPrlPrrPNCCCCSlSrSXS(
  152. ^(~&l,~viewport+~&rr); %eLeWXMk; *+ *+ ^/~&+ +^\view+~&l <..~&h;+ //times+ ~&rl,~&th;+ //times+ ~&rr>,
  153. %eLLLMk+ ^H\(~&rr.curves; * %eeWXLMk+ -*+ ~/peg points) -+
  154. *+ *+ <..~&rl;+ times^^/!+~&lh ~&rh,~&l;+ times^^/!+~&lth ~&rth,~&rr;+ times^^/!+~&ltth ~&rtth>,
  155. ^(div\*.5+ ~&lr,~&rr; ~placer*+ <.~abscissa,~pegaxis,~ordinates.&h>)+-)+-+-+-
  156. -------------------------------------------- file formatting functions -----------------------------------------------------
  157. lit_rendering = # a light source to a function taking ((observer,eccentricty),visualization) to a LaTeX fragment
  158. "l". _visualization%seLUeWZXwXMk; ~&rhPlrtPCC/'\psset{unit=1pt}'+ -+
  159. -&~pegaxis,~ordinates,~curves; all~peg&& all_same length+ ~points&-?r\<'invalid surface'>!% :^(
  160. ~&r.picture_frame; '\begin{picture}'--+ --+ ~~ printf/$'%0.2f'; :/`(+ --')'+ ^|T/~& :/`,,
  161. --<'\end{picture}'>+ ~&L+ <.
  162. rear_edges+ ~/&l &r.viewport,
  163. side_edges+ ~/&l &r.viewport,
  164. axes^/~&l ~&r; ^/~viewport <.~abscissa,~pegaxis,~ordinates.&h>,
  165. surface^/~&l ^|\~& "l",
  166. front_edges+ ~/&l &r.viewport,
  167. ~&r; ~boxed&& ~picture_frame; -+
  168. :/'% bounding box'+ ~&iNC+ '\put'--+ ^T/~&r '{\dashbox'--+ --'{}}'+ ~&l,
  169. ~~ printf/$'%0.2f'; :/`(+ --')'+ ^|T/~& :/`,+->),
  170. _visualization%eLWwXMk^|(
  171. %eLWMk+ -+
  172. ((all -&fleq/0.+ ~&l,fleq&-)^p/~&l times/*2.+ ~&r)?/<'invalid observation point'>!% ~&,
  173. eql?r\<'misspecified observer'>!% ^\~&rr ~&lrlPE?/~&l times^*p/~&rl div\*.5+ ~&rr,
  174. ^/~&l ^/observer+~&l ~&r; ||(0.5!* 7)! ~&i&& --<0.5>+ ~&lrNCC+ times/$.5+-,
  175. _visualization%Mk+ ?(
  176. ~(picture_frame,margin,headroom)== ~(picture_frame,margin,headroom) visualization&,
  177. ~&\~& visualization+ (picture_frame,margin,headroom,viewport):= (((400.,400.),(-50.,-50.)),50.,50.,(300.,300.))!))+-
  178. #library+
  179. rendering = lit_rendering 50%~?/left_light right_light
  180. left_lit_rendering = lit_rendering left_light
  181. right_lit_rendering = lit_rendering right_light
  182. back_lit_rendering = lit_rendering back_light
  183. drafts = # renders all recommended views of a visualization for a given eccentricity into a free standing LaTeX document
  184. _visualization%eWZwXMk; latex_document+ mat0+ -+
  185. * ^T(<'\mbox{}','\vfill'>--+ ~&llNC,:/''+ --<'\vfill','\pagebreak'>+ rendering),
  186. ^Drll2lXrrPXS/~&l recommended_observers*-+ boxed:=&!+ ~&r+-