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

monoPolyPart.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: 2006-03-12 00:07:02 +0000 (Sun, 12 Mar 2006) $ $Revision: 1.1 $
00035 */
00036 /*
00037  *monoPolyPart.C
00038  *
00039  *To partition a v-monotone polygon into some uv-monotone polygons.
00040  *The algorithm is different from the general monotone partition algorithm.
00041  *while the general monotone partition algorithm works for this special case,
00042  *but it is more expensive (O(nlogn)). The algorithm implemented here takes
00043  *advantage of the fact that the input is a v-monotone polygon and it is
00044  *conceptually simpler and  computationally cheaper (a linear time algorithm).
00045  *The algorithm is described in Zicheng Liu's  paper
00046  * "Quality-Oriented Linear Time Tessellation".
00047  */
00048 
00049 #include <stdlib.h>
00050 #include <stdio.h>
00051 #include "directedLine.h"
00052 #include "monoPolyPart.h"
00053 
00054 /*a vertex is u_maximal if both of its two neightbors are to the left of this 
00055  *vertex
00056  */
00057 static Int is_u_maximal(directedLine* v)
00058 {
00059   if (compV2InX(v->getPrev()->head(), v->head()) == -1 &&
00060       compV2InX(v->getNext()->head(), v->head()) == -1)
00061     return 1;
00062   else
00063     return 0;
00064 }
00065 
00066 /*a vertex is u_minimal if both of its two neightbors are to the right of this 
00067  *vertex
00068  */
00069 static Int is_u_minimal(directedLine* v)
00070 {
00071   if (compV2InX(v->getPrev()->head(), v->head()) == 1 &&
00072       compV2InX(v->getNext()->head(), v->head()) == 1)
00073     return 1;
00074   else
00075     return 0;
00076 }
00077 
00078 /*poly: a v-monotone polygon
00079  *return: a linked list of uv-monotone polygons.
00080  */
00081 directedLine* monoPolyPart(directedLine* polygon)
00082 {
00083   //handle special cases:
00084   if(polygon == NULL)
00085     return NULL;
00086   if(polygon->getPrev() == polygon)
00087     return polygon;
00088   if(polygon->getPrev() == polygon->getNext())
00089     return polygon;
00090   if(polygon->getPrev()->getPrev() == polygon->getNext())
00091     return polygon;
00092 
00093   //find the top and bottom vertexes
00094   directedLine *tempV, *topV, *botV;
00095   topV = botV = polygon;
00096   for(tempV = polygon->getNext(); tempV != polygon; tempV = tempV->getNext())
00097     {
00098       if(compV2InY(topV->head(), tempV->head())<0) {
00099     topV = tempV;
00100       }
00101       if(compV2InY(botV->head(), tempV->head())>0) {
00102     botV = tempV;
00103       }
00104     }
00105 
00106   //initilization
00107   directedLine *A, *B, *C, *D, *G, *H;
00108   //find A:the first u_maximal vertex on the left chain
00109   //and C: the left most vertex between top and A
00110   A = NULL;
00111   C = topV;
00112   for(tempV=topV->getNext(); tempV != botV; tempV = tempV->getNext())
00113     {
00114       if(tempV->head()[0] < C->head()[0])
00115     C = tempV;
00116 
00117       if(is_u_maximal(tempV))
00118     {
00119       A = tempV;
00120       break;
00121     }
00122     }
00123   if(A == NULL)
00124     {
00125       A = botV;
00126       if(A->head()[0] < C->head()[0])
00127     C = A;
00128     }
00129       
00130   //find B: the first u_minimal vertex on the right chain
00131   //and  D: the right most vertex between top and B
00132   B = NULL;
00133   D = topV;
00134   for(tempV=topV->getPrev(); tempV != botV; tempV = tempV->getPrev())
00135     {
00136       if(tempV->head()[0] > D->head()[0])
00137     D = tempV;
00138       if(is_u_minimal(tempV))
00139     {
00140       B = tempV;
00141       break;
00142     }
00143     }
00144   if(B == NULL)
00145     {
00146       B = botV;
00147       if(B->head()[0] > D->head()[0])
00148     D = B;
00149     }
00150 
00151   //error checking XXX
00152   if(C->head()[0] >= D->head()[0])
00153     return polygon;
00154 
00155   //find G on the left chain that is right above B
00156   for(tempV=topV; compV2InY(tempV->head(), B->head()) == 1;  tempV=tempV->getNext());
00157   G = tempV->getPrev();
00158   //find H on the right chain that is right above A
00159   for(tempV=topV; compV2InY(tempV->head(), A->head()) == 1; tempV = tempV->getPrev());
00160   H = tempV->getNext();
00161   
00162   //Main Loop
00163   directedLine* ret = NULL;
00164   directedLine* currentPolygon = polygon;
00165   while(1)
00166     {
00167       //if both B and D are equal to botV, then this polygon is already 
00168       //u-monotone
00169       if(A == botV && B == botV)
00170     {
00171       ret = currentPolygon->insertPolygon(ret);
00172       return ret;
00173     }
00174       else //not u-monotone
00175     {
00176       directedLine *ret_p1, *ret_p2;
00177       if(compV2InY(A->head(),B->head()) == 1) //A is above B
00178         {
00179           directedLine* E = NULL;
00180           for(tempV = C; tempV != D; tempV = tempV->getPrev())
00181         {
00182           if(tempV->head()[0] >= A->head()[0])
00183             {
00184               E = tempV;
00185               break;
00186             }
00187         }
00188 
00189           if(E == NULL)
00190         E = D;
00191           if(E->head()[0]> H->head()[0])
00192         E = H;
00193           //connect AE and output polygon ECA
00194           polygon->connectDiagonal_2slines(A, E,
00195                            &ret_p1,
00196                            &ret_p2,
00197                            NULL);
00198           ret = ret_p2->insertPolygon(ret);
00199           currentPolygon = ret_p1;
00200 
00201           if(E == D)
00202         D = ret_p1;
00203           if(E == H)
00204         H = ret_p1;
00205               if(G->head()[1] >= A->head()[1])
00206         G = A;
00207           //update A to be the next u-maxiaml vertex on left chain
00208           //and C the leftmost vertex between the old A and the new A
00209           C = A;
00210           for(tempV = A->getNext(); tempV != botV; tempV = tempV->getNext())
00211         {
00212 
00213           if(tempV->head()[0] < C->head()[0])
00214             C = tempV;
00215           if(is_u_maximal(tempV))
00216             {
00217               A = tempV;
00218               break;
00219             }
00220         }
00221 
00222           if(tempV == botV)
00223         {
00224           A = botV;
00225           if(botV->head()[0] < C->head()[0])
00226             C = botV;
00227         }
00228           //update H
00229 
00230               if(A == botV)
00231         H = botV;
00232               else
00233         {
00234           for(tempV = H; compV2InY(tempV->head(), A->head()) == 1; tempV = tempV->getPrev());
00235           H = tempV->getNext();
00236         }
00237 
00238         }
00239       else //A is below B
00240         {
00241 
00242           directedLine* F = NULL;
00243           for(tempV = D; tempV != C; tempV = tempV->getNext())
00244         {
00245           if(tempV->head()[0] <= B->head()[0])
00246             {
00247               F = tempV;
00248               break;
00249             }
00250         }
00251           if(F == NULL)
00252         F = C;
00253           if(F->head()[0] < G->head()[0])
00254         F = G;
00255 
00256           //connect FB
00257           polygon->connectDiagonal_2slines(F, B, 
00258                            &ret_p1,
00259                            &ret_p2,
00260                            NULL);
00261           ret = ret_p2->insertPolygon(ret);
00262           currentPolygon = ret_p1;
00263           B = ret_p1;
00264           if(H ->head()[1] >= B->head()[1])
00265         H = ret_p1;
00266 
00267           //update B to be the next u-minimal vertex on right chain
00268           //and D the rightmost vertex between the old B and the new B
00269           D = B;
00270           for(tempV = B->getPrev(); tempV != botV; tempV = tempV->getPrev())
00271         {
00272           if(tempV->head()[0] > D->head()[0])
00273             D = tempV;
00274           if(is_u_minimal(tempV))
00275             {
00276               B = tempV;
00277               break;
00278             }
00279         }
00280           if(tempV == botV)
00281         {
00282           B = botV;
00283           if(botV->head()[0] > D->head()[0])
00284             D = botV;
00285         }
00286           //update G
00287               if(B == botV)
00288         G = botV; 
00289               else
00290         {
00291           for(tempV = G; compV2InY(tempV->head(), B->head()) == 1;  tempV = tempV->getNext());
00292           G = tempV->getPrev();
00293         }
00294         } //end of A is below B
00295     } //end not u-monotone  
00296     } //end of main loop
00297 }
00298 
00299 
00300 

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.