ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

partitionY.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.