Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > DoxygenmonoPolyPart.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
1.7.6.1
|