PageRenderTime 55ms CodeModel.GetById 27ms RepoModel.GetById 1ms app.codeStats 0ms

/brlcad/tags/rel-4-4/sig/fhor.c

https://bitbucket.org/vrrm/brl-cad-copy-for-fast-history-browsing-in-git
C | 395 lines | 263 code | 46 blank | 86 comment | 57 complexity | d51b77b7789da70881e85b3166528c1d MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, LGPL-2.1, Apache-2.0, AGPL-3.0, LGPL-3.0, GPL-3.0, MPL-2.0-no-copyleft-exception, CC-BY-SA-3.0, 0BSD, BSD-3-Clause
  1. /*
  2. * Floating horizon 3D plotting routines.
  3. *
  4. * The terminology throughout is X across, Y up, Z toward you.
  5. *
  6. * Ref: "Procedural Elements for Computer Graphics,"
  7. * D. F. Rogers.
  8. */
  9. #include "conf.h"
  10. #include <stdio.h>
  11. #include <math.h> /* XXX - temp debug */
  12. #include "machine.h"
  13. #include "fb.h"
  14. #define MYMETHOD on
  15. #define MAX(x,y) (((x)>(y))?(x):(y))
  16. #define MIN(x,y) (((x)<(y))?(x):(y))
  17. #define HSCREEN 1024 /* Max Horizontal screen resolution */
  18. #define VSCREEN 1024 /* Max Vertical screen resolution */
  19. #define INVISIBLE 0
  20. #define ABOVE 1
  21. #define BELOW -1
  22. /* Max and Min horizon holders */
  23. static int upper[HSCREEN], lower[HSCREEN];
  24. static int Xleft, Yleft, Xright, Yright; /* XXX */
  25. FBIO *fbp; /* XXX - debug */
  26. fhinit()
  27. {
  28. int i;
  29. Xleft = Yleft = Xright = Yright = -1;
  30. /* Set initial horizons */
  31. for( i = 0; i < HSCREEN; i++ ) {
  32. upper[ i ] = 0;
  33. lower[ i ] = VSCREEN;
  34. }
  35. }
  36. /*
  37. * Add another Z cut to the display.
  38. * This one goes "behind" the last one.
  39. */
  40. fhnewz( f, num )
  41. int f[], num;
  42. {
  43. int x, y, Xprev, Yprev, Xi, Yi;
  44. int Previously, Currently;
  45. /* Init previous X and Y values */
  46. Xprev = 0;
  47. Yprev = f[ 0 ];
  48. /* VIEWING XFORM */
  49. /* Fill left side */
  50. Efill( );
  51. /* Previously = fhvis( x, y ); <<< WHAT ARE X AND Y? */
  52. Previously = fhvis( Xprev, Yprev ); /* <<< WHAT ARE X AND Y? */
  53. /* Do each point in Z plane */
  54. for( x = 0; x < num; x++ ) {
  55. y = f[x];
  56. /* VIEWING XFORM */
  57. /* Check visibility and fill horizon */
  58. Currently = fhvis( x, y );
  59. if( Currently == Previously ) {
  60. if( Currently != INVISIBLE ) {
  61. /*
  62. * Current and Previous point both
  63. * visible on same side of horizon.
  64. */
  65. Draw( Xprev, Yprev, x, y );
  66. Horizon( Xprev, Yprev, x, y );
  67. }
  68. /* else both invisible */
  69. } else {
  70. /*
  71. * Visibility has changed.
  72. * Calculate intersection and fill horizon.
  73. */
  74. switch( Currently ) {
  75. case INVISIBLE:
  76. if( Previously == ABOVE )
  77. Intersect( Xprev, Yprev, x, y, upper, &Xi, &Yi );
  78. else /* previously BELOW */
  79. Intersect( Xprev, Yprev, x, y, lower, &Xi, &Yi );
  80. Draw( Xprev, Yprev, Xi, Yi );
  81. Horizon( Xprev, Yprev, Xi, Yi );
  82. break;
  83. case ABOVE:
  84. if( Previously == INVISIBLE ) {
  85. Intersect( Xprev, Yprev, x, y, lower, &Xi, &Yi );
  86. Draw( Xi, Yi, x, y );
  87. Horizon( Xi, Yi, x, y );
  88. } else { /* previously BELOW */
  89. Intersect( Xprev, Yprev, x, y, lower, &Xi, &Yi );
  90. Draw( Xprev, Yprev, Xi, Yi );
  91. Horizon( Xprev, Yprev, Xi, Yi );
  92. Intersect( Xprev, Yprev, x, y, upper, &Xi, &Yi );
  93. Draw( Xi, Yi, x, y );
  94. Horizon( Xi, Yi, x, y );
  95. }
  96. break;
  97. case BELOW:
  98. if( Previously == INVISIBLE ) {
  99. Intersect( Xprev, Yprev, x, y, lower, &Xi, &Yi );
  100. Draw( Xi, Yi, x, y );
  101. Horizon( Xi, Yi, x, y );
  102. } else { /* previously ABOVE */
  103. Intersect( Xprev, Yprev, x, y, upper, &Xi, &Yi );
  104. Draw( Xprev, Yprev, Xi, Yi );
  105. Horizon( Xprev, Yprev, Xi, Yi );
  106. Intersect( Xprev, Yprev, x, y, lower, &Xi, &Yi );
  107. Draw( Xi, Yi, x, y );
  108. Horizon( Xi, Yi, x, y );
  109. }
  110. break;
  111. }
  112. } /* end changed visibility */
  113. /*
  114. * Reset "previous" point values for next iteration.
  115. */
  116. Previously = Currently;
  117. Xprev = x;
  118. Yprev = y;
  119. }
  120. /* Fill Right Side */
  121. Efill( );
  122. }
  123. /*
  124. * INTERNAL Visibility routine.
  125. * Answers, Is Y visible at point X?
  126. *
  127. * Returns: 0 if invisible
  128. * 1 if visible above upper horizon.
  129. * -1 if visible below lower horizon.
  130. */
  131. fhvis( x, y )
  132. int x, y;
  133. {
  134. /* See if hidden behind horizons */
  135. if( y < upper[x] && y > lower[x] )
  136. return( INVISIBLE );
  137. if( y >= upper[x] )
  138. return( ABOVE );
  139. return( BELOW );
  140. }
  141. /*
  142. * INTERNAL Edge fill routine.
  143. * NOT DONE YET.
  144. */
  145. Efill()
  146. {
  147. }
  148. /*
  149. * Fill the upper and lower horizon arrays from x1 to x2
  150. * with a line spanning (x1,y1) to (x2,y2).
  151. */
  152. Horizon( x1, y1, x2, y2 )
  153. int x1, y1, x2, y2;
  154. {
  155. int xinc, x, y;
  156. double slope;
  157. xinc = sign( x2 - x1 );
  158. if( xinc == 0 ) {
  159. /* Vertical line */
  160. upper[x2] = MAX( upper[x2], y2 );
  161. lower[x2] = MIN( lower[x2], y2 );
  162. } else {
  163. slope = (y2 - y1) / (x2 - x1);
  164. for( x = x1; x <= x2; x += xinc ) {
  165. y = slope * (x - x1) + y1;
  166. upper[x] = MAX( upper[x], y );
  167. lower[x] = MIN( lower[x], y );
  168. }
  169. }
  170. }
  171. /*
  172. * Find the intersection (xi,yi) between the line (x1,y1)->(x2,y2)
  173. * and the horizon hor[].
  174. */
  175. Intersect( x1, y1, x2, y2, hor, xi, yi )
  176. int x1, y1, x2, y2;
  177. int hor[];
  178. int *xi, *yi;
  179. {
  180. int xinc, ysign, denom;
  181. int slope;
  182. /*
  183. printf("Intersect( (%3d,%3d)->(%3d,%3d) & (%3d,%3d)->(%3d,%3d) ) = ", x1, y1, x2, y2, x1, hor[x1], x2, hor[x2] );
  184. fflush( stdout );
  185. */
  186. xinc = sign( x2 - x1 );
  187. if( xinc == 0 ) {
  188. /* Vertical line */
  189. *xi = x2;
  190. *yi = hor[x2];
  191. /*printf("(vert x2=%d) ", x2);*/
  192. } else {
  193. #ifdef FOOBARBAZ
  194. denom = (hor[x2]-hor[x1])-(y2-y1);
  195. if( denom == 0 ) {
  196. /* same line! */
  197. *xi = x1;
  198. } else
  199. *xi = x1 + ((x2-x1)*(hor[x1]-y1))/denom;
  200. *yi = y1 + (*xi-x1)*((y2-y1)/(x2-x1)) + 0.5;
  201. /*printf("(%3d,%3d)\n", *xi, *yi );*/
  202. return;
  203. #endif /* FOOBARBAZ */
  204. slope = (y2 - y1) / (x2 - x1);
  205. ysign = sign( y1 - hor[x1 + xinc] );
  206. #ifdef MYMETHOD
  207. for( *xi = x1; *xi <= x2; *xi += xinc ) {
  208. *yi = y1 + (*xi-x1)*slope; /* XXX */
  209. if( sign( *yi - hor[*xi + xinc] ) != ysign )
  210. break;
  211. }
  212. if( xinc == 1 && *xi > x2 ) *xi = x2;
  213. if( xinc == -1 && *xi < x2 ) *xi = x2;
  214. #else
  215. *yi = y1;
  216. *xi = x1;
  217. while( sign( *yi - hor[*xi + xinc] ) == ysign ) {
  218. for( *xi = x1; *xi <= x2; *xi += xinc )
  219. *yi = *yi + slope; /* XXX */
  220. /*printf("[%3d,%3d]", *xi, *yi );*/
  221. }
  222. *xi = *xi + xinc;
  223. #endif /* MYMETHOD */
  224. }
  225. /*printf("(%3d,%3d)\n", *xi, *yi );*/
  226. }
  227. sign( i )
  228. int i;
  229. {
  230. if( i > 0 )
  231. return( 1 );
  232. else if( i < 0 )
  233. return( -1 );
  234. else
  235. return( 0 );
  236. }
  237. /*
  238. * DRAW - plot a line from (x1,y1) to (x2,y2)
  239. * An integer Bresenham algorithm for any quadrant.
  240. */
  241. Draw( x1, y1, x2, y2 )
  242. int x1, y1, x2, y2;
  243. {
  244. int x, y, deltx, delty, error, i;
  245. int temp, s1, s2, interchange;
  246. static RGBpixel white = { 255, 255, 255 }; /* XXX - debug */
  247. /*printf("Draw (%d %d) -> (%d %d)\n", x1, y1, x2, y2 );*/
  248. x = x1;
  249. y = y1;
  250. deltx = (x2 > x1 ? x2 - x1 : x1 - x2);
  251. delty = (y2 > y1 ? y2 - y1 : y1 - y2);
  252. s1 = sign(x2 - x1);
  253. s2 = sign(y2 - y1);
  254. /* check for swap of deltx and delty */
  255. if( delty > deltx ) {
  256. temp = deltx;
  257. deltx = delty;
  258. delty = temp;
  259. interchange = 1;
  260. } else
  261. interchange = 0;
  262. /* init error term */
  263. error = 2 * delty - deltx;
  264. for( i = 0; i < deltx; i++ ) {
  265. /* plotxy( x, y );*/
  266. /* printf( "(%3d,%3d)\n", x, y );*/
  267. fb_write( fbp, x, y, white, 1 );
  268. while( error >= 0 ) {
  269. if( interchange == 1 )
  270. x += s1;
  271. else
  272. y += s2;
  273. error -= 2 * deltx;
  274. }
  275. if( interchange == 1 )
  276. y += s2;
  277. else
  278. x += s1;
  279. error += 2 * delty;
  280. }
  281. }
  282. #ifdef SOMBRERO
  283. main()
  284. {
  285. int f[500];
  286. int x, y, z;
  287. double r;
  288. fhinit();
  289. fbp = fb_open( NULL, 512, 512 );
  290. fb_clear( fbp, PIXEL_NULL );
  291. /* Nearest to Farthest */
  292. for( z = 500; z > 0; z-- ) {
  293. /* Left to Right */
  294. for( x = 0; x < 500; x++ ) {
  295. r = (x - 250) * (x - 250) + (z - 250) * (z - 250);
  296. r = 0.10*sqrt( r ) + 0.00001;
  297. y = 250.0 * sin( r ) / r + 100.0 + (500-z)/3;
  298. f[x] = y;
  299. /* printf( "f[%3d] = %d\n", x, y );*/
  300. }
  301. fhnewz( f, 500 );
  302. }
  303. }
  304. #endif
  305. static char usage[] = "\
  306. Usage: fhor [width] < doubles\n";
  307. main( argc, argv )
  308. int argc;
  309. char **argv;
  310. {
  311. double inbuf[512];
  312. int f[512];
  313. int i, x, y, z;
  314. int size = 512;
  315. if( argc > 1 ) {
  316. size = atoi( argv[1] );
  317. }
  318. if( isatty(fileno(stdin)) ) {
  319. fprintf( stderr, usage );
  320. exit( 1 );
  321. }
  322. fhinit();
  323. fbp = fb_open( NULL, 0, 0 );
  324. fb_clear( fbp, PIXEL_NULL );
  325. bzero( (char *)f, 512*sizeof(*f) );
  326. fhnewz( f, 512 );
  327. /*
  328. * Nearest to Farthest
  329. * Here we reverse the sense of Z
  330. * (it now goes into the screen).
  331. */
  332. z = 0;
  333. while( fread( inbuf, sizeof(*inbuf), size, stdin ) != 0 ) {
  334. /* Left to Right */
  335. /*bzero( (char *)f, 512*sizeof(*f) );*/
  336. for( i = 0; i < 512; i++ ) {
  337. f[i] = 4*z; /* up 4 for every z back */
  338. }
  339. for( i = 0; i < size; i++ ) {
  340. x = i + 2*z; /* right 2 for every z back */
  341. if( x >= 0 && x < 512 ) {
  342. f[x] += 128 * inbuf[i];
  343. }
  344. /*printf( "f[%3d] = %d\n", x, y );*/
  345. }
  346. fhnewz( f, 512 );
  347. z++;
  348. }
  349. }