Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > DoxygenpartitionY.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 ** $Date: 2009-08-30 15:53:16 +0000 (Sun, 30 Aug 2009) $ $Revision: 1.1 $ 00035 */ 00036 /* 00037 ** $Header: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/glu32/libnurbs/nurbtess/partitionY.cc,v 1.1 2004/02/02 16:39:13 navaraf Exp $ 00038 */ 00039 00040 #include <stdlib.h> 00041 #include <stdio.h> 00042 #include <time.h> 00043 00044 #include "zlassert.h" 00045 #include "partitionY.h" 00046 #include "searchTree.h" 00047 #include "quicksort.h" 00048 #include "polyUtil.h" 00049 00050 00051 #define max(a,b) ((a>b)? a:b) 00052 #define min(a,b) ((a>b)? b:a) 00053 00054 00055 /*retrurn 00056 *-1: if A < B (Ya<Yb) || (Ya==Yb) 00057 * 0: if A == B 00058 * 1: if A>B 00059 */ 00060 static Int compVertInY(Real A[2], Real B[2]) 00061 { 00062 if( (A[1] < B[1]) || (A[1]==B[1] && A[0]<B[0])) 00063 return -1; 00064 else if 00065 ( A[1] == B[1] && A[0] == B[0]) return 0; 00066 else 00067 return 1; 00068 } 00069 00070 /*v is a vertex: the head of en edge, 00071 *e is an edge, 00072 *return 1 if e is below v: assume v1 and v2 are the two endpoints of e: 00073 * v1<= v, v2<=v. 00074 */ 00075 Int isBelow(directedLine *v, directedLine *e) 00076 { 00077 Real* vert = v->head(); 00078 if( compVertInY(e->head(), vert) != 1 00079 && compVertInY(e->tail(), vert) != 1 00080 ) 00081 return 1; 00082 else 00083 return 0; 00084 } 00085 00086 /*v is a vertex: the head of en edge, 00087 *e is an edge, 00088 *return 1 if e is below v: assume v1 and v2 are the two endpoints of e: 00089 * v1>= v, v2>=v. 00090 */ 00091 Int isAbove(directedLine *v, directedLine *e) 00092 { 00093 Real* vert = v->head(); 00094 if( compVertInY(e->head(), vert) != -1 00095 && compVertInY(e->tail(), vert) != -1 00096 ) 00097 return 1; 00098 else 00099 return 0; 00100 } 00101 00102 Int isCusp(directedLine *v) 00103 { 00104 Real *A=v->getPrev()->head(); 00105 Real *B=v->head(); 00106 Real *C=v->tail(); 00107 if(A[1] < B[1] && B[1] < C[1]) 00108 return 0; 00109 else if(A[1] > B[1] && B[1] > C[1]) 00110 return 0; 00111 else if(A[1] < B[1] && C[1] < B[1]) 00112 return 1; 00113 else if(A[1] > B[1] && C[1] > B[1]) 00114 return 1; 00115 00116 if((isAbove(v, v) && isAbove(v, v->getPrev())) || 00117 (isBelow(v, v) && isBelow(v, v->getPrev()))) 00118 return 1; 00119 else 00120 return 0; 00121 } 00122 00123 /*crossproduct is strictly less than 0*/ 00124 Int isReflex(directedLine *v) 00125 { 00126 Real* A = v->getPrev()->head(); 00127 Real* B = v->head(); 00128 Real* C = v->tail(); 00129 Real Bx,By, Cx, Cy; 00130 Bx = B[0] - A[0]; 00131 By = B[1] - A[1]; 00132 Cx = C[0] - A[0]; 00133 Cy = C[1] - A[1]; 00134 00135 if(Bx*Cy - Cx*By < 0) return 1; 00136 else return 0; 00137 } 00138 00139 /*return 00140 *0: not-cusp 00141 *1: interior cusp 00142 *2: exterior cusp 00143 */ 00144 Int cuspType(directedLine *v) 00145 { 00146 if(! isCusp(v)) return 0; 00147 else if(isReflex(v)) return 1; 00148 else 00149 return 2; 00150 } 00151 00152 sweepRange* sweepRangeMake(directedLine* left, Int leftType, 00153 directedLine* right, Int rightType) 00154 { 00155 sweepRange* ret = (sweepRange*)malloc(sizeof(sweepRange)); 00156 assert(ret); 00157 ret->left = left; 00158 ret->leftType = leftType; 00159 ret->right = right; 00160 ret->rightType = rightType; 00161 return ret; 00162 } 00163 00164 void sweepRangeDelete(sweepRange* range) 00165 { 00166 free(range); 00167 } 00168 00169 Int sweepRangeEqual(sweepRange* src1, sweepRange* src2) 00170 { 00171 Int leftEqual; 00172 Int rightEqual; 00173 00174 00175 /*The case when both are vertices should not happen*/ 00176 assert(! (src1->leftType == 0 && src2->leftType == 0)); 00177 if(src1->leftType == 0 && src2->leftType == 1){ 00178 if(src1->left == src2->left || 00179 src1->left->getPrev() == src2->left 00180 ) 00181 leftEqual = 1; 00182 else 00183 leftEqual = 0; 00184 } 00185 else if(src1->leftType == 1 && src2->leftType == 1){ 00186 if(src1->left == src2->left) 00187 leftEqual = 1; 00188 else 00189 leftEqual = 0; 00190 } 00191 else /*src1->leftType == 1 && src2->leftType == 0*/{ 00192 if(src1->left == src2->left || 00193 src1->left == src2->left->getPrev() 00194 ) 00195 leftEqual = 1; 00196 else 00197 leftEqual = 0; 00198 } 00199 00200 /*the same thing for right*/ 00201 /*The case when both are vertices should not happen*/ 00202 assert(! (src1->rightType == 0 && src2->rightType == 0)); 00203 if(src1->rightType == 0 && src2->rightType == 1){ 00204 if(src1->right == src2->right || 00205 src1->right->getPrev() == src2->right 00206 ) 00207 rightEqual = 1; 00208 else 00209 rightEqual = 0; 00210 } 00211 else if(src1->rightType == 1 && src2->rightType == 1){ 00212 if(src1->right == src2->right) 00213 rightEqual = 1; 00214 else 00215 rightEqual = 0; 00216 } 00217 else /*src1->rightType == 1 && src2->rightType == 0*/{ 00218 if(src1->right == src2->right || 00219 src1->right == src2->right->getPrev() 00220 ) 00221 rightEqual = 1; 00222 else 00223 rightEqual = 0; 00224 } 00225 00226 return (leftEqual == 1 || rightEqual == 1); 00227 } 00228 00229 /*given (x_1, y_1) and (x_2, y_2), and y 00230 *return x such that (x,y) is on the line 00231 */ 00232 inline/*static*/ Real intersectHoriz(Real x1, Real y1, Real x2, Real y2, Real y) 00233 { 00234 return ((y2==y1)? (x1+x2)*Real(0.5) : x1 + ((y-y1)/(y2-y1)) * (x2-x1)); 00235 /* 00236 if(y2 == y1) return (x1+x2)*0.5; 00237 else return x1 + ((y-y1)/(y2-y1)) * (x2-x1); 00238 */ 00239 } 00240 00241 /*compare two edges of a polygon. 00242 *edge A < edge B if there is a horizontal line so that the intersection 00243 *with A is to the left of the intersection with B. 00244 *This function is used in sweepY for the dynamic search tree insertion to 00245 *order the edges. 00246 * Implementation: (x_1,y_1) and (x_2, y_2) 00247 */ 00248 static Int compEdges(directedLine *e1, directedLine *e2) 00249 { 00250 Real* head1 = e1->head(); 00251 Real* tail1 = e1->tail(); 00252 Real* head2 = e2->head(); 00253 Real* tail2 = e2->tail(); 00254 /* 00255 Real h10 = head1[0]; 00256 Real h11 = head1[1]; 00257 Real t10 = tail1[0]; 00258 Real t11 = tail1[1]; 00259 Real h20 = head2[0]; 00260 Real h21 = head2[1]; 00261 Real t20 = tail2[0]; 00262 Real t21 = tail2[1]; 00263 */ 00264 Real e1_Ymax, e1_Ymin, e2_Ymax, e2_Ymin; 00265 /* 00266 if(h11>t11) { 00267 e1_Ymax= h11; 00268 e1_Ymin= t11; 00269 } 00270 else{ 00271 e1_Ymax = t11; 00272 e1_Ymin = h11; 00273 } 00274 00275 if(h21>t21) { 00276 e2_Ymax= h21; 00277 e2_Ymin= t21; 00278 } 00279 else{ 00280 e2_Ymax = t21; 00281 e2_Ymin = h21; 00282 } 00283 */ 00284 00285 if(head1[1]>tail1[1]) { 00286 e1_Ymax= head1[1]; 00287 e1_Ymin= tail1[1]; 00288 } 00289 else{ 00290 e1_Ymax = tail1[1]; 00291 e1_Ymin = head1[1]; 00292 } 00293 00294 if(head2[1]>tail2[1]) { 00295 e2_Ymax= head2[1]; 00296 e2_Ymin= tail2[1]; 00297 } 00298 else{ 00299 e2_Ymax = tail2[1]; 00300 e2_Ymin = head2[1]; 00301 } 00302 00303 00304 /*Real e1_Ymax = max(head1[1], tail1[1]);*/ /*max(e1->head()[1], e1->tail()[1]);*/ 00305 /*Real e1_Ymin = min(head1[1], tail1[1]);*/ /*min(e1->head()[1], e1->tail()[1]);*/ 00306 /*Real e2_Ymax = max(head2[1], tail2[1]);*/ /*max(e2->head()[1], e2->tail()[1]);*/ 00307 /*Real e2_Ymin = min(head2[1], tail2[1]);*/ /*min(e2->head()[1], e2->tail()[1]);*/ 00308 00309 Real Ymax = min(e1_Ymax, e2_Ymax); 00310 Real Ymin = max(e1_Ymin, e2_Ymin); 00311 00312 Real y = Real(0.5)*(Ymax + Ymin); 00313 00314 /* Real x1 = intersectHoriz(e1->head()[0], e1->head()[1], e1->tail()[0], e1->tail()[1], y); 00315 Real x2 = intersectHoriz(e2->head()[0], e2->head()[1], e2->tail()[0], e2->tail()[1], y); 00316 */ 00317 /* 00318 Real x1 = intersectHoriz(h10, h11, t10, t11, y); 00319 Real x2 = intersectHoriz(h20, h21, t20, t21, y); 00320 */ 00321 Real x1 = intersectHoriz(head1[0], head1[1], tail1[0], tail1[1], y); 00322 Real x2 = intersectHoriz(head2[0], head2[1], tail2[0], tail2[1], y); 00323 00324 if(x1<= x2) return -1; 00325 else return 1; 00326 } 00327 00328 /*used by sort precedures 00329 */ 00330 static Int compInY(directedLine* v1, directedLine* v2) 00331 { 00332 return v1->compInY(v2); 00333 } 00334 00335 void findDiagonals(Int total_num_edges, directedLine** sortedVertices, sweepRange** ranges, Int& num_diagonals, directedLine** diagonal_vertices) 00336 { 00337 Int i,j,k; 00338 00339 k=0; 00340 00341 for(i=0; i<total_num_edges; i++) 00342 { 00343 directedLine* vert =sortedVertices[i]; 00344 directedLine* thisEdge = vert; 00345 directedLine* prevEdge = vert->getPrev(); 00346 /* 00347 printf("find i=%i\n", i); 00348 printf("the vertex is\n"); 00349 vert->printSingle(); 00350 */ 00351 if(isBelow(vert, thisEdge) && isBelow(vert, prevEdge) && compEdges(prevEdge, thisEdge)<0) 00352 { 00353 /*this is an upward interior cusp*/ 00354 diagonal_vertices[k++] = vert; 00355 00356 for(j=i+1; j<total_num_edges; j++) 00357 if(sweepRangeEqual(ranges[i], ranges[j])) 00358 { 00359 diagonal_vertices[k++] = sortedVertices[j]; 00360 break; 00361 } 00362 assert(j<total_num_edges); 00363 00364 00365 } 00366 else if(isAbove(vert, thisEdge) && isAbove(vert, prevEdge) && compEdges(prevEdge, thisEdge)>0) 00367 { 00368 /*this is an downward interior cusp*/ 00369 diagonal_vertices[k++] = vert; 00370 for(j=i-1; j>=0; j--) 00371 if(sweepRangeEqual(ranges[i], ranges[j])) 00372 { 00373 diagonal_vertices[k++] = sortedVertices[j]; 00374 break; 00375 } 00376 /* printf("j=%i\n", j);*/ 00377 assert(j>=0); 00378 00379 00380 00381 } 00382 } 00383 num_diagonals = k/2; 00384 } 00385 00386 /*get rid of repeated diagonlas so that each diagonal appears only once in the array 00387 */ 00388 Int deleteRepeatDiagonals(Int num_diagonals, directedLine** diagonal_vertices, directedLine** new_vertices) 00389 { 00390 Int i,k; 00391 Int j,l; 00392 Int index; 00393 index=0; 00394 for(i=0,k=0; i<num_diagonals; i++, k+=2) 00395 { 00396 Int isRepeated=0; 00397 /*check the diagonla (diagonal_vertice[k], diagonal_vertices[k+1]) 00398 *is repeated or not 00399 */ 00400 for(j=0,l=0; j<index; j++, l+=2) 00401 { 00402 if( 00403 (diagonal_vertices[k] == new_vertices[l] && 00404 diagonal_vertices[k+1] == new_vertices[l+1] 00405 ) 00406 || 00407 ( 00408 diagonal_vertices[k] == new_vertices[l+1] && 00409 diagonal_vertices[k+1] == new_vertices[l] 00410 ) 00411 ) 00412 { 00413 isRepeated=1; 00414 break; 00415 } 00416 } 00417 if(! isRepeated) 00418 { 00419 new_vertices[index+index] = diagonal_vertices[k]; 00420 new_vertices[index+index+1] = diagonal_vertices[k+1]; 00421 index++; 00422 } 00423 } 00424 return index; 00425 } 00426 00427 /*for debug only*/ 00428 directedLine** DBGfindDiagonals(directedLine *polygons, Int& num_diagonals) 00429 { 00430 Int total_num_edges = 0; 00431 directedLine** array = polygons->toArrayAllPolygons(total_num_edges); 00432 quicksort( (void**)array, 0, total_num_edges-1, (Int (*)(void*, void*)) compInY); 00433 sweepRange** ranges = (sweepRange**) malloc(sizeof(sweepRange*) * total_num_edges); 00434 assert(ranges); 00435 00436 sweepY(total_num_edges, array, ranges); 00437 00438 directedLine** diagonal_vertices = (directedLine**) malloc(sizeof(directedLine*) * total_num_edges); 00439 assert(diagonal_vertices); 00440 findDiagonals(total_num_edges, array, ranges, num_diagonals, diagonal_vertices); 00441 00442 num_diagonals=deleteRepeatDiagonals(num_diagonals, diagonal_vertices, diagonal_vertices); 00443 return diagonal_vertices; 00444 00445 } 00446 00447 00448 /*partition into Y-monotone polygons*/ 00449 directedLine* partitionY(directedLine *polygons, sampledLine **retSampledLines) 00450 { 00451 Int total_num_edges = 0; 00452 directedLine** array = polygons->toArrayAllPolygons(total_num_edges); 00453 00454 quicksort( (void**)array, 0, total_num_edges-1, (Int (*)(void*, void*)) compInY); 00455 00456 sweepRange** ranges = (sweepRange**) malloc(sizeof(sweepRange*) * (total_num_edges)); 00457 assert(ranges); 00458 00459 00460 00461 sweepY(total_num_edges, array, ranges); 00462 00463 00464 00465 /*the diagonal vertices are stored as: 00466 *v0-v1: 1st diagonal 00467 *v2-v3: 2nd diagonal 00468 *v5-v5: 3rd diagonal 00469 *... 00470 */ 00471 00472 00473 Int num_diagonals; 00474 /*number diagonals is < total_num_edges*total_num_edges*/ 00475 directedLine** diagonal_vertices = (directedLine**) malloc(sizeof(directedLine*) * total_num_edges*2/*total_num_edges*/); 00476 assert(diagonal_vertices); 00477 00478 00479 00480 findDiagonals(total_num_edges, array, ranges, num_diagonals, diagonal_vertices); 00481 00482 00483 00484 directedLine* ret_polygons = polygons; 00485 sampledLine* newSampledLines = NULL; 00486 Int i,k; 00487 00488 num_diagonals=deleteRepeatDiagonals(num_diagonals, diagonal_vertices, diagonal_vertices); 00489 00490 00491 00492 Int *removedDiagonals=(Int*)malloc(sizeof(Int) * num_diagonals); 00493 for(i=0; i<num_diagonals; i++) 00494 removedDiagonals[i] = 0; 00495 00496 00497 00498 00499 00500 for(i=0,k=0; i<num_diagonals; i++,k+=2) 00501 { 00502 00503 00504 directedLine* v1=diagonal_vertices[k]; 00505 directedLine* v2=diagonal_vertices[k+1]; 00506 directedLine* ret_p1; 00507 directedLine* ret_p2; 00508 00509 /*we ahve to determine whether v1 and v2 belong to the same polygon before 00510 *their structure are modified by connectDiagonal(). 00511 */ 00512 /* 00513 directedLine *root1 = v1->findRoot(); 00514 directedLine *root2 = v2->findRoot(); 00515 assert(root1); 00516 assert(root2); 00517 */ 00518 00519 directedLine* root1 = v1->rootLinkFindRoot(); 00520 directedLine* root2 = v2->rootLinkFindRoot(); 00521 00522 if(root1 != root2) 00523 { 00524 00525 removedDiagonals[i] = 1; 00526 sampledLine* generatedLine; 00527 00528 00529 00530 v1->connectDiagonal(v1,v2, &ret_p1, &ret_p2, &generatedLine, ret_polygons); 00531 00532 00533 00534 newSampledLines = generatedLine->insert(newSampledLines); 00535 /* 00536 ret_polygons = ret_polygons->cutoffPolygon(root1); 00537 00538 ret_polygons = ret_polygons->cutoffPolygon(root2); 00539 ret_polygons = ret_p1->insertPolygon(ret_polygons); 00540 root1->rootLinkSet(ret_p1); 00541 root2->rootLinkSet(ret_p1); 00542 ret_p1->rootLinkSet(NULL); 00543 ret_p2->rootLinkSet(ret_p1); 00544 */ 00545 ret_polygons = ret_polygons->cutoffPolygon(root2); 00546 00547 00548 00549 root2->rootLinkSet(root1); 00550 ret_p1->rootLinkSet(root1); 00551 ret_p2->rootLinkSet(root1); 00552 00553 /*now that we have connected the diagonal v1 and v2, 00554 *we have to check those unprocessed diagonals which 00555 *have v1 or v2 as an end point. Notice that the head of v1 00556 *has the same coodinates as the head of v2->prev, and the head of 00557 *v2 has the same coordinate as the head of v1->prev. 00558 *Suppose these is a diagonal (v1, x). If (v1,x) is still a valid 00559 *diagonal, then x should be on the left hand side of the directed line: *v1->prev->head -- v1->head -- v1->tail. Otherwise, (v1,x) should be 00560 *replaced by (v2->prev, x), that is, x is on the left of 00561 * v2->prev->prev->head, v2->prev->head, v2->prev->tail. 00562 */ 00563 Int ii, kk; 00564 for(ii=0, kk=0; ii<num_diagonals; ii++, kk+=2) 00565 if( removedDiagonals[ii]==0) 00566 { 00567 directedLine* d1=diagonal_vertices[kk]; 00568 directedLine* d2=diagonal_vertices[kk+1]; 00569 /*check d1, and replace diagonal_vertices[kk] if necessary*/ 00570 if(d1 == v1) { 00571 /*check if d2 is to left of v1->prev->head:v1->head:v1->tail*/ 00572 if(! pointLeft2Lines(v1->getPrev()->head(), 00573 v1->head(), v1->tail(), d2->head())) 00574 { 00575 /* 00576 assert(pointLeft2Lines(v2->getPrev()->getPrev()->head(), 00577 v2->getPrev()->head(), 00578 v2->getPrev()->tail(), d2->head())); 00579 */ 00580 diagonal_vertices[kk] = v2->getPrev(); 00581 } 00582 } 00583 if(d1 == v2) { 00584 /*check if d2 is to left of v2->prev->head:v2->head:v2->tail*/ 00585 if(! pointLeft2Lines(v2->getPrev()->head(), 00586 v2->head(), v2->tail(), d2->head())) 00587 { 00588 /* 00589 assert(pointLeft2Lines(v1->getPrev()->getPrev()->head(), 00590 v1->getPrev()->head(), 00591 v1->getPrev()->tail(), d2->head())); 00592 */ 00593 diagonal_vertices[kk] = v1->getPrev(); 00594 } 00595 } 00596 /*check d2 and replace diagonal_vertices[k+1] if necessary*/ 00597 if(d2 == v1) { 00598 /*check if d1 is to left of v1->prev->head:v1->head:v1->tail*/ 00599 if(! pointLeft2Lines(v1->getPrev()->head(), 00600 v1->head(), v1->tail(), d1->head())) 00601 { 00602 /* assert(pointLeft2Lines(v2->getPrev()->getPrev()->head(), 00603 v2->getPrev()->head(), 00604 v2->getPrev()->tail(), d1->head())); 00605 */ 00606 diagonal_vertices[kk+1] = v2->getPrev(); 00607 } 00608 } 00609 if(d2 == v2) { 00610 /*check if d1 is to left of v2->prev->head:v2->head:v2->tail*/ 00611 if(! pointLeft2Lines(v2->getPrev()->head(), 00612 v2->head(), v2->tail(), d1->head())) 00613 { 00614 /* assert(pointLeft2Lines(v1->getPrev()->getPrev()->head(), 00615 v1->getPrev()->head(), 00616 v1->getPrev()->tail(), d1->head())); 00617 */ 00618 diagonal_vertices[kk+1] = v1->getPrev(); 00619 } 00620 } 00621 } 00622 }/*end if (root1 not equal to root 2)*/ 00623 } 00624 00625 /*second pass, now all diagoals should belong to the same polygon*/ 00626 00627 00628 00629 for(i=0,k=0; i<num_diagonals; i++, k += 2) 00630 if(removedDiagonals[i] == 0) 00631 { 00632 00633 00634 directedLine* v1=diagonal_vertices[k]; 00635 directedLine* v2=diagonal_vertices[k+1]; 00636 00637 00638 00639 directedLine* ret_p1; 00640 directedLine* ret_p2; 00641 00642 /*we ahve to determine whether v1 and v2 belong to the same polygon before 00643 *their structure are modified by connectDiagonal(). 00644 */ 00645 directedLine *root1 = v1->findRoot(); 00646 /* 00647 directedLine *root2 = v2->findRoot(); 00648 00649 00650 00651 assert(root1); 00652 assert(root2); 00653 assert(root1 == root2); 00654 */ 00655 sampledLine* generatedLine; 00656 00657 00658 00659 v1->connectDiagonal(v1,v2, &ret_p1, &ret_p2, &generatedLine, ret_polygons); 00660 newSampledLines = generatedLine->insert(newSampledLines); 00661 00662 ret_polygons = ret_polygons->cutoffPolygon(root1); 00663 00664 ret_polygons = ret_p1->insertPolygon(ret_polygons); 00665 00666 ret_polygons = ret_p2->insertPolygon(ret_polygons); 00667 00668 00669 00670 for(Int j=i+1; j<num_diagonals; j++) 00671 { 00672 if(removedDiagonals[j] ==0) 00673 { 00674 00675 directedLine* temp1=diagonal_vertices[2*j]; 00676 directedLine* temp2=diagonal_vertices[2*j+1]; 00677 if(temp1==v1 || temp1==v2 || temp2==v1 || temp2==v2) 00678 if(! temp1->samePolygon(temp1, temp2)) 00679 { 00680 /*if temp1 and temp2 are in different polygons, 00681 *then one of them must be v1 or v2. 00682 */ 00683 00684 00685 00686 assert(temp1==v1 || temp1 == v2 || temp2==v1 || temp2 ==v2); 00687 if(temp1==v1) 00688 { 00689 diagonal_vertices[2*j] = v2->getPrev(); 00690 } 00691 if(temp2==v1) 00692 { 00693 diagonal_vertices[2*j+1] = v2->getPrev(); 00694 } 00695 if(temp1==v2) 00696 { 00697 diagonal_vertices[2*j] = v1->getPrev(); 00698 } 00699 if(temp2==v2) 00700 { 00701 diagonal_vertices[2*j+1] = v1->getPrev(); 00702 } 00703 } 00704 } 00705 } 00706 00707 } 00708 00709 /*clean up spaces*/ 00710 free(array); 00711 free(ranges); 00712 free(diagonal_vertices); 00713 free(removedDiagonals); 00714 00715 *retSampledLines = newSampledLines; 00716 return ret_polygons; 00717 } 00718 00719 /*given a set of simple polygons where the interior 00720 *is decided by left-hand principle, 00721 *return a range (sight) for each vertex. This is called 00722 *Trapezoidalization. 00723 */ 00724 void sweepY(Int nVertices, directedLine** sortedVertices, sweepRange** ret_ranges) 00725 { 00726 Int i; 00727 /*for each vertex in the sorted list, update the binary search tree. 00728 *and store the range information for each vertex. 00729 */ 00730 treeNode* searchTree = NULL; 00731 for(i=0; i<nVertices;i++) 00732 { 00733 00734 directedLine* vert = sortedVertices[i]; 00735 00736 directedLine* thisEdge = vert; 00737 directedLine* prevEdge = vert->getPrev(); 00738 00739 if(isBelow(vert, thisEdge) && isAbove(vert, prevEdge)) 00740 { 00741 00742 /*case 1: this < v < prev 00743 *the polygon is going down at v, the interior is to 00744 *the right hand side. 00745 * find the edge to the right of thisEdge for right range. 00746 * delete thisEdge 00747 * insert prevEdge 00748 */ 00749 treeNode* thisNode = TreeNodeFind(searchTree, thisEdge, ( Int (*) (void *, void *))compEdges); 00750 assert(thisNode); 00751 00752 treeNode* succ = TreeNodeSuccessor(thisNode); 00753 assert(succ); 00754 searchTree = TreeNodeDeleteSingleNode(searchTree, thisNode); 00755 searchTree = TreeNodeInsert(searchTree, TreeNodeMake(prevEdge), ( Int (*) (void *, void *))compEdges); 00756 00757 00758 ret_ranges[i] = sweepRangeMake(vert, 0, (directedLine*) (succ->key), 1); 00759 00760 } 00761 else if(isAbove(vert, thisEdge) && isBelow(vert, prevEdge)) 00762 { 00763 00764 /*case 2: this > v > prev 00765 *the polygon is going up at v, the interior is to 00766 *the left hand side. 00767 * find the edge to the left of thisEdge for left range. 00768 * delete prevEdge 00769 * insert thisEdge 00770 */ 00771 treeNode* prevNode = TreeNodeFind(searchTree, prevEdge, ( Int (*) (void *, void *))compEdges); 00772 assert(prevNode); 00773 treeNode* pred = TreeNodePredecessor(prevNode); 00774 searchTree = TreeNodeDeleteSingleNode(searchTree, prevNode); 00775 searchTree = TreeNodeInsert(searchTree, TreeNodeMake(thisEdge), ( Int (*) (void *, void *))compEdges); 00776 ret_ranges[i] = sweepRangeMake((directedLine*)(pred->key), 1, vert, 0); 00777 } 00778 else if(isAbove(vert, thisEdge) && isAbove(vert, prevEdge)) 00779 { 00780 00781 /*case 3: insert both edges*/ 00782 treeNode* thisNode = TreeNodeMake(thisEdge); 00783 treeNode* prevNode = TreeNodeMake(prevEdge); 00784 searchTree = TreeNodeInsert(searchTree, thisNode, ( Int (*) (void *, void *))compEdges); 00785 searchTree = TreeNodeInsert(searchTree, prevNode, ( Int (*) (void *, void *))compEdges); 00786 if(compEdges(thisEdge, prevEdge)<0) /*interior cusp*/ 00787 { 00788 00789 treeNode* leftEdge = TreeNodePredecessor(thisNode); 00790 treeNode* rightEdge = TreeNodeSuccessor(prevNode); 00791 ret_ranges[i] = sweepRangeMake( (directedLine*) leftEdge->key, 1, 00792 (directedLine*) rightEdge->key, 1 00793 ); 00794 } 00795 else /*exterior cusp*/ 00796 { 00797 00798 ret_ranges[i] = sweepRangeMake( prevEdge, 1, thisEdge, 1); 00799 } 00800 } 00801 else if(isBelow(vert, thisEdge) && isBelow(vert, prevEdge)) 00802 { 00803 00804 /*case 4: delete both edges*/ 00805 treeNode* thisNode = TreeNodeFind(searchTree, thisEdge, ( Int (*) (void *, void *))compEdges); 00806 treeNode* prevNode = TreeNodeFind(searchTree, prevEdge, ( Int (*) (void *, void *))compEdges); 00807 if(compEdges(thisEdge, prevEdge)>0) /*interior cusp*/ 00808 { 00809 treeNode* leftEdge = TreeNodePredecessor(prevNode); 00810 treeNode* rightEdge = TreeNodeSuccessor(thisNode); 00811 ret_ranges[i] = sweepRangeMake( (directedLine*) leftEdge->key, 1, 00812 (directedLine*) rightEdge->key, 1 00813 ); 00814 } 00815 else /*exterior cusp*/ 00816 { 00817 ret_ranges[i] = sweepRangeMake( thisEdge, 1, prevEdge, 1); 00818 } 00819 searchTree = TreeNodeDeleteSingleNode(searchTree, thisNode); 00820 searchTree = TreeNodeDeleteSingleNode(searchTree, prevNode); 00821 } 00822 else 00823 { 00824 fprintf(stderr,"error in partitionY.C, invalid case\n"); 00825 printf("vert is\n"); 00826 vert->printSingle(); 00827 printf("thisEdge is\n"); 00828 thisEdge->printSingle(); 00829 printf("prevEdge is\n"); 00830 prevEdge->printSingle(); 00831 00832 exit(1); 00833 } 00834 } 00835 00836 /*finaly clean up space: delete the search tree*/ 00837 TreeNodeDeleteWholeTree(searchTree); 00838 } Generated on Thu May 24 2012 04:24:15 for ReactOS by
1.7.6.1
|