Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > DoxygenpolyDBG.cc
Go to the documentation of this file.
00001 /* 00002 ** License Applicability. Except to the extent portions of this file are 00003 ** made subject to an alternative license as permitted in the SGI Free 00004 ** Software License B, Version 1.1 (the "License"), the contents of this 00005 ** file are subject only to the provisions of the License. You may not use 00006 ** this file except in compliance with the License. You may obtain a copy 00007 ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 00008 ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: 00009 ** 00010 ** http://oss.sgi.com/projects/FreeB 00011 ** 00012 ** Note that, as provided in the License, the Software is distributed on an 00013 ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS 00014 ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND 00015 ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A 00016 ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. 00017 ** 00018 ** Original Code. The Original Code is: OpenGL Sample Implementation, 00019 ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, 00020 ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. 00021 ** Copyright in any portions created by third parties is as indicated 00022 ** elsewhere herein. All Rights Reserved. 00023 ** 00024 ** Additional Notice Provisions: The application programming interfaces 00025 ** established by SGI in conjunction with the Original Code are The 00026 ** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released 00027 ** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version 00028 ** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X 00029 ** Window System(R) (Version 1.3), released October 19, 1998. This software 00030 ** was created using the OpenGL(R) version 1.2.1 Sample Implementation 00031 ** published by SGI, but has not been independently verified as being 00032 ** compliant with the OpenGL(R) version 1.2.1 Specification. 00033 ** 00034 */ 00035 /* 00036 */ 00037 00038 #include <stdlib.h> 00039 #include <stdio.h> 00040 #include <math.h> 00041 #include "zlassert.h" 00042 #include "polyDBG.h" 00043 00044 #ifdef __WATCOMC__ 00045 #pragma warning 14 10 00046 #pragma warning 391 10 00047 #pragma warning 726 10 00048 #endif 00049 00050 static Real area(Real A[2], Real B[2], Real C[2]) 00051 { 00052 Real Bx, By, Cx, Cy; 00053 Bx = B[0] - A[0]; 00054 By = B[1] - A[1]; 00055 Cx = C[0] - A[0]; 00056 Cy = C[1] - A[1]; 00057 return Bx*Cy - Cx*By; 00058 } 00059 00060 Int DBG_isConvex(directedLine *poly) 00061 { 00062 directedLine* temp; 00063 if(area(poly->head(), poly->tail(), poly->getNext()->tail()) < 0.00000) 00064 return 0; 00065 for(temp = poly->getNext(); temp != poly; temp = temp->getNext()) 00066 { 00067 if(area(temp->head(), temp->tail(), temp->getNext()->tail()) < 0.00000) 00068 return 0; 00069 } 00070 return 1; 00071 } 00072 00073 Int DBG_is_U_monotone(directedLine* poly) 00074 { 00075 Int n_changes = 0; 00076 Int prev_sign; 00077 Int cur_sign; 00078 directedLine* temp; 00079 cur_sign = compV2InX(poly->tail(), poly->head()); 00080 00081 n_changes = (compV2InX(poly->getPrev()->tail(), poly->getPrev()->head()) 00082 != cur_sign); 00083 00084 for(temp = poly->getNext(); temp != poly; temp = temp->getNext()) 00085 { 00086 prev_sign = cur_sign; 00087 cur_sign = compV2InX(temp->tail(), temp->head()); 00088 00089 if(cur_sign != prev_sign) 00090 n_changes++; 00091 } 00092 00093 if(n_changes ==2) return 1; 00094 else return 0; 00095 } 00096 00097 /*if u-monotone, and there is a long horizontal edge*/ 00098 Int DBG_is_U_direction(directedLine* poly) 00099 { 00100 /* 00101 if(! DBG_is_U_monotone(poly)) 00102 return 0; 00103 */ 00104 Int V_count = 0; 00105 Int U_count = 0; 00106 directedLine* temp; 00107 if( fabs(poly->head()[0] - poly->tail()[0]) <= fabs(poly->head()[1]-poly->tail()[1])) 00108 V_count += poly->get_npoints(); 00109 else 00110 U_count += poly->get_npoints(); 00111 /* 00112 else if(poly->head()[1] == poly->tail()[1]) 00113 U_count += poly->get_npoints(); 00114 */ 00115 for(temp = poly->getNext(); temp != poly; temp = temp->getNext()) 00116 { 00117 if( fabs(temp->head()[0] - temp->tail()[0]) <= fabs(temp->head()[1]-temp->tail()[1])) 00118 V_count += temp->get_npoints(); 00119 else 00120 U_count += temp->get_npoints(); 00121 /* 00122 if(temp->head()[0] == temp->tail()[0]) 00123 V_count += temp->get_npoints(); 00124 else if(temp->head()[1] == temp->tail()[1]) 00125 U_count += temp->get_npoints(); 00126 */ 00127 } 00128 00129 if(U_count > V_count) return 1; 00130 else return 0; 00131 } 00132 00133 /*given two line segments, determine whether 00134 *they intersect each other or not. 00135 *return 1 if they do, 00136 *return 0 otherwise 00137 */ 00138 Int DBG_edgesIntersect(directedLine* l1, directedLine* l2) 00139 { 00140 if(l1->getNext() == l2) 00141 { 00142 if(area(l1->head(), l1->tail(), l2->tail()) == 0) //colinear 00143 { 00144 if( (l1->tail()[0] - l1->head()[0])*(l2->tail()[0]-l2->head()[0]) + 00145 (l1->tail()[1] - l1->head()[1])*(l2->tail()[1]-l2->head()[1]) >=0) 00146 return 0; //not intersect 00147 else 00148 return 1; 00149 } 00150 //else we use the normal code 00151 } 00152 else if(l1->getPrev() == l2) 00153 { 00154 if(area(l2->head(), l2->tail(), l1->tail()) == 0) //colinear 00155 { 00156 if( (l2->tail()[0] - l2->head()[0])*(l1->tail()[0]-l1->head()[0]) + 00157 (l2->tail()[1] - l2->head()[1])*(l1->tail()[1]-l1->head()[1]) >=0) 00158 return 0; //not intersect 00159 else 00160 return 1; 00161 } 00162 //else we use the normal code 00163 } 00164 else //the two edges are not connected 00165 { 00166 if((l1->head()[0] == l2->head()[0] && 00167 l1->head()[1] == l2->head()[1]) || 00168 (l1->tail()[0] == l2->tail()[0] && 00169 l1->tail()[1] == l2->tail()[1])) 00170 return 1; 00171 00172 } 00173 00174 00175 if( 00176 ( 00177 area(l1->head(), l1->tail(), l2->head()) 00178 * 00179 area(l1->head(), l1->tail(), l2->tail()) 00180 < 0 00181 ) 00182 && 00183 ( 00184 area(l2->head(), l2->tail(), l1->head()) 00185 *area(l2->head(), l2->tail(), l1->tail()) 00186 < 0 00187 ) 00188 ) 00189 return 1; 00190 else 00191 return 0; 00192 } 00193 00194 /*whether AB and CD intersect 00195 *return 1 if they do 00196 *retur 0 otheriwse 00197 */ 00198 Int DBG_edgesIntersectGen(Real A[2], Real B[2], Real C[2], Real D[2]) 00199 { 00200 if( 00201 ( 00202 area(A, B, C) * area(A,B,D) <0 00203 ) 00204 && 00205 ( 00206 area(C,D,A) * area(C,D,B) < 0 00207 ) 00208 ) 00209 return 1; 00210 else 00211 return 0; 00212 } 00213 00214 /*determien whether (A,B) interesect chain[start] to [end] 00215 */ 00216 Int DBG_intersectChain(vertexArray* chain, Int start, Int end, Real A[2], Real B[2]) 00217 { 00218 Int i; 00219 for(i=start; i<=end-2; i++) 00220 if(DBG_edgesIntersectGen(chain->getVertex(i), chain->getVertex(i+1), A, B)) 00221 return 1; 00222 00223 return 0; 00224 } 00225 00226 /*determine whether a polygon intersect itself or not 00227 *return 1 is it does, 00228 * 0 otherwise 00229 */ 00230 Int DBG_polygonSelfIntersect(directedLine* poly) 00231 { 00232 directedLine* temp1; 00233 directedLine* temp2; 00234 temp1=poly; 00235 for(temp2=temp1->getNext(); temp2 != temp1; temp2=temp2->getNext()) 00236 { 00237 if(DBG_edgesIntersect(temp1, temp2)) 00238 { 00239 return 1; 00240 } 00241 00242 } 00243 00244 for(temp1=poly->getNext(); temp1 != poly; temp1 = temp1->getNext()) 00245 for(temp2=temp1->getNext(); temp2 != temp1; temp2=temp2->getNext()) 00246 { 00247 if(DBG_edgesIntersect(temp1, temp2)) 00248 { 00249 return 1; 00250 } 00251 } 00252 return 0; 00253 } 00254 00255 /*check whether a line segment intersects a polygon 00256 */ 00257 Int DBG_edgeIntersectPoly(directedLine* edge, directedLine* poly) 00258 { 00259 directedLine* temp; 00260 if(DBG_edgesIntersect(edge, poly)) 00261 return 1; 00262 for(temp=poly->getNext(); temp != poly; temp=temp->getNext()) 00263 if(DBG_edgesIntersect(edge, temp)) 00264 return 1; 00265 return 0; 00266 } 00267 00268 /*check whether two polygons intersect 00269 */ 00270 Int DBG_polygonsIntersect(directedLine* p1, directedLine* p2) 00271 { 00272 directedLine* temp; 00273 if(DBG_edgeIntersectPoly(p1, p2)) 00274 return 1; 00275 for(temp=p1->getNext(); temp!= p1; temp = temp->getNext()) 00276 if(DBG_edgeIntersectPoly(temp, p2)) 00277 return 1; 00278 return 0; 00279 } 00280 00281 /*check whether there are polygons intersecting each other in 00282 *a list of polygons 00283 */ 00284 Int DBG_polygonListIntersect(directedLine* pList) 00285 { 00286 directedLine *temp; 00287 for(temp=pList; temp != NULL; temp = temp->getNextPolygon()) 00288 if(DBG_polygonSelfIntersect(temp)) 00289 return 1; 00290 directedLine* temp2; 00291 for(temp=pList; temp!=NULL; temp=temp->getNextPolygon()) 00292 { 00293 for(temp2=temp->getNextPolygon(); temp2 != NULL; temp2=temp2->getNextPolygon()) 00294 if(DBG_polygonsIntersect(temp, temp2)) 00295 return 1; 00296 } 00297 00298 return 0; 00299 } 00300 00301 00302 Int DBG_isCounterclockwise(directedLine* poly) 00303 { 00304 return (poly->polyArea() > 0); 00305 } 00306 00307 /*ray: v0 with direction (dx,dy). 00308 *edge: v1-v2. 00309 * the extra point v10[2] is given for the information at 00310 *v1. Basically this edge is connectd to edge 00311 * v10-v1. If v1 is on the ray, 00312 * then we need v10 to determine whether this ray intersects 00313 * the edge or not (that is, return 1 or return 0). 00314 * If v1 is on the ray, then if v2 and v10 are on the same side of the ray, 00315 * we return 0, otherwise return 1. 00316 *For v2, if v2 is on the ray, we always return 0. 00317 *Notice that v1 and v2 are not symmetric. So the edge is directed!!! 00318 * The purpose for this convention is such that: a point is inside a polygon 00319 * if and only if it intersets with odd number of edges. 00320 */ 00321 Int DBG_rayIntersectEdge(Real v0[2], Real dx, Real dy, Real v10[2], Real v1[2], Real v2[2]) 00322 { 00323 /* 00324 if( (v1[1] >= v0[1] && v2[1]<= v0[1] ) 00325 ||(v2[1] >= v0[1] && v1[1]<= v0[1] ) 00326 ) 00327 printf("rayIntersectEdge, *********\n"); 00328 */ 00329 00330 Real denom = (v2[0]-v1[0])*(-dy) - (v2[1]-v1[1]) * (-dx); 00331 Real nomRay = (v2[0]-v1[0]) * (v0[1] - v1[1]) - (v2[1]-v1[1])*(v0[0]-v1[0]); 00332 Real nomEdge = (v0[0]-v1[0]) * (-dy) - (v0[1]-v1[1])*(-dx); 00333 00334 00335 /*if the ray is parallel to the edge, return 0: not intersect*/ 00336 if(denom == 0.0) 00337 return 0; 00338 00339 /*if v0 is on the edge, return 0: not intersect*/ 00340 if(nomRay == 0.0) 00341 return 0; 00342 00343 /*if v1 is on the positive ray, and the neighbor of v1 crosses the ray 00344 *return 1: intersect 00345 */ 00346 if(nomEdge == 0) 00347 { /*v1 is on the positive or negative ray*/ 00348 00349 /* 00350 printf("v1 is on the ray\n"); 00351 */ 00352 00353 if(dx*(v1[0]-v0[0])>=0 && dy*(v1[1]-v0[1])>=0) /*v1 on positive ray*/ 00354 { 00355 if(area(v0, v1, v10) * area(v0, v1, v2) >0) 00356 return 0; 00357 else 00358 return 1; 00359 } 00360 else /*v1 on negative ray*/ 00361 return 0; 00362 } 00363 00364 /*if v2 is on the ray, always return 0: not intersect*/ 00365 if(nomEdge == denom) { 00366 /* printf("v2 is on the ray\n");*/ 00367 return 0; 00368 } 00369 00370 /*finally */ 00371 if(denom*nomRay>0 && denom*nomEdge>0 && nomEdge/denom <=1.0) 00372 return 1; 00373 return 0; 00374 } 00375 00376 00377 /*return the number of intersections*/ 00378 Int DBG_rayIntersectPoly(Real v0[2], Real dx, Real dy, directedLine* poly) 00379 { 00380 directedLine* temp; 00381 Int count=0; 00382 if(DBG_rayIntersectEdge(v0, dx, dy, poly->getPrev()->head(), poly->head(), poly->tail())) 00383 count++; 00384 00385 for(temp=poly->getNext(); temp != poly; temp = temp->getNext()) 00386 if(DBG_rayIntersectEdge(v0, dx, dy, temp->getPrev()->head(), temp->head(), temp->tail())) 00387 count++; 00388 /*printf("ray intersect poly: count=%i\n", count);*/ 00389 return count; 00390 } 00391 00392 Int DBG_pointInsidePoly(Real v[2], directedLine* poly) 00393 { 00394 /* 00395 printf("enter pointInsidePoly , v=(%f,%f)\n", v[0], v[1]); 00396 printf("the polygon is\n"); 00397 poly->printList(); 00398 */ 00399 /*for debug purpose*/ 00400 assert( (DBG_rayIntersectPoly(v,1,0,poly) % 2 ) 00401 == (DBG_rayIntersectPoly(v,1,Real(0.1234), poly) % 2 ) 00402 ); 00403 if(DBG_rayIntersectPoly(v, 1, 0, poly) % 2 == 1) 00404 return 1; 00405 else 00406 return 0; 00407 } 00408 00409 /*return the number of polygons which contain thie polygon 00410 * as a subset 00411 */ 00412 Int DBG_enclosingPolygons(directedLine* poly, directedLine* list) 00413 { 00414 directedLine* temp; 00415 Int count=0; 00416 /* 00417 printf("%i\n", DBG_pointInsidePoly(poly->head(), 00418 list->getNextPolygon() 00419 ->getNextPolygon() 00420 ->getNextPolygon() 00421 ->getNextPolygon() 00422 )); 00423 */ 00424 00425 for(temp = list; temp != NULL; temp = temp->getNextPolygon()) 00426 { 00427 if(poly != temp) 00428 if(DBG_pointInsidePoly(poly->head(), temp)) 00429 count++; 00430 /* printf("count=%i\n", count);*/ 00431 } 00432 return count; 00433 } 00434 00435 void DBG_reverse(directedLine* poly) 00436 { 00437 if(poly->getDirection() == INCREASING) 00438 poly->putDirection(DECREASING); 00439 else 00440 poly->putDirection(INCREASING); 00441 00442 directedLine* oldNext = poly->getNext(); 00443 poly->putNext(poly->getPrev()); 00444 poly->putPrev(oldNext); 00445 00446 directedLine* temp; 00447 for(temp=oldNext; temp!=poly; temp = oldNext) 00448 { 00449 if(temp->getDirection() == INCREASING) 00450 temp->putDirection(DECREASING); 00451 else 00452 temp->putDirection(INCREASING); 00453 00454 oldNext = temp->getNext(); 00455 temp->putNext(temp->getPrev()); 00456 temp->putPrev(oldNext); 00457 } 00458 printf("reverse done\n"); 00459 } 00460 00461 Int DBG_checkConnectivity(directedLine *polygon) 00462 { 00463 if(polygon == NULL) return 1; 00464 directedLine* temp; 00465 if(polygon->head()[0] != polygon->getPrev()->tail()[0] || 00466 polygon->head()[1] != polygon->getPrev()->tail()[1]) 00467 return 0; 00468 for(temp=polygon->getNext(); temp != polygon; temp=temp->getNext()) 00469 { 00470 if(temp->head()[0] != temp->getPrev()->tail()[0] || 00471 temp->head()[1] != temp->getPrev()->tail()[1]) 00472 return 0; 00473 } 00474 return 1; 00475 } 00476 00477 /*print out error message. 00478 *If it cannot modify the polygon list to make it satify the 00479 *requirements, return 1. 00480 *otherwise modify the polygon list, and return 0 00481 */ 00482 Int DBG_check(directedLine *polyList) 00483 { 00484 directedLine* temp; 00485 if(polyList == NULL) return 0; 00486 00487 /*if there are intersections, print out error message 00488 */ 00489 if(DBG_polygonListIntersect(polyList)) 00490 { 00491 fprintf(stderr, "DBG_check: there are self intersections, don't know to modify the polygons\n"); 00492 return 1; 00493 } 00494 00495 /*check the connectivity of each polygon*/ 00496 for(temp = polyList; temp!= NULL; temp = temp ->getNextPolygon()) 00497 { 00498 if(! DBG_checkConnectivity(temp)) 00499 { 00500 fprintf(stderr, "DBG_check, polygon not connected\n"); 00501 return 1; 00502 } 00503 } 00504 00505 /*check the orientation of each polygon*/ 00506 for(temp = polyList; temp!= NULL; temp = temp ->getNextPolygon()) 00507 { 00508 00509 00510 Int correctDir; 00511 00512 if( DBG_enclosingPolygons(temp, polyList) % 2 == 0) 00513 correctDir = 1; /*counterclockwise*/ 00514 else 00515 correctDir = 0; /*clockwise*/ 00516 00517 Int actualDir = DBG_isCounterclockwise(temp); 00518 00519 if(correctDir != actualDir) 00520 { 00521 fprintf(stderr, "DBG_check: polygon with incorrect orientations. reversed\n"); 00522 00523 DBG_reverse(temp); 00524 } 00525 00526 } 00527 return 0; 00528 } 00529 00530 /**************handle self intersections*****************/ 00531 //determine whether e interects [begin, end] or not 00532 static directedLine* DBG_edgeIntersectChainD(directedLine *e, 00533 directedLine *begin, directedLine *end) 00534 { 00535 directedLine *temp; 00536 for(temp=begin; temp != end; temp = temp->getNext()) 00537 { 00538 if(DBG_edgesIntersect(e, temp)) 00539 return temp; 00540 } 00541 if(DBG_edgesIntersect(e, end)) 00542 return end; 00543 return NULL; 00544 } 00545 00546 //given a polygon, cut the edges off and finally obtain a 00547 //a polygon without intersections. The cut-off edges are 00548 //dealloated. The new polygon is returned. 00549 directedLine* DBG_cutIntersectionPoly(directedLine *polygon, int& cutOccur) 00550 { 00551 directedLine *begin, *end, *next; 00552 begin = polygon; 00553 end = polygon; 00554 cutOccur = 0; 00555 while( (next = end->getNext()) != begin) 00556 { 00557 directedLine *interc = NULL; 00558 if( (interc = DBG_edgeIntersectChainD(next, begin, end))) 00559 { 00560 int fixed = 0; 00561 if(DBG_edgesIntersect(next, interc->getNext())) 00562 { 00563 //trying to fix it 00564 Real buf[2]; 00565 int i; 00566 Int n=5; 00567 buf[0] = interc->tail()[0]; 00568 buf[1] = interc->tail()[1]; 00569 00570 for(i=1; i<n; i++) 00571 { 00572 Real r = ((Real)i) / ((Real) n); 00573 Real u = (1-r) * interc->head()[0] + r * interc->tail()[0]; 00574 Real v = (1-r) * interc->head()[1] + r * interc->tail()[1]; 00575 interc->tail()[0] = interc->getNext()->head()[0] = u; 00576 interc->tail()[1] = interc->getNext()->head()[1] = v; 00577 if( (! DBG_edgesIntersect(next, interc)) && 00578 (! DBG_edgesIntersect(next, interc->getNext()))) 00579 break; //we fixed it 00580 } 00581 if(i==n) // we didn't fix it 00582 { 00583 fixed = 0; 00584 //back to original 00585 interc->tail()[0] = interc->getNext()->head()[0] = buf[0]; 00586 interc->tail()[1] = interc->getNext()->head()[1] = buf[1]; 00587 } 00588 else 00589 { 00590 fixed = 1; 00591 } 00592 } 00593 if(fixed == 0) 00594 { 00595 cutOccur = 1; 00596 begin->deleteSingleLine(next); 00597 00598 if(begin != end) 00599 { 00600 if(DBG_polygonSelfIntersect(begin)) 00601 { 00602 directedLine* newEnd = end->getPrev(); 00603 begin->deleteSingleLine(end); 00604 end = newEnd; 00605 } 00606 } 00607 } 00608 else 00609 { 00610 end = end->getNext(); 00611 } 00612 } 00613 else 00614 { 00615 end = end->getNext(); 00616 } 00617 } 00618 return begin; 00619 } 00620 00621 directedLine* DBG_cutIntersectionAllPoly(directedLine* list) 00622 { 00623 directedLine* temp; 00624 directedLine* tempNext=NULL; 00625 directedLine* ret = NULL; 00626 int cutOccur=0; 00627 for(temp=list; temp != NULL; temp = tempNext) 00628 { 00629 directedLine *left; 00630 tempNext = temp->getNextPolygon(); 00631 00632 left = DBG_cutIntersectionPoly(temp, cutOccur); 00633 if(left != NULL) 00634 ret=left->insertPolygon(ret); 00635 } 00636 return ret; 00637 } 00638 00639 sampledLine* DBG_collectSampledLinesAllPoly(directedLine *polygonList) 00640 { 00641 directedLine *temp; 00642 sampledLine* tempHead = NULL; 00643 sampledLine* tempTail = NULL; 00644 sampledLine* cHead = NULL; 00645 sampledLine* cTail = NULL; 00646 00647 if(polygonList == NULL) 00648 return NULL; 00649 00650 DBG_collectSampledLinesPoly(polygonList, cHead, cTail); 00651 00652 assert(cHead); 00653 assert(cTail); 00654 for(temp = polygonList->getNextPolygon(); temp != NULL; temp = temp->getNextPolygon()) 00655 { 00656 DBG_collectSampledLinesPoly(temp, tempHead, tempTail); 00657 cTail->insert(tempHead); 00658 cTail = tempTail; 00659 } 00660 return cHead; 00661 } 00662 00663 void DBG_collectSampledLinesPoly(directedLine *polygon, sampledLine*& retHead, sampledLine*& retTail) 00664 { 00665 directedLine *temp; 00666 retHead = NULL; 00667 retTail = NULL; 00668 if(polygon == NULL) 00669 return; 00670 00671 retHead = retTail = polygon->getSampledLine(); 00672 for(temp = polygon->getNext(); temp != polygon; temp=temp->getNext()) 00673 { 00674 retHead = temp->getSampledLine()->insert(retHead); 00675 } 00676 } Generated on Sat May 26 2012 04:22:19 for ReactOS by
1.7.6.1
|