Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > DoxygendirectedLine.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 */ 00035 /* 00036 */ 00037 00038 #include <stdlib.h> 00039 #include <stdio.h> 00040 #include <math.h> 00041 #include "glimports.h" 00042 #include "zlassert.h" 00043 00044 #include "quicksort.h" 00045 #include "directedLine.h" 00046 #include "polyDBG.h" 00047 00048 #ifdef __WATCOMC__ 00049 #pragma warning 726 10 00050 #endif 00051 00052 //we must return the newLine 00053 directedLine* directedLine::deleteChain(directedLine* begin, directedLine* end) 00054 { 00055 if(begin->head()[0] == end->tail()[0] && 00056 begin->head()[1] == end->tail()[1] 00057 ) 00058 { 00059 directedLine *ret = begin->prev; 00060 begin->prev->next = end->next; 00061 end->next->prev = begin->prev; 00062 delete begin->sline; 00063 delete end->sline; 00064 delete begin; 00065 delete end; 00066 00067 return ret; 00068 } 00069 00070 directedLine* newLine; 00071 sampledLine* sline = new sampledLine(begin->head(), end->tail()); 00072 newLine = new directedLine(INCREASING, sline); 00073 directedLine *p = begin->prev; 00074 directedLine *n = end->next; 00075 p->next = newLine; 00076 n->prev = newLine; 00077 newLine->prev = p; 00078 newLine->next = n; 00079 00080 delete begin->sline; 00081 delete end->sline; 00082 delete begin; 00083 delete end; 00084 return newLine; 00085 } 00086 00087 00088 void directedLine::deleteSingleLine(directedLine* dline) 00089 { 00090 //make sure that dline->prev->tail is the same as 00091 //dline->next->head. This is for numerical erros. 00092 //for example, if we delete a line which is almost degeneate 00093 //within (epsilon), then we want to make that the polygon after deletion 00094 //is still a valid polygon 00095 00096 dline->next->head()[0] = dline->prev->tail()[0]; 00097 dline->next->head()[1] = dline->prev->tail()[1]; 00098 00099 dline->prev->next = dline->next; 00100 dline->next->prev = dline->prev; 00101 00102 delete dline; 00103 00104 } 00105 00106 static Int myequal(Real a[2], Real b[2]) 00107 { 00108 /* 00109 if(a[0]==b[0] && a[1] == b[1]) 00110 return 1; 00111 else 00112 return 0; 00113 */ 00114 00115 00116 if(fabs(a[0]-b[0]) < 0.00001 && 00117 fabs(a[1]-b[1]) < 0.00001) 00118 return 1; 00119 else 00120 return 0; 00121 00122 } 00123 00124 directedLine* directedLine::deleteDegenerateLines() 00125 { 00126 //if there is only one edge or two edges, don't do anything 00127 if(this->next == this) 00128 return this; 00129 if(this->next == this->prev) 00130 return this; 00131 00132 //find a nondegenerate line 00133 directedLine* temp; 00134 directedLine* first = NULL; 00135 if(! myequal(head(), tail())) 00136 /* 00137 if(head()[0] != tail()[0] || 00138 head()[1] != tail()[1]) 00139 */ 00140 first = this; 00141 else 00142 { 00143 for(temp = this->next; temp != this; temp = temp->next) 00144 { 00145 /* 00146 if(temp->head()[0] != temp->tail()[0] || 00147 temp->head()[1] != temp->tail()[1]) 00148 */ 00149 if(! myequal(temp->head(), temp->tail())) 00150 { 00151 first = temp; 00152 break; 00153 } 00154 00155 } 00156 } 00157 00158 //if there are no non-degenerate lines, then we simply return NULL. 00159 if(first == NULL) 00160 { 00161 deleteSinglePolygonWithSline(); 00162 return NULL; 00163 } 00164 00165 directedLine* tempNext = NULL; 00166 for(temp =first->next; temp != first; temp = tempNext) 00167 { 00168 tempNext = temp->getNext(); 00169 /* 00170 if(temp->head()[0] == temp->tail()[0] && 00171 temp->head()[1] == temp->tail()[1]) 00172 */ 00173 00174 if(myequal(temp->head(), temp->tail())) 00175 deleteSingleLine(temp); 00176 } 00177 return first; 00178 } 00179 00180 directedLine* directedLine::deleteDegenerateLinesAllPolygons() 00181 { 00182 directedLine* temp; 00183 directedLine *tempNext = NULL; 00184 directedLine* ret= NULL; 00185 directedLine* retEnd = NULL; 00186 for(temp=this; temp != NULL; temp = tempNext) 00187 { 00188 tempNext = temp->nextPolygon; 00189 temp->nextPolygon = NULL; 00190 if(ret == NULL) 00191 { 00192 ret = retEnd = temp->deleteDegenerateLines(); 00193 00194 } 00195 else 00196 { 00197 directedLine *newPolygon = temp->deleteDegenerateLines(); 00198 if(newPolygon != NULL) 00199 { 00200 retEnd->nextPolygon = temp->deleteDegenerateLines(); 00201 retEnd = retEnd->nextPolygon; 00202 } 00203 } 00204 } 00205 return ret; 00206 } 00207 00208 directedLine* directedLine::cutIntersectionAllPoly(int &cutOccur) 00209 { 00210 directedLine* temp; 00211 directedLine *tempNext = NULL; 00212 directedLine* ret= NULL; 00213 directedLine* retEnd = NULL; 00214 cutOccur = 0; 00215 for(temp=this; temp != NULL; temp = tempNext) 00216 { 00217 int eachCutOccur=0; 00218 tempNext = temp->nextPolygon; 00219 temp->nextPolygon = NULL; 00220 if(ret == NULL) 00221 { 00222 00223 ret = retEnd = DBG_cutIntersectionPoly(temp, eachCutOccur); 00224 if(eachCutOccur) 00225 cutOccur = 1; 00226 } 00227 else 00228 { 00229 00230 retEnd->nextPolygon = DBG_cutIntersectionPoly(temp, eachCutOccur); 00231 retEnd = retEnd->nextPolygon; 00232 if(eachCutOccur) 00233 cutOccur = 1; 00234 } 00235 } 00236 return ret; 00237 } 00238 00239 00240 void directedLine::deleteSinglePolygonWithSline() 00241 { 00242 directedLine *temp, *tempNext; 00243 prev->next = NULL; 00244 for(temp=this; temp != NULL; temp = tempNext) 00245 { 00246 tempNext = temp->next; 00247 delete temp->sline; 00248 delete temp; 00249 } 00250 } 00251 00252 void directedLine::deletePolygonListWithSline() 00253 { 00254 directedLine *temp, *tempNext; 00255 for(temp=this; temp != NULL; temp=tempNext) 00256 { 00257 tempNext = temp->nextPolygon; 00258 temp->deleteSinglePolygonWithSline(); 00259 } 00260 } 00261 00262 void directedLine::deleteSinglePolygon() 00263 { 00264 directedLine *temp, *tempNext; 00265 prev->next = NULL; 00266 for(temp=this; temp != NULL; temp = tempNext) 00267 { 00268 tempNext = temp->next; 00269 delete temp; 00270 } 00271 } 00272 00273 void directedLine::deletePolygonList() 00274 { 00275 directedLine *temp, *tempNext; 00276 for(temp=this; temp != NULL; temp=tempNext) 00277 { 00278 tempNext = temp->nextPolygon; 00279 temp->deleteSinglePolygon(); 00280 } 00281 } 00282 00283 00284 /*a loop by itself*/ 00285 directedLine::directedLine(short dir, sampledLine* sl) 00286 { 00287 direction = dir; 00288 sline = sl; 00289 next = this; 00290 prev = this; 00291 nextPolygon = NULL; 00292 // prevPolygon = NULL; 00293 rootBit = 0;/*important to initilzae to 0 meaning not root yet*/ 00294 00295 rootLink = NULL; 00296 00297 } 00298 00299 void directedLine::init(short dir, sampledLine* sl) 00300 { 00301 direction = dir; 00302 sline = sl; 00303 } 00304 00305 directedLine::directedLine() 00306 { 00307 next = this; 00308 prev = this; 00309 nextPolygon = NULL; 00310 rootBit = 0;/*important to initilzae to 0 meaning not root yet*/ 00311 rootLink = NULL; 00312 } 00313 00314 directedLine::~directedLine() 00315 { 00316 } 00317 00318 Real* directedLine::head() 00319 { 00320 00321 return (direction==INCREASING)? (sline->get_points())[0] : (sline->get_points())[sline->get_npoints()-1]; 00322 } 00323 00324 /*inline*/ Real* directedLine::getVertex(Int i) 00325 { 00326 return (direction==INCREASING)? (sline->get_points())[i] : (sline->get_points())[sline->get_npoints() - 1 -i]; 00327 } 00328 00329 Real* directedLine::tail() 00330 { 00331 return (direction==DECREASING)? (sline->get_points())[0] : (sline->get_points())[sline->get_npoints()-1]; 00332 } 00333 00334 /*insert a new line between prev and this*/ 00335 void directedLine::insert(directedLine* nl) 00336 { 00337 nl->next = this; 00338 nl->prev = prev; 00339 prev->next = nl; 00340 prev = nl; 00341 nl->rootLink = this; /*assuming that 'this' is the root!!!*/ 00342 } 00343 00344 Int directedLine::numEdges() 00345 { 00346 Int ret=0; 00347 directedLine* temp; 00348 if(next == this) return 1; 00349 00350 ret = 1; 00351 for(temp = next; temp != this; temp = temp->next) 00352 ret++; 00353 return ret; 00354 } 00355 00356 Int directedLine::numEdgesAllPolygons() 00357 { 00358 Int ret=0; 00359 directedLine* temp; 00360 for(temp=this; temp!= NULL; temp=temp->nextPolygon) 00361 { 00362 ret += temp->numEdges(); 00363 } 00364 return ret; 00365 } 00366 00367 /*return 1 if the double linked list forms a polygon. 00368 */ 00369 short directedLine::isPolygon() 00370 { 00371 directedLine* temp; 00372 00373 /*a polygon contains at least 3 edges*/ 00374 if(numEdges() <=2) return 0; 00375 00376 /*check this edge*/ 00377 if(! isConnected()) return 0; 00378 00379 /*check all other edges*/ 00380 for(temp=next; temp != this; temp = temp->next){ 00381 if(!isConnected()) return 0; 00382 } 00383 return 1; 00384 } 00385 00386 /*check if the head of this edge is connected to 00387 *the tail of the prev 00388 */ 00389 short directedLine::isConnected() 00390 { 00391 if( (head()[0] == prev->tail()[0]) && (head()[1] == prev->tail()[1])) 00392 return 1; 00393 else 00394 return 0; 00395 } 00396 00397 Int compV2InY(Real A[2], Real B[2]) 00398 { 00399 if(A[1] < B[1]) return -1; 00400 if(A[1] == B[1] && A[0] < B[0]) return -1; 00401 if(A[1] == B[1] && A[0] == B[0]) return 0; 00402 return 1; 00403 } 00404 00405 Int compV2InX(Real A[2], Real B[2]) 00406 { 00407 if(A[0] < B[0]) return -1; 00408 if(A[0] == B[0] && A[1] < B[1]) return -1; 00409 if(A[0] == B[0] && A[1] == B[1]) return 0; 00410 return 1; 00411 } 00412 00413 /*compare two vertices NOT lines! 00414 *A vertex is the head of a directed line. 00415 *(x_1, y_1) <= (x_2, y_2) if 00416 *either y_1 < y_2 00417 *or y_1 == y_2 && x_1 < x_2. 00418 *return -1 if this->head() <= nl->head(), 00419 *return 1 otherwise 00420 */ 00421 Int directedLine::compInY(directedLine* nl) 00422 { 00423 if(head()[1] < nl->head()[1]) return -1; 00424 if(head()[1] == nl->head()[1] && head()[0] < nl->head()[0]) return -1; 00425 return 1; 00426 } 00427 00428 /*compare two vertices NOT lines! 00429 *A vertex is the head of a directed line. 00430 *(x_1, y_1) <= (x_2, y_2) if 00431 *either x_1 < x_2 00432 *or x_1 == x_2 && y_1 < y_2. 00433 *return -1 if this->head() <= nl->head(), 00434 *return 1 otherwise 00435 */ 00436 Int directedLine::compInX(directedLine* nl) 00437 { 00438 if(head()[0] < nl->head()[0]) return -1; 00439 if(head()[0] == nl->head()[0] && head()[1] < nl->head()[1]) return -1; 00440 return 1; 00441 } 00442 00443 /*used by sort precedures 00444 */ 00445 static Int compInY2(directedLine* v1, directedLine* v2) 00446 { 00447 return v1->compInY(v2); 00448 } 00449 #ifdef NOT_USED 00450 static Int compInX(directedLine* v1, directedLine* v2) 00451 { 00452 return v1->compInX(v2); 00453 } 00454 #endif 00455 00456 /*sort all the vertices NOT the lines! 00457 *a vertex is the head of a directed line 00458 */ 00459 directedLine** directedLine::sortAllPolygons() 00460 { 00461 Int total_num_edges = 0; 00462 directedLine** array = toArrayAllPolygons(total_num_edges); 00463 quicksort( (void**)array, 0, total_num_edges-1, (Int (*)(void *, void *)) compInY2); 00464 00465 return array; 00466 } 00467 00468 void directedLine::printSingle() 00469 { 00470 if(direction == INCREASING) 00471 printf("direction is INCREASING\n"); 00472 else 00473 printf("direction is DECREASING\n"); 00474 printf("head=%f,%f)\n", head()[0], head()[1]); 00475 sline->print(); 00476 } 00477 00478 /*print one polygon*/ 00479 void directedLine::printList() 00480 { 00481 directedLine* temp; 00482 printSingle(); 00483 for(temp = next; temp!=this; temp=temp->next) 00484 temp->printSingle(); 00485 } 00486 00487 /*print all the polygons*/ 00488 void directedLine::printAllPolygons() 00489 { 00490 directedLine *temp; 00491 for(temp = this; temp!=NULL; temp = temp->nextPolygon) 00492 { 00493 printf("polygon:\n"); 00494 temp->printList(); 00495 } 00496 } 00497 00498 /*insert this polygon into the head of the old polygon List*/ 00499 directedLine* directedLine::insertPolygon(directedLine* oldList) 00500 { 00501 /*this polygon is a root*/ 00502 setRootBit(); 00503 if(oldList == NULL) return this; 00504 nextPolygon = oldList; 00505 /* oldList->prevPolygon = this;*/ 00506 return this; 00507 } 00508 00509 /*cutoff means delete. but we don't deallocate any space, 00510 *so we use cutoff instead of delete 00511 */ 00512 directedLine* directedLine::cutoffPolygon(directedLine *p) 00513 { 00514 directedLine* temp; 00515 directedLine* prev_polygon = NULL; 00516 if(p == NULL) return this; 00517 00518 for(temp=this; temp != p; temp = temp->nextPolygon) 00519 { 00520 if(temp == NULL) 00521 { 00522 fprintf(stderr, "in cutoffPolygon, not found\n"); 00523 exit(1); 00524 } 00525 prev_polygon = temp; 00526 } 00527 00528 /* prev_polygon = p->prevPolygon;*/ 00529 00530 p->resetRootBit(); 00531 if(prev_polygon == NULL) /*this is the one to cutoff*/ 00532 return nextPolygon; 00533 else { 00534 prev_polygon->nextPolygon = p->nextPolygon; 00535 return this; 00536 } 00537 } 00538 00539 Int directedLine::numPolygons() 00540 { 00541 if(nextPolygon == NULL) return 1; 00542 else return 1+nextPolygon->numPolygons(); 00543 } 00544 00545 00546 /*let array[index ...] denote 00547 *all the edges in this polygon 00548 *return the next available index of array. 00549 */ 00550 Int directedLine::toArraySinglePolygon(directedLine** array, Int index) 00551 { 00552 directedLine *temp; 00553 array[index++] = this; 00554 for(temp = next; temp != this; temp = temp->next) 00555 { 00556 array[index++] = temp; 00557 } 00558 return index; 00559 } 00560 00561 /*the space is allocated. The caller is responsible for 00562 *deallocate the space. 00563 *total_num_edges is set to be the total number of edges of all polygons 00564 */ 00565 directedLine** directedLine::toArrayAllPolygons(Int& total_num_edges) 00566 { 00567 total_num_edges=numEdgesAllPolygons(); 00568 directedLine** ret = (directedLine**) malloc(sizeof(directedLine*) * total_num_edges); 00569 assert(ret); 00570 00571 directedLine *temp; 00572 Int index = 0; 00573 for(temp=this; temp != NULL; temp=temp->nextPolygon) { 00574 index = temp->toArraySinglePolygon(ret, index); 00575 } 00576 return ret; 00577 } 00578 00579 /*assume the polygon is a simple polygon, return 00580 *the area enclosed by it. 00581 *if thee order is counterclock wise, the area is positive. 00582 */ 00583 Real directedLine::polyArea() 00584 { 00585 directedLine* temp; 00586 Real ret=0.0; 00587 Real x1,y1,x2,y2; 00588 x1 = this->head()[0]; 00589 y1 = this->head()[1]; 00590 x2 = this->next->head()[0]; 00591 y2 = this->next->head()[1]; 00592 ret = -(x2*y1-x1*y2); 00593 for(temp=this->next; temp!=this; temp = temp->next) 00594 { 00595 x1 = temp->head()[0]; 00596 y1 = temp->head()[1]; 00597 x2 = temp->next->head()[0]; 00598 y2 = temp->next->head()[1]; 00599 ret += -( x2*y1-x1*y2); 00600 } 00601 return Real(0.5)*ret; 00602 } 00603 00604 /*******************split or combine polygons begin********************/ 00605 /*conect a diagonal of a single simple polygon or two simple polygons. 00606 *If the two vertices v1 (head) and v2 (head) are in the same simple polygon, 00607 *then we actually split the simple polygon into two polygons. 00608 *If instead two vertices velong to two difference polygons, 00609 *then we combine the two polygons into one polygon. 00610 *It is upto the caller to decide whether this is a split or a 00611 *combination. 00612 * 00613 *Case Split: 00614 *split a single simple polygon into two simple polygons by 00615 *connecting a diagonal (two vertices). 00616 *v1, v2: the two vertices are the head() of the two directedLines. 00617 * this routine generates one new sampledLine which is returned in 00618 *generatedLine, 00619 *and it generates two directedLines returned in ret_p1 and ret_p2. 00620 *ret_p1 and ret_p2 are used as the entry to the two new polygons. 00621 *Notice the caller should not deallocate the space of v2 and v2 after 00622 *calling this function, since all of the edges are connected to 00623 *ret_p1 or ret_p2. 00624 * 00625 *combine: 00626 *combine two simpolygons into one by connecting one diagonal. 00627 *the returned polygon is returned in ret_p1. 00628 */ 00629 /*ARGSUSED*/ 00630 void directedLine::connectDiagonal(directedLine* v1, directedLine* v2, 00631 directedLine** ret_p1, 00632 directedLine** ret_p2, 00633 sampledLine** generatedLine, 00634 directedLine* polygonList ) 00635 { 00636 sampledLine *nsline = new sampledLine(2); 00637 00638 00639 00640 nsline->setPoint(0, v1->head()); 00641 nsline->setPoint(1, v2->head()); 00642 00643 00644 00645 /*the increasing line is from v1 head to v2 head*/ 00646 directedLine* newLineInc = new directedLine(INCREASING, nsline); 00647 00648 00649 00650 directedLine* newLineDec = new directedLine(DECREASING, nsline); 00651 00652 00653 directedLine* v1Prev = v1->prev; 00654 directedLine* v2Prev = v2->prev; 00655 00656 v1 ->prev = newLineDec; 00657 v2Prev ->next = newLineDec; 00658 newLineDec->next = v1; 00659 newLineDec->prev = v2Prev; 00660 00661 v2 ->prev = newLineInc; 00662 v1Prev ->next = newLineInc; 00663 newLineInc->next = v2; 00664 newLineInc->prev = v1Prev; 00665 00666 *ret_p1 = newLineDec; 00667 *ret_p2 = newLineInc; 00668 *generatedLine = nsline; 00669 } 00670 00671 //see the function connectDiangle 00672 /*ARGSUSED*/ 00673 void directedLine::connectDiagonal_2slines(directedLine* v1, directedLine* v2, 00674 directedLine** ret_p1, 00675 directedLine** ret_p2, 00676 directedLine* polygonList ) 00677 { 00678 sampledLine *nsline = new sampledLine(2); 00679 sampledLine *nsline2 = new sampledLine(2); 00680 00681 nsline->setPoint(0, v1->head()); 00682 nsline->setPoint(1, v2->head()); 00683 nsline2->setPoint(0, v1->head()); 00684 nsline2->setPoint(1, v2->head()); 00685 00686 /*the increasing line is from v1 head to v2 head*/ 00687 directedLine* newLineInc = new directedLine(INCREASING, nsline); 00688 00689 directedLine* newLineDec = new directedLine(DECREASING, nsline2); 00690 00691 directedLine* v1Prev = v1->prev; 00692 directedLine* v2Prev = v2->prev; 00693 00694 v1 ->prev = newLineDec; 00695 v2Prev ->next = newLineDec; 00696 newLineDec->next = v1; 00697 newLineDec->prev = v2Prev; 00698 00699 v2 ->prev = newLineInc; 00700 v1Prev ->next = newLineInc; 00701 newLineInc->next = v2; 00702 newLineInc->prev = v1Prev; 00703 00704 *ret_p1 = newLineDec; 00705 *ret_p2 = newLineInc; 00706 00707 } 00708 00709 Int directedLine::samePolygon(directedLine* v1, directedLine* v2) 00710 { 00711 if(v1 == v2) return 1; 00712 directedLine *temp; 00713 for(temp = v1->next; temp != v1; temp = temp->next) 00714 { 00715 if(temp == v2) return 1; 00716 } 00717 return 0; 00718 } 00719 00720 directedLine* directedLine::findRoot() 00721 { 00722 if(rootBit) return this; 00723 directedLine* temp; 00724 for(temp = next; temp != this; temp = temp->next) 00725 if(temp -> rootBit ) return temp; 00726 return NULL; /*should not happen*/ 00727 } 00728 00729 directedLine* directedLine::rootLinkFindRoot() 00730 { 00731 directedLine* tempRoot; 00732 directedLine* tempLink; 00733 tempRoot = this; 00734 tempLink = rootLink; 00735 while(tempLink != NULL){ 00736 tempRoot = tempLink; 00737 tempLink = tempRoot->rootLink; 00738 } 00739 return tempRoot; 00740 } 00741 00742 /*******************split or combine polygons end********************/ 00743 00744 /*****************IO stuff begin*******************/ 00745 00746 /*format: 00747 *#polygons 00748 * #vertices 00749 * vertices 00750 * #vertices 00751 * vertices 00752 *... 00753 */ 00754 void directedLine::writeAllPolygons(char* filename) 00755 { 00756 FILE* fp = fopen(filename, "w"); 00757 assert(fp); 00758 Int nPolygons = numPolygons(); 00759 directedLine *root; 00760 fprintf(fp, "%i\n", nPolygons); 00761 for(root = this; root != NULL; root = root->nextPolygon) 00762 { 00763 directedLine *temp; 00764 Int npoints=0; 00765 npoints = root->get_npoints()-1; 00766 for(temp = root->next; temp != root; temp=temp->next) 00767 npoints += temp->get_npoints()-1; 00768 fprintf(fp, "%i\n", npoints/*root->numEdges()*/); 00769 00770 00771 for(Int i=0; i<root->get_npoints()-1; i++){ 00772 fprintf(fp, "%f ", root->getVertex(i)[0]); 00773 fprintf(fp, "%f ", root->getVertex(i)[1]); 00774 } 00775 00776 for(temp=root->next; temp != root; temp = temp->next) 00777 { 00778 for(Int i=0; i<temp->get_npoints()-1; i++){ 00779 00780 fprintf(fp, "%f ", temp->getVertex(i)[0]); 00781 fprintf(fp, "%f ", temp->getVertex(i)[1]); 00782 } 00783 fprintf(fp,"\n"); 00784 } 00785 fprintf(fp, "\n"); 00786 } 00787 fclose(fp); 00788 } 00789 00790 directedLine* readAllPolygons(char* filename) 00791 { 00792 Int i,j; 00793 FILE* fp = fopen(filename, "r"); 00794 assert(fp); 00795 Int nPolygons; 00796 fscanf(fp, "%i", &nPolygons); 00797 directedLine *ret = NULL; 00798 00799 for(i=0; i<nPolygons; i++) 00800 { 00801 Int nEdges; 00802 fscanf(fp, "%i", &nEdges); 00803 Real vert[2][2]; 00804 Real VV[2][2]; 00805 /*the first two vertices*/ 00806 fscanf(fp, "%f", &(vert[0][0])); 00807 fscanf(fp, "%f", &(vert[0][1])); 00808 fscanf(fp, "%f", &(vert[1][0])); 00809 fscanf(fp, "%f", &(vert[1][1])); 00810 VV[1][0] = vert[0][0]; 00811 VV[1][1] = vert[0][1]; 00812 sampledLine *sLine = new sampledLine(2, vert); 00813 directedLine *thisPoly = new directedLine(INCREASING, sLine); 00814 thisPoly->rootLinkSet(NULL); 00815 00816 directedLine *dLine; 00817 for(j=2; j<nEdges; j++) 00818 { 00819 vert[0][0]=vert[1][0]; 00820 vert[0][1]=vert[1][1]; 00821 fscanf(fp, "%f", &(vert[1][0])); 00822 fscanf(fp, "%f", &(vert[1][1])); 00823 sLine = new sampledLine(2,vert); 00824 dLine = new directedLine(INCREASING, sLine); 00825 dLine->rootLinkSet(thisPoly); 00826 thisPoly->insert(dLine); 00827 } 00828 00829 VV[0][0]=vert[1][0]; 00830 VV[0][1]=vert[1][1]; 00831 sLine = new sampledLine(2,VV); 00832 dLine = new directedLine(INCREASING, sLine); 00833 dLine->rootLinkSet(thisPoly); 00834 thisPoly->insert(dLine); 00835 00836 ret = thisPoly->insertPolygon(ret); 00837 } 00838 fclose(fp); 00839 return ret; 00840 } 00841 00842 00843 00844 00845 00846 00847 00848 Generated on Sun May 27 2012 04:23:48 for ReactOS by
1.7.6.1
|