Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

489 lines
12 KiB

  1. /**************************************************************************
  2. * *
  3. * Copyright (C) 1992, Silicon Graphics, Inc. *
  4. * *
  5. * These coded instructions, statements, and computer programs contain *
  6. * unpublished proprietary information of Silicon Graphics, Inc., and *
  7. * are protected by Federal copyright law. They may not be disclosed *
  8. * to third parties or copied or duplicated in any form, in whole or *
  9. * in part, without the prior written consent of Silicon Graphics, Inc. *
  10. * *
  11. **************************************************************************/
  12. /*
  13. * ccw.c++ - $Revision: 1.1 $
  14. * Derrick Burns - 1991
  15. */
  16. #include "glimport.h"
  17. #include "mystdio.h"
  18. #include "myassert.h"
  19. #include "subdivid.h"
  20. #include "types.h"
  21. #include "arc.h"
  22. #include "trimvert.h"
  23. #include "simplema.h"
  24. inline int
  25. Subdivider::bbox( TrimVertex *a, TrimVertex *b, TrimVertex *c, int p )
  26. {
  27. return bbox( a->param[p], b->param[p], c->param[p],
  28. a->param[1-p], b->param[1-p], c->param[1-p] );
  29. }
  30. int
  31. Subdivider::ccwTurn_sr( Arc_ptr j1, Arc_ptr j2 ) // dir = 1
  32. {
  33. register TrimVertex *v1 = &j1->pwlArc->pts[j1->pwlArc->npts-1];
  34. register TrimVertex *v1last = &j1->pwlArc->pts[0];
  35. register TrimVertex *v2 = &j2->pwlArc->pts[0];
  36. register TrimVertex *v2last = &j2->pwlArc->pts[j2->pwlArc->npts-1];
  37. register TrimVertex *v1next = v1-1;
  38. register TrimVertex *v2next = v2+1;
  39. int sgn;
  40. assert( v1 != v1last );
  41. assert( v2 != v2last );
  42. #ifndef NDEBUG
  43. dprintf( "arc_ccw_turn, p = %d\n", 0 );
  44. #endif
  45. // the arcs lie on the line (0 == v1->param[0])
  46. if( v1->param[0] == v1next->param[0] && v2->param[0] == v2next->param[0] )
  47. return 0;
  48. if( v2next->param[0] < v2->param[0] || v1next->param[0] < v1->param[0] )
  49. ::mylongjmp( jumpbuffer, 28 );
  50. if( v1->param[1] < v2->param[1] )
  51. return 0;
  52. else if( v1->param[1] > v2->param[1] )
  53. return 1;
  54. while( 1 ) {
  55. if( v1next->param[0] < v2next->param[0] ) {
  56. #ifndef NDEBUG
  57. dprintf( "case a\n" );
  58. #endif
  59. assert( v1->param[0] <= v1next->param[0] );
  60. assert( v2->param[0] <= v1next->param[0] );
  61. switch( bbox( v2, v2next, v1next, 1 ) ) {
  62. case -1:
  63. return 0;
  64. case 0:
  65. sgn = ccw( v1next, v2, v2next );
  66. if( sgn != -1 ) {
  67. return sgn;
  68. } else {
  69. dprintf( "decr\n" );
  70. v1 = v1next--;
  71. if( v1 == v1last ) {
  72. dprintf( "no good results\n" );
  73. return 0; // ill-conditioned, guess answer
  74. }
  75. }
  76. break;
  77. case 1:
  78. return 1;
  79. }
  80. } else if( v1next->param[0] > v2next->param[0] ) {
  81. #ifndef NDEBUG
  82. dprintf( "case b\n" );
  83. #endif
  84. assert( v1->param[0] <= v2next->param[0] );
  85. assert( v2->param[0] <= v2next->param[0] );
  86. switch( bbox( v1, v1next, v2next, 1 ) ) {
  87. case -1:
  88. return 1;
  89. case 0:
  90. sgn = ccw( v1next, v1, v2next );
  91. if( sgn != -1 ) {
  92. return sgn;
  93. } else {
  94. dprintf( "incr\n" );
  95. v2 = v2next++;
  96. if( v2 == v2last ) {
  97. dprintf( "no good results\n" );
  98. return 0; // ill-conditioned, guess answer
  99. }
  100. }
  101. break;
  102. case 1:
  103. return 0;
  104. }
  105. } else {
  106. #ifndef NDEBUG
  107. dprintf( "case ab\n" );
  108. #endif
  109. if( v1next->param[1] < v2next->param[1] )
  110. return 0;
  111. else if( v1next->param[1] > v2next->param[1] )
  112. return 1;
  113. else {
  114. dprintf( "incr\n" );
  115. v2 = v2next++;
  116. if( v2 == v2last ) {
  117. dprintf( "no good results\n" );
  118. return 0; // ill-conditioned, guess answer
  119. }
  120. }
  121. }
  122. }
  123. }
  124. int
  125. Subdivider::ccwTurn_sl( Arc_ptr j1, Arc_ptr j2 ) // dir = 0
  126. {
  127. register TrimVertex *v1 = &j1->pwlArc->pts[j1->pwlArc->npts-1];
  128. register TrimVertex *v1last = &j1->pwlArc->pts[0];
  129. register TrimVertex *v2 = &j2->pwlArc->pts[0];
  130. register TrimVertex *v2last = &j2->pwlArc->pts[j2->pwlArc->npts-1];
  131. register TrimVertex *v1next = v1-1;
  132. register TrimVertex *v2next = v2+1;
  133. int sgn;
  134. assert( v1 != v1last );
  135. assert( v2 != v2last );
  136. #ifndef NDEBUG
  137. dprintf( "arc_ccw_turn, p = %d\n", 0 );
  138. #endif
  139. // the arcs lie on the line (0 == v1->param[0])
  140. if( v1->param[0] == v1next->param[0] && v2->param[0] == v2next->param[0] )
  141. return 0;
  142. if( v2next->param[0] > v2->param[0] || v1next->param[0] > v1->param[0] )
  143. ::mylongjmp( jumpbuffer, 28 );
  144. if( v1->param[1] < v2->param[1] )
  145. return 1;
  146. else if( v1->param[1] > v2->param[1] )
  147. return 0;
  148. while( 1 ) {
  149. if( v1next->param[0] > v2next->param[0] ) {
  150. #ifndef NDEBUG
  151. dprintf( "case c\n" );
  152. #endif
  153. assert( v1->param[0] >= v1next->param[0] );
  154. assert( v2->param[0] >= v1next->param[0] );
  155. switch( bbox( v2next, v2, v1next, 1 ) ) {
  156. case -1:
  157. return 1;
  158. case 0:
  159. sgn = ccw( v1next, v2, v2next );
  160. if( sgn != -1 )
  161. return sgn;
  162. else {
  163. v1 = v1next--;
  164. dprintf( "decr\n" );
  165. if( v1 == v1last ) {
  166. dprintf( "no good results\n" );
  167. return 0; // ill-conditioned, guess answer
  168. }
  169. }
  170. break;
  171. case 1:
  172. return 0;
  173. }
  174. } else if( v1next->param[0] < v2next->param[0] ) {
  175. #ifndef NDEBUG
  176. dprintf( "case d\n" );
  177. #endif
  178. assert( v1->param[0] >= v2next->param[0] );
  179. assert( v2->param[0] >= v2next->param[0] );
  180. switch( bbox( v1next, v1, v2next, 1 ) ) {
  181. case -1:
  182. return 0;
  183. case 0:
  184. sgn = ccw( v1next, v1, v2next );
  185. if( sgn != -1 )
  186. return sgn;
  187. else {
  188. v2 = v2next++;
  189. dprintf( "incr\n" );
  190. if( v2 == v2last ) {
  191. dprintf( "no good results\n" );
  192. return 0; // ill-conditioned, guess answer
  193. }
  194. }
  195. break;
  196. case 1:
  197. return 1;
  198. }
  199. } else {
  200. dprintf( "case cd\n" );
  201. if( v1next->param[1] < v2next->param[1] )
  202. return 1;
  203. else if( v1next->param[1] > v2next->param[1] )
  204. return 0;
  205. else {
  206. v2 = v2next++;
  207. dprintf( "incr\n" );
  208. if( v2 == v2last ) {
  209. dprintf( "no good results\n" );
  210. return 0; // ill-conditioned, guess answer
  211. }
  212. }
  213. }
  214. }
  215. }
  216. int
  217. Subdivider::ccwTurn_tr( Arc_ptr j1, Arc_ptr j2 ) // dir = 1
  218. {
  219. register TrimVertex *v1 = &j1->pwlArc->pts[j1->pwlArc->npts-1];
  220. register TrimVertex *v1last = &j1->pwlArc->pts[0];
  221. register TrimVertex *v2 = &j2->pwlArc->pts[0];
  222. register TrimVertex *v2last = &j2->pwlArc->pts[j2->pwlArc->npts-1];
  223. register TrimVertex *v1next = v1-1;
  224. register TrimVertex *v2next = v2+1;
  225. int sgn;
  226. assert( v1 != v1last );
  227. assert( v2 != v2last );
  228. #ifndef NDEBUG
  229. dprintf( "arc_ccw_turn, p = %d\n", 1 );
  230. #endif
  231. // the arcs lie on the line (1 == v1->param[1])
  232. if( v1->param[1] == v1next->param[1] && v2->param[1] == v2next->param[1] )
  233. return 0;
  234. if( v2next->param[1] < v2->param[1] || v1next->param[1] < v1->param[1] )
  235. ::mylongjmp( jumpbuffer, 28 );
  236. if( v1->param[0] < v2->param[0] )
  237. return 1;
  238. else if( v1->param[0] > v2->param[0] )
  239. return 0;
  240. while( 1 ) {
  241. if( v1next->param[1] < v2next->param[1] ) {
  242. #ifndef NDEBUG
  243. dprintf( "case a\n" );
  244. #endif
  245. assert( v1->param[1] <= v1next->param[1] );
  246. assert( v2->param[1] <= v1next->param[1] );
  247. switch( bbox( v2, v2next, v1next, 0 ) ) {
  248. case -1:
  249. return 1;
  250. case 0:
  251. sgn = ccw( v1next, v2, v2next );
  252. if( sgn != -1 ) {
  253. return sgn;
  254. } else {
  255. dprintf( "decr\n" );
  256. v1 = v1next--;
  257. if( v1 == v1last ) {
  258. dprintf( "no good results\n" );
  259. return 0; // ill-conditioned, guess answer
  260. }
  261. }
  262. break;
  263. case 1:
  264. return 0;
  265. }
  266. } else if( v1next->param[1] > v2next->param[1] ) {
  267. #ifndef NDEBUG
  268. dprintf( "case b\n" );
  269. #endif
  270. assert( v1->param[1] <= v2next->param[1] );
  271. assert( v2->param[1] <= v2next->param[1] );
  272. switch( bbox( v1, v1next, v2next, 0 ) ) {
  273. case -1:
  274. return 0;
  275. case 0:
  276. sgn = ccw( v1next, v1, v2next );
  277. if( sgn != -1 ) {
  278. return sgn;
  279. } else {
  280. dprintf( "incr\n" );
  281. v2 = v2next++;
  282. if( v2 == v2last ) {
  283. dprintf( "no good results\n" );
  284. return 0; // ill-conditioned, guess answer
  285. }
  286. }
  287. break;
  288. case 1:
  289. return 1;
  290. }
  291. } else {
  292. dprintf( "case ab\n" );
  293. if( v1next->param[0] < v2next->param[0] )
  294. return 1;
  295. else if( v1next->param[0] > v2next->param[0] )
  296. return 0;
  297. else {
  298. dprintf( "incr\n" );
  299. v2 = v2next++;
  300. if( v2 == v2last ) {
  301. dprintf( "no good results\n" );
  302. return 0; // ill-conditioned, guess answer
  303. }
  304. }
  305. }
  306. }
  307. }
  308. int
  309. Subdivider::ccwTurn_tl( Arc_ptr j1, Arc_ptr j2 )
  310. {
  311. register TrimVertex *v1 = &j1->pwlArc->pts[j1->pwlArc->npts-1];
  312. register TrimVertex *v1last = &j1->pwlArc->pts[0];
  313. register TrimVertex *v2 = &j2->pwlArc->pts[0];
  314. register TrimVertex *v2last = &j2->pwlArc->pts[j2->pwlArc->npts-1];
  315. register TrimVertex *v1next = v1-1;
  316. register TrimVertex *v2next = v2+1;
  317. int sgn;
  318. assert( v1 != v1last );
  319. assert( v2 != v2last );
  320. #ifndef NDEBUG
  321. dprintf( "arc_ccw_turn, p = %d\n", 1 );
  322. #endif
  323. // the arcs lie on the line (1 == v1->param[1])
  324. if( v1->param[1] == v1next->param[1] && v2->param[1] == v2next->param[1] )
  325. return 0;
  326. if( v2next->param[1] > v2->param[1] || v1next->param[1] > v1->param[1] )
  327. ::mylongjmp( jumpbuffer, 28 );
  328. if( v1->param[0] < v2->param[0] )
  329. return 0;
  330. else if( v1->param[0] > v2->param[0] )
  331. return 1;
  332. while( 1 ) {
  333. if( v1next->param[1] > v2next->param[1] ) {
  334. #ifndef NDEBUG
  335. dprintf( "case c\n" );
  336. #endif
  337. assert( v1->param[1] >= v1next->param[1] );
  338. assert( v2->param[1] >= v1next->param[1] );
  339. switch( bbox( v2next, v2, v1next, 0 ) ) {
  340. case -1:
  341. return 0;
  342. case 0:
  343. sgn = ccw( v1next, v2, v2next );
  344. if( sgn != -1 )
  345. return sgn;
  346. else {
  347. v1 = v1next--;
  348. dprintf( "decr\n" );
  349. if( v1 == v1last ) {
  350. dprintf( "no good results\n" );
  351. return 0; // ill-conditioned, guess answer
  352. }
  353. }
  354. break;
  355. case 1:
  356. return 1;
  357. }
  358. } else if( v1next->param[1] < v2next->param[1] ) {
  359. #ifndef NDEBUG
  360. dprintf( "case d\n" );
  361. assert( v1->param[1] >= v2next->param[1] );
  362. assert( v2->param[1] >= v2next->param[1] );
  363. #endif
  364. switch( bbox( v1next, v1, v2next, 0 ) ) {
  365. case -1:
  366. return 1;
  367. case 0:
  368. sgn = ccw( v1next, v1, v2next );
  369. if( sgn != -1 )
  370. return sgn;
  371. else {
  372. v2 = v2next++;
  373. dprintf( "incr\n" );
  374. if( v2 == v2last ) {
  375. dprintf( "no good results\n" );
  376. return 0; // ill-conditioned, guess answer
  377. }
  378. }
  379. break;
  380. case 1:
  381. return 0;
  382. }
  383. } else {
  384. dprintf( "case cd\n" );
  385. if( v1next->param[0] < v2next->param[0] )
  386. return 0;
  387. else if( v1next->param[0] > v2next->param[0] )
  388. return 1;
  389. else {
  390. v2 = v2next++;
  391. dprintf( "incr\n" );
  392. if( v2 == v2last ) {
  393. dprintf( "no good results\n" );
  394. return 0; // ill-conditioned, guess answer
  395. }
  396. }
  397. }
  398. }
  399. }
  400. #ifndef NDEBUG
  401. int
  402. Subdivider::bbox( register REAL sa, register REAL sb, register REAL sc,
  403. register REAL ta, register REAL tb, register REAL tc )
  404. #else
  405. int
  406. Subdivider::bbox( register REAL sa, register REAL sb, register REAL sc,
  407. register REAL , register REAL , register REAL )
  408. #endif
  409. {
  410. #ifndef NDEBUG
  411. assert( tc >= ta );
  412. assert( tc <= tb );
  413. #endif
  414. if( sa < sb ) {
  415. if( sc <= sa ) {
  416. return -1;
  417. } else if( sb <= sc ) {
  418. return 1;
  419. } else {
  420. return 0;
  421. }
  422. } else if( sa > sb ) {
  423. if( sc >= sa ) {
  424. return 1;
  425. } else if( sb >= sc ) {
  426. return -1;
  427. } else {
  428. return 0;
  429. }
  430. } else {
  431. if( sc > sa ) {
  432. return 1;
  433. } else if( sb > sc ) {
  434. return -1;
  435. } else {
  436. return 0;
  437. }
  438. }
  439. }
  440. /*----------------------------------------------------------------------------
  441. * ccw - determine how three points are oriented by computing their
  442. * determinant.
  443. * Return 1 if the vertices are ccw oriented,
  444. * 0 if they are cw oriented, or
  445. * -1 if the computation is ill-conditioned.
  446. *----------------------------------------------------------------------------
  447. */
  448. int
  449. Subdivider::ccw( TrimVertex *a, TrimVertex *b, TrimVertex *c )
  450. {
  451. REAL d = det3( a, b, c );
  452. if( abs(d) < 0.0001 ) return -1;
  453. return (d < 0.0) ? 0 : 1;
  454. }