home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format 19 / af019.adf / MOSAIC_TEXT < prev    next >
Text File  |  1978-04-04  |  6KB  |  239 lines

  1. Submission Ref: A374/1-1                Author: PAUL OVERAA
  2.  
  3. Title:          Mosaic Transfer
  4.  
  5. Copy Date:      4th November 1990
  6.  
  7.  
  8.             ------------------------------------------------
  9.             Paul Overaa describes a trick that's useful for 
  10.             creating random mosaic fades and copy effects... 
  11.             ------------------------------------------------
  12.  
  13.  
  14. I've got to admit at the outset that my heart is not really into
  15. graphics programming. The underlying theoretical stuff is interesting but,
  16. in practice, it all seems to get a bit too 'dirty' and machine dependent 
  17. for my liking. With high-speed processors you can do things cleanly, but 
  18. on most 16 bit computers you're forever having to cut corners to keep 
  19. the speed up.
  20.  
  21. Occasionally however I get attracted by the odd graphics problem and 
  22. such is the case with this month's little excursion...
  23.  
  24. You've no doubt seen those TV effects where the picture breaks into 
  25. hundreds of small squares which are then randomly disintegrated, faded 
  26. or otherwise modified.  These 'mosaic' rearrangements aren't too difficult 
  27. to do and, since I've been playing around with a few ideas in this area,  
  28. I thought it might be a useful topic to look at. 
  29.  
  30. Let's suppose then that we consider a rectangular 'source' area of the 
  31. screen as being broken into an unspecified number of smaller rectangular 
  32. blocks. It seems reasonable to identify these blocks by some co-ordinate
  33. scheme and I've opted for using the top left co-ordinates in all cases.
  34.  
  35. If we do this it becomes possible  to create a nice simple model whereby 
  36. identified screen blocks such as...
  37.  
  38.  
  39.  
  40.  
  41.  
  42.  
  43. *------*------*-----.... etc 
  44. |      |      |
  45. *------*------*--
  46. |      |      |
  47. *------*---
  48. |      |
  49. *---
  50. .
  51. .
  52. .
  53. etc.
  54.  
  55.  
  56.  
  57. are represented just by their virtual top-left co-ordinates...
  58.  
  59.  
  60.  
  61.  
  62. *      *      * .... etc.                       (0,0)   (1,0)   (2,0)... etc.
  63.  
  64. *      *      *                                 (0,1)   (1,1)   (2,1)
  65.                       <--- top left points
  66. *      *                   are stored as        (0,2)   (1,2)
  67.        .                   the array  --->
  68. *      .                                        (0,3)... etc.
  69. .      .
  70.                                                         
  71. etc.                                             
  72.  
  73.  
  74.  
  75.  
  76. In other words we can describe the locations of all of the blocks in a 
  77. mosaic pattern by an array containing the (x,y) block number co-ordinates. 
  78. Rather than use a two dimensional array I will, in the following discussion, 
  79. be using separate x and y vectors. There's no real difference as far as 
  80. coding complexity goes, but the vector approach does make the explanations 
  81. a little easier to understand.
  82.  
  83. Essentially the problems we're solving are these:
  84.  
  85. Firstly we want to find a way of generating a random, or apparently random, 
  86. set of block (x,y) co-ordinates without eating into too much memory (ie 
  87. without building lists of every possible co-ordinate pair).
  88.  
  89. Secondly we want a way of accessing these co-ordinates using a mechanism 
  90. which ensures that, after the 'random' operations have been completed, 
  91. every co-ordinate pair will have been used.
  92.  
  93. One obvious way to ensure that every mosaic block would be used is to
  94. use a twin loop like this...
  95.  
  96.  
  97. for (x=0; x<XMAX; x++)
  98.  
  99.    {
  100.            
  101.          for (y=0; y<YMAX; y++)
  102.          
  103.          {
  104.          
  105.           do something with block (x,y)
  106.          
  107.           eg copy block (x,y) to location (x+offset_X, y+offset_Y) 
  108.  
  109.          }
  110.          
  111.    }
  112.  
  113.  
  114.  
  115. This moves all of the blocks but it does so in a uniform way. What we 
  116. want is some way of randomizing the x and y co-ordinates. To start with 
  117. let's assume that we have a mosaic block 'vertical_block_count' blocks 
  118. high and 'horizontal_block_count' blocks wide. We can create a random, but 
  119. complete, list of vertical co-ordinates by initializing and rearranging 
  120. the values like this...
  121.  
  122.  
  123. for (n=0; n<vertical_block_count; n++) { yvector[n]=n; }
  124.  
  125. for (n=0; n<vertical_block_count; n++)
  126.  
  127. {
  128.  
  129. r=rand() % vertical_block_count; 
  130.  
  131. d=yvector[n]; 
  132.  
  133. yvector[n]=yvector[r]; 
  134.  
  135. yvector[r]=d;
  136.  
  137. }
  138.  
  139. Now we carry out a similar operation (based incidentally on a mathematically 
  140. sound mod co-ordinate offset relationship) on the horizontal co-ordinate 
  141. set...
  142.  
  143.  
  144. for (n=0; n<horizontal_block_count; n++) 
  145.  
  146. {
  147.  
  148. xvector[n] = rand() % horizontal_block_count; 
  149.  
  150. n_rand[n] = n;
  151.  
  152. }
  153.  
  154. for (n=0; n<horizontal_block_count; n++)
  155.  
  156. {
  157.  
  158. r=rand() % horizontal_block_count; 
  159.  
  160. d=n_rand[n]; 
  161.  
  162. n_rand[n]=n_rand[r]; 
  163.  
  164. n_rand[r]=d;
  165.  
  166. }
  167.  
  168.  
  169. With that done the only thing needed now is to use a standard twin loop 
  170. arrangement to read the jumbled up block co-ordinates. 
  171.  
  172. Here's some example code for handling the calculations and data transfer.
  173. Firstly the block co-ordinates are calculated, secondly they are converted 
  174. to real screen locations, finally the base addresses of the source and 
  175. target areas are added to provide the co-ordinates which are going to be 
  176. used.  I've used a couple of system calls BltBitMap() and RectFill() 
  177. to move the data but obviously how you use the final co-ordinates depends
  178. on what you're wishing to do. 
  179.  
  180. Normally a lot of the operations shown in the following piece of code 
  181. would be coded together but, for clarity, I've written them so that the 
  182. individual stages are distinguishable...
  183.  
  184.  
  185. for (m=0; m<vertical_block_count; m++)
  186.  
  187.    {
  188.         
  189.     for (n=0; n<horizontal_block_count; n++)
  190.  
  191.       {
  192.     
  193.        /* calculate the block co-ordinates... */
  194.  
  195.        target_x=source_x = n_rand[n];
  196.            
  197.        target_y=source_y = ((yvector[m] + xvector[n]) % vertical_block_count);
  198.  
  199.  
  200.        /* now translate to real screen co-ordinates... */
  201.  
  202.        target_x=source_x*=pixel_block_width; 
  203.         
  204.        target_y=source_y*=pixel_block_height;
  205.                
  206.        
  207.        /* add the base addresses and move the data... */
  208.  
  209.        source_x+=x_source_base;
  210.        
  211.        source_y+=y_source_base;
  212.        
  213.        target_x+=x_target_base;
  214.        
  215.        target_y+=y_target_base;
  216.   
  217.        BltBitMap(global_rastport_p->BitMap, source_x, source_y,
  218.                  global_rastport_p->BitMap, target_x, target_y,
  219.                  pixel_block_width, pixel_block_height, 0x30, 0xFF);
  220.  
  221.         RectFill(global_rastport_p,source_x,source_y,
  222.         source_x+pixel_block_width-1,source_y+pixel_block_height-1);  
  223.          
  224.  
  225.        }
  226.  
  227.    }
  228.  
  229.  
  230.  
  231.  
  232. You will find a WorkBench/CLI runable example, together with the source 
  233. code, in the 'mosaic' folder of the cover disk. 
  234.  
  235.  
  236.  
  237.  
  238.  
  239.