home *** CD-ROM | disk | FTP | other *** search
/ Media Share 9 / MEDIASHARE_09.ISO / progmisc / euphor10.zip / WIRE.EX < prev   
Text File  |  1993-06-18  |  9KB  |  337 lines

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