home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / euphoria / wire.ex < prev   
Text File  |  1994-01-31  |  8KB  |  313 lines

  1.         ----------------------------
  2.         -- 3-D Wire Frame Picture --
  3.         ----------------------------
  4. -- Hit space bar to freeze/restart the picture.
  5. -- Any other key to quit.
  6.  
  7. without type_check
  8.  
  9. include graphics.e
  10. include select.e
  11.  
  12. constant GRAPHICS_MODE = 261  -- try to get SVGA
  13. constant X = 1, Y = 2, Z = 3
  14. constant TRUE = 1
  15. constant SCREEN = 1
  16. constant BLACK = 0, WHITE = 255
  17.  
  18. type point(sequence x)
  19.     return length(x) = 3
  20. end type
  21.  
  22. type matrix(sequence x)
  23.     return length(x) = 4 and sequence(x[1])
  24. end type
  25.  
  26. type vector(sequence x)
  27.     return length(x) = 4 and atom(x[1])
  28. end type
  29.  
  30. integer axis
  31. atom sin_angle, cos_angle
  32.  
  33. function product(sequence factor)
  34. -- matrix multiply a number of 4-vectors/4x4 matrices
  35. -- only the first one could be a vector
  36.     sequence a, c
  37.     matrix b
  38.  
  39.     a = factor[1]
  40.     for f = 2 to length(factor) do
  41.     b = factor[f]
  42.     if atom(a[1]) then
  43.         -- a is a vector
  44.         c = repeat(0, 4)
  45.         for j = 1 to 4 do
  46.         c[j] = a[1] * b[1][j] +
  47.                a[2] * b[2][j] +
  48.                a[3] * b[3][j] +
  49.                a[4] * b[4][j]
  50.         end for
  51.     else
  52.         -- a is a matrix
  53.         c = repeat(repeat(0, 4), 4)
  54.         for i = 1 to 4 do
  55.         for j = 1 to 4 do
  56.             for k = 1 to 4 do
  57.             c[i][j] = c[i][j] + a[i][k] * b[k][j]
  58.             end for
  59.         end for
  60.         end for
  61.     end if
  62.     a = c
  63.     end for
  64.     return c
  65. end function
  66.  
  67. sequence vc -- video configuration
  68.  
  69. procedure display(sequence old_coords, sequence coords)
  70. -- erase the old lines, draw the new ones
  71.     for i = 1 to length(old_coords) do
  72.     draw_line(BLACK, old_coords[i][1..2])
  73.     end for
  74.     for i = 1 to length(coords) do
  75.     if vc[VC_COLOR] then
  76.         draw_line(coords[i][3], coords[i][1..2])
  77.     else
  78.         draw_line(WHITE, coords[i][1..2])
  79.     end if
  80.     end for
  81. end procedure
  82.  
  83. function view(point view_point)
  84. -- compute initial view
  85.     matrix t1, t2, t3, t4, n
  86.     atom cos_theta, sin_theta, hyp, a_b
  87.  
  88.     -- change origin
  89.     t1 = {{1, 0, 0, 0},
  90.       {0, 1, 0, 0},
  91.       {0, 0, 1, 0},
  92.       -view_point & 1}
  93.  
  94.     -- get left-handed coordinate system
  95.     t2 = {{-1, 0,  0, 0},
  96.       { 0, 0, -1, 0},
  97.       { 0, 1,  0, 0},
  98.       { 0, 0,  0, 1}}
  99.  
  100.     -- rotate so Ze points properly
  101.     hyp = sqrt(view_point[1] * view_point[1] + view_point[2] * view_point[2])
  102.     sin_theta = view_point[1] / hyp
  103.     cos_theta = view_point[2] / hyp
  104.     t3 = {{cos_theta, 0, sin_theta, 0},
  105.       {        0, 1,         0, 0},
  106.       {-sin_theta,0, cos_theta, 0},
  107.       {        0, 0,         0, 1}}
  108.  
  109.     -- rotate so Ze points at the origin (0, 0, 0)
  110.     t4 = {{1, 0, 0, 0},
  111.       {0, cos_theta, -sin_theta, 0},
  112.       {0, sin_theta, cos_theta, 0},
  113.       {0, 0, 0, 1}}
  114.  
  115.     a_b = 2
  116.  
  117.     n = {{a_b, 0, 0, 0},
  118.      {0, a_b, 0, 0},
  119.      {0, 0, 1, 0},
  120.      {0, 0, 0, 1}}
  121.  
  122.     return product({t1, t2, t3, t4, n})
  123. end function
  124.  
  125. function new_coords(sequence overall, sequence shape)
  126. -- compute the screen coordinates from the 3-D coordinates
  127.     sequence screen_coords, final
  128.     point p
  129.     atom x2, y2
  130.  
  131.     x2 = vc[VC_XPIXELS]/2
  132.     y2 = vc[VC_YPIXELS]/2
  133.     screen_coords = repeat({0, 0, 0}, length(shape))
  134.     for i = 1 to length(shape) do
  135.     for j = 1 to 2  do
  136.         p = shape[i][j]
  137.         final = product({p & 1, overall})
  138.         screen_coords[i][j] = {x2*(final[X]/final[Z]+1),
  139.                    y2*(final[Y]/final[Z]+1)}
  140.     end for
  141.     screen_coords[i][3] = shape[i][3]
  142.     end for
  143.     return screen_coords
  144. end function
  145.  
  146. function x_rotate(point p)
  147. -- compute x rotation of a point
  148.     return {p[X],
  149.         p[Y] * cos_angle + p[Z] * sin_angle,
  150.         p[Z] * cos_angle - p[Y] * sin_angle}
  151. end function
  152.  
  153. function y_rotate(point p)
  154. -- compute y rotation of a point
  155.     return {p[X] * cos_angle - p[Z] * sin_angle,
  156.         p[Y],
  157.         p[X] * sin_angle + p[Z] * cos_angle}
  158. end function
  159.  
  160. function z_rotate(point p)
  161. -- compute z rotation matrix
  162.     return {p[X] * cos_angle + p[Y] * sin_angle,
  163.         p[Y] * cos_angle - p[X] * sin_angle,
  164.         p[Z]}
  165. end function
  166.  
  167. function compute_rotate(integer axis, sequence shape)
  168. -- rotate a shape
  169.     for i = 1 to length(shape) do
  170.     for j = 1 to 2 do
  171.         if axis = X then
  172.         shape[i][j] = x_rotate(shape[i][j])
  173.         elsif axis = Y then
  174.         shape[i][j] = y_rotate(shape[i][j])
  175.         else
  176.         shape[i][j] = z_rotate(shape[i][j])
  177.         end if
  178.     end for
  179.     end for
  180.     return shape
  181. end function
  182.  
  183. -- lines a block E
  184. constant E = {
  185. {{.2, 1.1, 2}, {.2, -.5, 2}, 1},
  186. {{.2, -.5, 2}, {.2, -.5, -2}, 14},
  187. {{.2, -.5, -2}, {.2, 1.1, -2}, 2},
  188. {{.2, 1.1, -2}, {.2, 1.2, -1.6}, 12},
  189. {{.2, 1.2, -1.6}, {.2, 1, -1.8}, 12},
  190. {{.2, 1, -1.8}, {.2, 0, -1.8}, 5},
  191. {{.2, 0, -1.8}, {.2, 0, -.1}, 11},
  192. {{.2, 0, -.1}, {.2, .5, -.1}, 1},
  193. {{.2, .5, -.1}, {.2, .6, -.2}, 1},
  194. {{.2, .6, -.2}, {.2, .6, .2}, 255},
  195. {{.2, .6, .2}, {.2, .5, .1}, 1},
  196. {{.2, .5, .1}, {.2, 0, .1}, 9},
  197. {{.2, 0, .1}, {.2, 0, 1.8}, 10},
  198. {{.2, 0, 1.8}, {.2, 1, 1.8}, 11},
  199. {{.2, 1, 1.8}, {.2, 1.2, 1.6}, 11},
  200. {{.2, 1.2, 1.6}, {.2, 1.1, 2}, 12},
  201.  
  202. -- opposite side:
  203. {{-.2, 1.1, 2}, {-.2, -.5, 2}, 1},
  204. {{-.2, -.5, 2}, {-.2, -.5, -2}, 14},
  205. {{-.2, -.5, -2}, {-.2, 1.1, -2}, 2},
  206. {{-.2, 1.1, -2}, {-.2, 1.2, -1.6}, 12},
  207. {{-.2, 1.2, -1.6}, {-.2, 1, -1.8}, 12},
  208. {{-.2, 1, -1.8}, {-.2, 0, -1.8}, 5},
  209. {{-.2, 0, -1.8}, {-.2, 0, -.1}, 11},
  210. {{-.2, 0, -.1}, {-.2, .5, -.1}, 1},
  211. {{-.2, .5, -.1}, {-.2, .6, -.2}, 1},
  212. {{-.2, .6, -.2}, {-.2, .6, .2}, 255},
  213. {{-.2, .6, .2}, {-.2, .5, .1}, 1},
  214. {{-.2, .5, .1}, {-.2, 0, .1}, 9},
  215. {{-.2, 0, .1}, {-.2, 0, 1.8}, 10},
  216. {{-.2, 0, 1.8}, {-.2, 1, 1.8}, 11},
  217. {{-.2, 1, 1.8}, {-.2, 1.2, 1.6}, 11},
  218. {{-.2, 1.2, 1.6}, {-.2, 1.1, 2}, 12},
  219.  
  220. -- cross pieces:
  221. {{.2, 1.1, 2}, {-.2, 1.1, 2}, 1},
  222. {{.2, -.5, 2}, {-.2, -.5, 2}, 1},
  223. {{.2, -.5, -2}, {-.2, -.5, -2}, 2},
  224. {{.2, 1.1, -2}, {-.2, 1.1, -2}, 2},
  225. {{.2, 1.2, -1.6}, {-.2, 1.2, -1.6}, 10},
  226. {{.2, .6, -.2}, {-.2, .6, -.2}, 255},
  227. {{.2, .6, .2}, {-.2, .6, .2}, 255},
  228. {{.2, 1.2, 1.6}, {-.2, 1.2, 1.6}, 10}
  229. }
  230.  
  231. procedure spin(sequence shape)
  232. -- spin a 3-D shape around on the screen in interesting ways
  233.     sequence history, coords, overall
  234.     point view_point
  235.     integer spread, r, c
  236.     atom rot_speed
  237.  
  238.     view_point = {6, 8, 7.5} / 2.2
  239.     overall = view(view_point)
  240.     rot_speed = 0.09
  241.     sin_angle = sin(rot_speed)
  242.     cos_angle = cos(rot_speed)
  243.     axis = Z
  244.     history = {}
  245.     spread = 0
  246.     while TRUE do
  247.     coords = new_coords(overall, shape)
  248.     if length(history) > spread then
  249.         display(history[1], coords)
  250.         history = history[2..length(history)]
  251.         if length(history) > spread then
  252.         display(history[1], {})
  253.         history = history[2..length(history)]
  254.         end if
  255.     else
  256.         display({}, coords)
  257.     end if
  258.     history = append(history, coords)
  259.     c = get_key()
  260.     if c != -1 then
  261.         if c = ' ' then
  262.             while TRUE do
  263.             c = get_key()
  264.             if c != -1 and c != ' ' then
  265.                 return
  266.             elsif c = ' ' then
  267.                 exit
  268.             end if
  269.             end while
  270.         else
  271.         return
  272.         end if
  273.     end if
  274.     r = rand(250)
  275.     if r = 1 then
  276.         axis = X
  277.     elsif r = 2 then
  278.         axis = Y
  279.     elsif r = 3 then
  280.         axis = Z
  281.     elsif r = 4 then
  282.         spread = 5 * rand(25)
  283.     elsif r = 5 or r = 6 then
  284.         spread = 0
  285.     elsif r = 7 then
  286.         if rand(2) = 1 then
  287.         rot_speed = .04
  288.         spread = 0
  289.         else
  290.         rot_speed = .02 * rand(10)
  291.         end if
  292.         sin_angle = sin(rot_speed)
  293.         cos_angle = cos(rot_speed)
  294.     end if
  295.     shape = compute_rotate(axis, shape)
  296.     end while
  297. end procedure
  298.  
  299. -- execution starts here:
  300. if not select_mode(GRAPHICS_MODE) then
  301.     puts(SCREEN, "can't find a good graphics mode\n")
  302. else
  303.     vc = video_config()
  304.     bk_color(7)
  305.     text_color(5)
  306.     clear_screen()
  307.     spin(E)
  308.     bk_color(0)
  309.     if graphics_mode(-1) then
  310.     end if
  311. end if
  312.  
  313.