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

monoChain.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: 2008-11-21 14:20:54 +0000 (Fri, 21 Nov 2008) $ $Revision: 1.1 $
00035 */
00036 /*
00037 ** $Header: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/glu32/libnurbs/nurbtess/monoChain.cc,v 1.1 2004/02/02 16:39:13 navaraf Exp $
00038 */
00039 
00040 #include "gluos.h"
00041 #include <stdlib.h>
00042 #include <stdio.h>
00043 #include <GL/gl.h>
00044 
00045 #include "glimports.h"
00046 #include "zlassert.h"
00047 
00048 #include "monoChain.h"
00049 #include "quicksort.h"
00050 #include "searchTree.h"
00051 #include "polyUtil.h"
00052 
00053 #ifndef max
00054 #define max(a,b) ((a>b)? a:b)
00055 #endif
00056 #ifndef min
00057 #define min(a,b) ((a>b)? b:a)
00058 #endif
00059 
00060 extern Int isCusp(directedLine *v);
00061 extern Int deleteRepeatDiagonals(Int num_diagonals, directedLine** diagonal_vertices, directedLine** new_vertices);
00062 
00063 #if 0
00064 //for debug purpose only
00065 static void drawDiagonals(Int num_diagonals, directedLine** diagonal_vertices)
00066 {
00067   Int i,k;
00068   for(i=0; i<num_diagonals; i++)
00069     {
00070       glBegin(GL_LINE);
00071       glVertex2fv(diagonal_vertices[2*i]->head());
00072       glVertex2fv(diagonal_vertices[2*i+1]->head());
00073       glEnd();
00074     }
00075 }
00076 #endif
00077 
00078 /*given (x_1, y_1) and (x_2, y_2), and y
00079  *return x such that (x,y) is on the line
00080  */
00081 inline Real intersectHoriz(Real x1, Real y1, Real x2, Real y2, Real y)
00082 {
00083   return ((y2==y1)? (x1+x2)*0.5 : x1 + ((y-y1)/(y2-y1)) * (x2-x1));
00084 }
00085 
00086 //compare the heads of the two chains
00087 static int compChainHeadInY(monoChain* mc1, monoChain* mc2)
00088 {
00089   return compV2InY(mc1->getHead()->head(), mc2->getHead()->head());
00090 }
00091 
00092 monoChain::monoChain(directedLine* cHead, directedLine* cTail)
00093 {
00094   chainHead = cHead;
00095   chainTail = cTail;
00096   next = this;
00097   prev = this;
00098   
00099   nextPolygon = NULL;
00100 
00101   //compute bounding box
00102   directedLine* temp;
00103   minX = maxX = chainTail->head()[0];
00104   minY = maxY = chainTail->head()[1];
00105 
00106   for(temp=chainHead; temp!=cTail; temp = temp->getNext())
00107     {
00108       if(temp->head()[0] < minX)
00109     minX = temp->head()[0];
00110       if(temp->head()[0] > maxX)
00111     maxX = temp->head()[0];
00112 
00113       if(temp->head()[1] < minY)
00114     minY = temp->head()[1];
00115       if(temp->head()[1] > maxY)
00116     maxY = temp->head()[1];
00117     }
00118 
00119   //check whether the chain is increasing or decreasing
00120   if(chainHead->compInY(chainTail) <0)
00121     isIncrease = 1;
00122   else
00123     isIncrease = 0;
00124   
00125   //initilize currrent, this is used for accelerating search
00126   if(isIncrease)
00127     current = chainHead;
00128   else
00129     current = chainTail;
00130 
00131   isKey = 0;
00132 }
00133 
00134 //insert a new line between prev and this
00135 void monoChain::insert(monoChain* nc)
00136 {
00137   nc->next = this;
00138   nc->prev = prev;
00139   prev->next = nc;
00140   prev = nc;
00141 }
00142 
00143 void monoChain::deleteLoop()
00144 {
00145   monoChain *temp, *tempNext;
00146   prev->next = NULL;
00147   for(temp=this; temp != NULL; temp = tempNext)
00148     {
00149       tempNext = temp->next;
00150       delete temp;
00151     }
00152 }
00153 
00154 void monoChain::deleteLoopList()
00155 {
00156   monoChain *temp, *tempNext;
00157   for(temp=this; temp != NULL; temp = tempNext)
00158     {
00159       tempNext = temp->nextPolygon;
00160       temp->deleteLoop();
00161     }
00162 }
00163 
00164 Int monoChain::toArraySingleLoop(monoChain** array, Int index)
00165 {
00166   monoChain *temp;
00167   array[index++] = this;
00168   for(temp = next; temp != this; temp = temp->next)
00169     {
00170       array[index++] = temp;
00171     }
00172   return index;
00173 }
00174 
00175 monoChain** monoChain::toArrayAllLoops(Int& num_chains)
00176 {
00177   num_chains = numChainsAllLoops();
00178   monoChain **ret =  (monoChain**) malloc(sizeof(monoChain*) * num_chains);
00179   assert(ret);
00180   monoChain *temp;
00181   Int index = 0;
00182   for(temp = this; temp != NULL; temp=temp->nextPolygon){
00183     index = temp->toArraySingleLoop(ret, index);
00184   }
00185   return ret;
00186 }
00187 
00188 Int monoChain::numChainsSingleLoop()
00189 {
00190   Int ret=0;
00191   monoChain* temp;
00192   if(next == this) return 1;
00193   ret = 1;
00194   for(temp=next; temp != this; temp = temp->next)
00195     ret++;
00196   return ret;
00197 }
00198 
00199 Int monoChain::numChainsAllLoops()
00200 {
00201   Int ret=0;
00202   monoChain *temp;
00203   for(temp =this; temp != NULL; temp = temp->nextPolygon)
00204     ret += temp->numChainsSingleLoop();
00205   return ret;
00206 }
00207 
00208 //update 'current'
00209 Real monoChain::chainIntersectHoriz(Real y)
00210 {
00211   directedLine* temp;
00212   if(isIncrease)
00213     {
00214       for(temp= current; temp != chainTail; temp = temp->getNext())
00215     {
00216       if(temp->head()[1] > y)
00217         break;
00218     }
00219       current = temp->getPrev();
00220     }
00221   else 
00222     {
00223       for(temp = current; temp != chainHead; temp = temp->getPrev())
00224     {
00225       if(temp->head()[1] > y)
00226         break;
00227     }
00228       current = temp->getNext();
00229     }
00230   return intersectHoriz(current->head()[0], current->head()[1], current->tail()[0], current->tail()[1], y);
00231 }
00232 
00233 monoChain* directedLineLoopToMonoChainLoop(directedLine* loop)
00234 {
00235   directedLine *temp;
00236   monoChain *ret=NULL;
00237 
00238   //find the first cusp
00239   directedLine *prevCusp=NULL;
00240   directedLine *firstCusp;
00241 
00242   if(isCusp(loop))
00243     prevCusp = loop;
00244   else
00245     {
00246       for(temp = loop->getNext(); temp != loop; temp = temp->getNext())
00247     if(isCusp(temp))
00248       break;
00249       prevCusp = temp;
00250     }
00251   firstCusp = prevCusp;
00252 //printf("first cusp is (%f,%f), (%f,%f), (%f,%f)\n", prevCusp->getPrev()->head()[0], prevCusp->getPrev()->head()[1], prevCusp->head()[0], prevCusp->head()[1], prevCusp->tail()[0], prevCusp->tail()[1]);
00253 
00254   for(temp = prevCusp->getNext(); temp != loop; temp = temp->getNext())
00255     {
00256       if(isCusp(temp))
00257     {
00258 //printf("the cusp is (%f,%f), (%f,%f), (%f,%f)\n", temp->getPrev()->head()[0], temp->getPrev()->head()[1], temp->head()[0], temp->head()[1], temp->tail()[0], temp->tail()[1]);
00259       if(ret == NULL)
00260         {
00261           ret = new monoChain(prevCusp, temp);
00262         }
00263       else
00264         ret->insert(new monoChain(prevCusp, temp));
00265       prevCusp = temp;    
00266     }
00267     }
00268   ret->insert(new monoChain(prevCusp, firstCusp));
00269 
00270   return ret;
00271 }
00272 
00273 monoChain* directedLineLoopListToMonoChainLoopList(directedLine* list)
00274 {
00275   directedLine* temp;
00276   monoChain* mc;
00277   monoChain* mcEnd;
00278   mc = directedLineLoopToMonoChainLoop(list);
00279   mcEnd = mc;  
00280   for(temp = list->getNextPolygon(); temp != NULL; temp = temp->getNextPolygon())
00281     {
00282       monoChain *newLoop = directedLineLoopToMonoChainLoop(temp);
00283       mcEnd->setNextPolygon(newLoop);
00284       mcEnd = newLoop;
00285     }
00286   return mc;
00287 }
00288 
00289 /*compare two edges of a polygon.
00290  *edge A < edge B if there is a horizontal line so that the intersection
00291  *with A is to the left of the intersection with B.
00292  *This function is used in sweepY for the dynamic search tree insertion to
00293  *order the edges.
00294  * Implementation: (x_1,y_1) and (x_2, y_2)
00295  */
00296 static Int compEdges(directedLine *e1, directedLine *e2)
00297 {
00298   Real* head1 = e1->head();
00299   Real* tail1 = e1->tail();
00300   Real* head2 = e2->head();
00301   Real* tail2 = e2->tail();
00302 /*
00303   Real h10 = head1[0];
00304   Real h11 = head1[1];
00305   Real t10 = tail1[0];
00306   Real t11 = tail1[1];
00307   Real h20 = head2[0];
00308   Real h21 = head2[1];
00309   Real t20 = tail2[0];
00310   Real t21 = tail2[1];
00311 */
00312   Real e1_Ymax, e1_Ymin, e2_Ymax, e2_Ymin;
00313 /*
00314   if(h11>t11) {
00315     e1_Ymax= h11;
00316     e1_Ymin= t11;
00317   }
00318   else{
00319     e1_Ymax = t11;
00320     e1_Ymin = h11;
00321   }
00322 
00323   if(h21>t21) {
00324     e2_Ymax= h21;
00325     e2_Ymin= t21;
00326   }
00327   else{
00328     e2_Ymax = t21;
00329     e2_Ymin = h21;
00330   }
00331 */
00332  
00333   if(head1[1]>tail1[1]) {
00334     e1_Ymax= head1[1];
00335     e1_Ymin= tail1[1];
00336   }
00337   else{
00338     e1_Ymax = tail1[1];
00339     e1_Ymin = head1[1];
00340   }
00341 
00342   if(head2[1]>tail2[1]) {
00343     e2_Ymax= head2[1];
00344     e2_Ymin= tail2[1];
00345   }
00346   else{
00347     e2_Ymax = tail2[1];
00348     e2_Ymin = head2[1];
00349   }
00350 
00351   
00352   /*Real e1_Ymax = max(head1[1], tail1[1]);*/ /*max(e1->head()[1], e1->tail()[1]);*/
00353   /*Real e1_Ymin = min(head1[1], tail1[1]);*/ /*min(e1->head()[1], e1->tail()[1]);*/
00354   /*Real e2_Ymax = max(head2[1], tail2[1]);*/ /*max(e2->head()[1], e2->tail()[1]);*/
00355   /*Real e2_Ymin = min(head2[1], tail2[1]);*/ /*min(e2->head()[1], e2->tail()[1]);*/
00356 
00357   Real Ymax = min(e1_Ymax, e2_Ymax);
00358   Real Ymin = max(e1_Ymin, e2_Ymin);
00359     
00360   Real y = 0.5*(Ymax + Ymin);
00361 
00362 /*  Real x1 = intersectHoriz(e1->head()[0], e1->head()[1], e1->tail()[0], e1->tail()[1], y);
00363   Real x2 = intersectHoriz(e2->head()[0], e2->head()[1], e2->tail()[0], e2->tail()[1], y);
00364 */
00365 /*
00366   Real x1 = intersectHoriz(h10, h11, t10, t11, y);
00367   Real x2 = intersectHoriz(h20, h21, t20, t21, y);
00368 */
00369   Real x1 = intersectHoriz(head1[0], head1[1], tail1[0], tail1[1], y);
00370   Real x2 = intersectHoriz(head2[0], head2[1], tail2[0], tail2[1], y);
00371 
00372   if(x1<= x2) return -1;
00373   else return 1;
00374 }
00375 
00376 Int  compChains(monoChain* mc1, monoChain* mc2)
00377 {
00378   Real y;
00379   assert(mc1->isKey || mc2->isKey);
00380   if(mc1->isKey)
00381     y = mc1->keyY;
00382   else
00383     y = mc2->keyY;
00384   directedLine *d1 = mc1->find(y);
00385   directedLine *d2 = mc2->find(y);
00386   mc2->find(y);
00387 //  Real x1 = mc1->chainIntersectHoriz(y);
00388 //  Real x2 = mc2->chainIntersectHoriz(y);
00389   return   compEdges(d1, d2);
00390 }
00391 
00392 //this function modifies current for efficiency
00393 directedLine* monoChain::find(Real y)
00394 {
00395   directedLine *ret;
00396   directedLine *temp;
00397   assert(current->head()[1] <= y);
00398   if(isIncrease)
00399     {
00400       assert(chainTail->head()[1] >=y);
00401       for(temp=current; temp!=chainTail; temp = temp->getNext())
00402     {
00403       if(temp->head()[1] > y)
00404         break;
00405     }
00406       current = temp->getPrev();
00407       ret = current;
00408     }
00409   else
00410     {
00411       for(temp=current; temp != chainHead; temp = temp->getPrev())
00412     {
00413       if(temp->head()[1] > y)
00414         break;
00415     }
00416       current = temp->getNext();
00417       ret = temp;
00418     }
00419   return ret;  
00420 }
00421 
00422 void monoChain::printOneChain()
00423 {
00424   directedLine* temp;
00425   for(temp = chainHead; temp != chainTail; temp = temp->getNext())
00426     {
00427       printf("(%f,%f) ", temp->head()[0], temp->head()[1]);
00428     }
00429   printf("(%f,%f) \n", chainTail->head()[0], chainTail->head()[1]);  
00430 }
00431 
00432 void monoChain::printChainLoop()
00433 {
00434   monoChain* temp;
00435   this->printOneChain();
00436   for(temp = next; temp != this; temp = temp->next)
00437     {
00438       temp->printOneChain();
00439     }
00440   printf("\n");
00441 }
00442 
00443 void monoChain::printAllLoops()
00444 {
00445   monoChain* temp;
00446   for(temp=this; temp != NULL; temp = temp->nextPolygon)
00447     temp->printChainLoop();
00448 }
00449 
00450 //return 1 if error occures
00451 Int MC_sweepY(Int nVertices, monoChain** sortedVertices, sweepRange** ret_ranges)
00452 {
00453   Int i;
00454   Real keyY;
00455   Int errOccur=0;
00456 //printf("enter MC_sweepY\n");
00457 //printf("nVertices=%i\n", nVertices);
00458   /*for each vertex in the sorted list, update the binary search tree.
00459    *and store the range information for each vertex.
00460    */
00461   treeNode* searchTree = NULL;
00462 //printf("nVertices=%i\n", nVertices);
00463   for(i=0; i<nVertices; i++)
00464     {
00465       monoChain* vert = sortedVertices[i];
00466       keyY = vert->getHead()->head()[1]; //the sweep line
00467       directedLine *dline = vert->getHead();
00468       directedLine *dlinePrev = dline->getPrev();
00469       if(isBelow(dline, dline) && isBelow(dline, dlinePrev))
00470     {
00471 //printf("case 1\n");
00472       //this<v and prev < v
00473       //delete both edges
00474       vert->isKey = 1;
00475       vert->keyY = keyY;
00476       treeNode* thisNode = TreeNodeFind(searchTree, vert, (Int (*) (void *, void *))compChains);
00477       vert->isKey = 0;
00478 
00479       vert->getPrev()->isKey = 1;
00480       vert->getPrev()->keyY = keyY;
00481       treeNode* prevNode = TreeNodeFind(searchTree, vert->getPrev(), (Int (*) (void *, void *))compChains);
00482       vert->getPrev()->isKey = 0;
00483 
00484       if(cuspType(dline) == 1)//interior cusp
00485         {
00486 
00487           treeNode* leftEdge = TreeNodePredecessor(prevNode);
00488           treeNode* rightEdge = TreeNodeSuccessor(thisNode);
00489           if(leftEdge == NULL ||  rightEdge == NULL)
00490         {
00491           errOccur = 1;
00492           goto JUMP_HERE;
00493         }
00494 
00495           directedLine* leftEdgeDline = ((monoChain* ) leftEdge->key)->find(keyY);
00496 
00497 
00498 
00499           directedLine* rightEdgeDline = ((monoChain* ) rightEdge->key)->find(keyY);
00500 
00501           ret_ranges[i] = sweepRangeMake(leftEdgeDline, 1, rightEdgeDline, 1);
00502         }
00503       else /*exterior cusp*/
00504         {
00505           ret_ranges[i] = sweepRangeMake( dline, 1, dlinePrev, 1);
00506         }
00507 
00508       searchTree = TreeNodeDeleteSingleNode(searchTree, thisNode);
00509       searchTree = TreeNodeDeleteSingleNode(searchTree, prevNode);
00510 
00511     }
00512       else if(isAbove(dline, dline) && isAbove(dline, dlinePrev))
00513     {
00514 //printf("case 2\n");
00515       //insert both edges
00516       treeNode* thisNode = TreeNodeMake(vert);
00517       treeNode* prevNode = TreeNodeMake(vert->getPrev());
00518       
00519       vert->isKey = 1;
00520           vert->keyY = keyY;
00521       searchTree = TreeNodeInsert(searchTree, thisNode, (Int (*) (void *, void *))compChains);
00522           vert->isKey = 0;
00523 
00524           vert->getPrev()->isKey = 1;
00525           vert->getPrev()->keyY = keyY;
00526       searchTree = TreeNodeInsert(searchTree, prevNode, (Int (*) (void *, void *))compChains);
00527           vert->getPrev()->isKey = 0;
00528 
00529       if(cuspType(dline) == 1) //interior cusp
00530         {
00531 //printf("cuspType is 1\n");
00532           treeNode* leftEdge = TreeNodePredecessor(thisNode);
00533           treeNode* rightEdge = TreeNodeSuccessor(prevNode);
00534               if(leftEdge == NULL || rightEdge == NULL)
00535         {
00536           errOccur = 1;
00537           goto JUMP_HERE;
00538         }
00539 //printf("leftEdge is %i, rightEdge is %i\n", leftEdge, rightEdge);
00540           directedLine* leftEdgeDline = ((monoChain*) leftEdge->key)->find(keyY);
00541           directedLine* rightEdgeDline = ((monoChain*) rightEdge->key)->find(keyY);
00542           ret_ranges[i] = sweepRangeMake( leftEdgeDline, 1, rightEdgeDline, 1);
00543         }
00544       else //exterior cusp
00545         {
00546 //printf("cuspType is not 1\n");
00547           ret_ranges[i] = sweepRangeMake(dlinePrev, 1, dline, 1);
00548         }
00549     }
00550       else
00551     {     
00552 //printf("%i,%i\n", isAbove(dline, dline), isAbove(dline, dlinePrev));
00553       errOccur = 1;
00554       goto JUMP_HERE;
00555       
00556       fprintf(stderr, "error in MC_sweepY\n");
00557       exit(1);
00558     }
00559     }
00560 
00561  JUMP_HERE:
00562   //finally clean up space: delete  the search tree
00563   TreeNodeDeleteWholeTree(searchTree);
00564   return errOccur;
00565 }
00566       
00567 void MC_findDiagonals(Int total_num_edges, monoChain** sortedVertices,
00568            sweepRange** ranges, Int& num_diagonals, 
00569            directedLine** diagonal_vertices)
00570 {
00571   Int i,j,k;
00572   k=0;
00573   //reset 'current' of all the monoChains
00574   for(i=0; i<total_num_edges; i++)
00575     sortedVertices[i]->resetCurrent();
00576   
00577   for(i=0; i<total_num_edges; i++)
00578     {
00579       directedLine* vert = sortedVertices[i]->getHead();
00580       directedLine* thisEdge = vert;
00581       directedLine* prevEdge = vert->getPrev();
00582       if(isBelow(vert, thisEdge) && isBelow(vert, prevEdge) && compEdges(prevEdge, thisEdge)<0)
00583     {
00584       //this is an upward interior cusp
00585       diagonal_vertices[k++] = vert;
00586 
00587       directedLine* leftEdge = ranges[i]->left;
00588       directedLine* rightEdge = ranges[i]->right;
00589       
00590       directedLine* leftVert = leftEdge;
00591       directedLine* rightVert = rightEdge->getNext();
00592       assert(leftVert->head()[1] >= vert->head()[1]);
00593       assert(rightVert->head()[1] >= vert->head()[1]);
00594       directedLine* minVert = (leftVert->head()[1] <= rightVert->head()[1])?leftVert:rightVert;
00595       Int found = 0;
00596       for(j=i+1; j<total_num_edges; j++)
00597         {
00598           if(sortedVertices[j]->getHead()->head()[1] > minVert->head()[1])
00599         break;
00600           
00601           if(sweepRangeEqual(ranges[i], ranges[j]))
00602         {
00603           found = 1;
00604           break;
00605         }
00606         }
00607 
00608       if(found)
00609         diagonal_vertices[k++] = sortedVertices[j]->getHead();
00610       else
00611         diagonal_vertices[k++] = minVert;
00612     }     
00613       else if(isAbove(vert, thisEdge) && isAbove(vert, prevEdge) && compEdges(prevEdge, thisEdge)>0)
00614     {
00615       //downward interior cusp
00616       diagonal_vertices[k++] = vert;
00617       directedLine* leftEdge = ranges[i]->left;
00618       directedLine* rightEdge = ranges[i]->right;
00619       directedLine* leftVert = leftEdge->getNext();
00620       directedLine* rightVert = rightEdge;
00621       assert(leftVert->head()[1] <= vert->head()[1]);
00622       assert(rightVert->head()[1] <= vert->head()[1]);
00623       directedLine* maxVert = (leftVert->head()[1] > rightVert->head()[1])? leftVert:rightVert;
00624       Int found=0;
00625       for(j=i-1; j>=0; j--)
00626         {
00627           if(sortedVertices[j]->getHead()->head()[1] < maxVert->head()[1])
00628         break;
00629           if(sweepRangeEqual(ranges[i], ranges[j]))
00630         {
00631           found = 1;
00632           break;
00633         }
00634         }
00635       if(found)
00636         diagonal_vertices[k++] = sortedVertices[j]->getHead();
00637       else
00638         diagonal_vertices[k++] = maxVert;
00639     }
00640     }
00641   num_diagonals = k/2;
00642 }
00643       
00644       
00645         
00646 
00647 directedLine* MC_partitionY(directedLine *polygons, sampledLine **retSampledLines)
00648 {
00649 //printf("enter mc_partitionY\n");
00650   Int total_num_chains = 0;
00651   monoChain* loopList = directedLineLoopListToMonoChainLoopList(polygons);
00652   monoChain** array = loopList->toArrayAllLoops(total_num_chains);
00653 
00654   if(total_num_chains<=2) //there is just one single monotone polygon
00655     {
00656       loopList->deleteLoopList();
00657       free(array); 
00658       *retSampledLines = NULL;
00659       return polygons;
00660     }
00661 
00662 //loopList->printAllLoops();
00663 //printf("total_num_chains=%i\n", total_num_chains);
00664   quicksort( (void**)array, 0, total_num_chains-1, (Int (*)(void*, void*))compChainHeadInY);
00665 //printf("after quicksort\n");  
00666 
00667   sweepRange** ranges = (sweepRange**)malloc(sizeof(sweepRange*) * (total_num_chains));
00668   assert(ranges);
00669 
00670   if(MC_sweepY(total_num_chains, array, ranges))
00671     {
00672       loopList->deleteLoopList();
00673       free(array);
00674       free(ranges);
00675       *retSampledLines = NULL;
00676       return NULL;
00677     }
00678 //printf("after MC_sweepY\n");
00679 
00680 
00681   Int num_diagonals;
00682   /*number diagonals is < total_num_edges*total_num_edges*/
00683   directedLine** diagonal_vertices = (directedLine**) malloc(sizeof(directedLine*) * total_num_chains*2/*total_num_edges*/);
00684   assert(diagonal_vertices);
00685 
00686 //printf("before call MC_findDiagonales\n");
00687 
00688   MC_findDiagonals(total_num_chains, array, ranges, num_diagonals, diagonal_vertices);
00689 //printf("after call MC_findDia, num_diagnla=%i\n", num_diagonals);
00690 
00691   directedLine* ret_polygons = polygons;
00692   sampledLine* newSampledLines = NULL;
00693   Int i,k;
00694 
00695   num_diagonals=deleteRepeatDiagonals(num_diagonals, diagonal_vertices, diagonal_vertices);
00696 
00697 
00698 
00699 //drawDiagonals(num_diagonals, diagonal_vertices);
00700 //printf("diagoanls are \n");
00701 //for(i=0; i<num_diagonals; i++)
00702 //  {
00703 //    printf("(%f,%f)\n", diagonal_vertices[2*i]->head()[0], diagonal_vertices[2*i]->head()[1]);
00704 //    printf("**(%f,%f)\n", diagonal_vertices[2*i+1]->head()[0], diagonal_vertices[2*i+1]->head()[1]);
00705 //  }
00706 
00707   Int *removedDiagonals=(Int*)malloc(sizeof(Int) * num_diagonals);
00708   for(i=0; i<num_diagonals; i++)
00709     removedDiagonals[i] = 0;
00710 //  printf("first pass\n");
00711 
00712 
00713  for(i=0,k=0; i<num_diagonals; i++,k+=2)
00714     {
00715 
00716 
00717       directedLine* v1=diagonal_vertices[k];
00718       directedLine* v2=diagonal_vertices[k+1];
00719       directedLine* ret_p1;
00720       directedLine* ret_p2;
00721       
00722       /*we ahve to determine whether v1 and v2 belong to the same polygon before
00723        *their structure are modified by connectDiagonal().
00724        */
00725 /*
00726       directedLine *root1 = v1->findRoot();
00727       directedLine *root2 = v2->findRoot();
00728       assert(root1);      
00729       assert(root2);
00730 */
00731 
00732 directedLine*  root1 = v1->rootLinkFindRoot();
00733 directedLine*  root2 = v2->rootLinkFindRoot();
00734 
00735       if(root1 != root2)
00736     {
00737 
00738       removedDiagonals[i] = 1;
00739       sampledLine* generatedLine;
00740 
00741 
00742 
00743       v1->connectDiagonal(v1,v2, &ret_p1, &ret_p2, &generatedLine, ret_polygons);
00744 
00745 
00746 
00747       newSampledLines = generatedLine->insert(newSampledLines);
00748 /*
00749       ret_polygons = ret_polygons->cutoffPolygon(root1);
00750 
00751       ret_polygons = ret_polygons->cutoffPolygon(root2);
00752       ret_polygons = ret_p1->insertPolygon(ret_polygons);
00753 root1->rootLinkSet(ret_p1);
00754 root2->rootLinkSet(ret_p1);
00755 ret_p1->rootLinkSet(NULL);
00756 ret_p2->rootLinkSet(ret_p1);
00757 */
00758       ret_polygons = ret_polygons->cutoffPolygon(root2);
00759 
00760 
00761 
00762 root2->rootLinkSet(root1);
00763 ret_p1->rootLinkSet(root1);
00764 ret_p2->rootLinkSet(root1);
00765 
00766        /*now that we have connected the diagonal v1 and v2, 
00767         *we have to check those unprocessed diagonals which 
00768         *have v1 or v2 as an end point. Notice that the head of v1
00769         *has the same coodinates as the head of v2->prev, and the head of
00770         *v2 has the same coordinate as the head of v1->prev. 
00771         *Suppose these is a diagonal (v1, x). If (v1,x) is still a valid
00772         *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  
00773         *replaced by (v2->prev, x), that is, x is on the left of 
00774         * v2->prev->prev->head, v2->prev->head, v2->prev->tail.
00775         */
00776         Int ii, kk;
00777         for(ii=0, kk=0; ii<num_diagonals; ii++, kk+=2)
00778       if( removedDiagonals[ii]==0)
00779         {
00780           directedLine* d1=diagonal_vertices[kk];
00781           directedLine* d2=diagonal_vertices[kk+1];
00782           /*check d1, and replace diagonal_vertices[kk] if necessary*/
00783           if(d1 == v1) {
00784         /*check if d2 is to left of v1->prev->head:v1->head:v1->tail*/
00785         if(! pointLeft2Lines(v1->getPrev()->head(), 
00786                      v1->head(), v1->tail(), d2->head()))
00787           {
00788 /*
00789             assert(pointLeft2Lines(v2->getPrev()->getPrev()->head(),
00790                        v2->getPrev()->head(), 
00791                        v2->getPrev()->tail(), d2->head()));
00792 */
00793             diagonal_vertices[kk] = v2->getPrev();
00794           }
00795           }
00796           if(d1 == v2) {
00797         /*check if d2 is to left of v2->prev->head:v2->head:v2->tail*/
00798         if(! pointLeft2Lines(v2->getPrev()->head(),
00799                      v2->head(), v2->tail(), d2->head()))
00800           {
00801 /*
00802             assert(pointLeft2Lines(v1->getPrev()->getPrev()->head(),
00803                        v1->getPrev()->head(),
00804                        v1->getPrev()->tail(), d2->head()));
00805 */
00806             diagonal_vertices[kk] = v1->getPrev();
00807           }
00808           }
00809           /*check d2 and replace diagonal_vertices[k+1] if necessary*/
00810           if(d2 == v1) {
00811         /*check if d1 is to left of v1->prev->head:v1->head:v1->tail*/
00812         if(! pointLeft2Lines(v1->getPrev()->head(), 
00813                      v1->head(), v1->tail(), d1->head()))
00814           {
00815 /*          assert(pointLeft2Lines(v2->getPrev()->getPrev()->head(),
00816                        v2->getPrev()->head(), 
00817                        v2->getPrev()->tail(), d1->head()));
00818 */
00819             diagonal_vertices[kk+1] = v2->getPrev();
00820           }
00821           }
00822           if(d2 == v2) {
00823         /*check if d1 is to left of v2->prev->head:v2->head:v2->tail*/
00824         if(! pointLeft2Lines(v2->getPrev()->head(),
00825                      v2->head(), v2->tail(), d1->head()))
00826           {
00827 /*          assert(pointLeft2Lines(v1->getPrev()->getPrev()->head(),
00828                        v1->getPrev()->head(),
00829                        v1->getPrev()->tail(), d1->head()));
00830 */
00831             diagonal_vertices[kk+1] = v1->getPrev();
00832           }
00833           }
00834         }                                  
00835 }/*end if (root1 not equal to root 2)*/
00836 }
00837 
00838   /*second pass,  now all diagoals should belong to the same polygon*/
00839 //printf("second pass: \n");
00840 
00841 //  for(i=0; i<num_diagonals; i++)
00842 //    printf("%i ", removedDiagonals[i]);
00843 
00844 
00845   for(i=0,k=0; i<num_diagonals; i++, k += 2)
00846     if(removedDiagonals[i] == 0) 
00847       {
00848 
00849 
00850     directedLine* v1=diagonal_vertices[k];
00851     directedLine* v2=diagonal_vertices[k+1];
00852 
00853 
00854 
00855     directedLine* ret_p1;
00856     directedLine* ret_p2;
00857 
00858     /*we ahve to determine whether v1 and v2 belong to the same polygon before
00859      *their structure are modified by connectDiagonal().
00860      */
00861     directedLine *root1 = v1->findRoot();
00862 /*
00863     directedLine *root2 = v2->findRoot();
00864 
00865 
00866 
00867     assert(root1);      
00868     assert(root2);      
00869     assert(root1 == root2);
00870   */    
00871     sampledLine* generatedLine;
00872 
00873 
00874 
00875     v1->connectDiagonal(v1,v2, &ret_p1, &ret_p2, &generatedLine, ret_polygons);
00876     newSampledLines = generatedLine->insert(newSampledLines);
00877 
00878     ret_polygons = ret_polygons->cutoffPolygon(root1);
00879 
00880     ret_polygons = ret_p1->insertPolygon(ret_polygons);
00881 
00882     ret_polygons = ret_p2->insertPolygon(ret_polygons);
00883 
00884 
00885 
00886     for(Int j=i+1; j<num_diagonals; j++) 
00887       {
00888         if(removedDiagonals[j] ==0)
00889           {
00890 
00891         directedLine* temp1=diagonal_vertices[2*j];
00892         directedLine* temp2=diagonal_vertices[2*j+1];
00893                if(temp1==v1 || temp1==v2 || temp2==v1 || temp2==v2)
00894         if(! temp1->samePolygon(temp1, temp2))
00895           {
00896             /*if temp1 and temp2 are in different polygons, 
00897              *then one of them must be v1 or v2.
00898              */
00899 
00900 
00901 
00902             assert(temp1==v1 || temp1 == v2 || temp2==v1 || temp2 ==v2);
00903             if(temp1==v1) 
00904               {
00905             diagonal_vertices[2*j] = v2->getPrev();
00906               }
00907             if(temp2==v1)
00908               {
00909             diagonal_vertices[2*j+1] = v2->getPrev();
00910               }
00911             if(temp1==v2)
00912               {
00913             diagonal_vertices[2*j] = v1->getPrev();           
00914               }
00915             if(temp2==v2)
00916               {
00917             diagonal_vertices[2*j+1] = v1->getPrev();
00918               }
00919           }
00920           }
00921       }      
00922 
00923       }
00924 
00925 
00926   //clean up
00927   loopList->deleteLoopList();
00928   free(array);
00929   free(ranges);
00930   free(diagonal_vertices);
00931   free(removedDiagonals);
00932 
00933   *retSampledLines = newSampledLines;
00934   return ret_polygons;
00935 }
00936       
00937 

Generated on Sun May 27 2012 04:23:48 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.