1f220fa62Smrg/* 2f220fa62Smrg** License Applicability. Except to the extent portions of this file are 3f220fa62Smrg** made subject to an alternative license as permitted in the SGI Free 4f220fa62Smrg** Software License B, Version 1.1 (the "License"), the contents of this 5f220fa62Smrg** file are subject only to the provisions of the License. You may not use 6f220fa62Smrg** this file except in compliance with the License. You may obtain a copy 7f220fa62Smrg** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 8f220fa62Smrg** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: 9f220fa62Smrg** 10f220fa62Smrg** http://oss.sgi.com/projects/FreeB 11f220fa62Smrg** 12f220fa62Smrg** Note that, as provided in the License, the Software is distributed on an 13f220fa62Smrg** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS 14f220fa62Smrg** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND 15f220fa62Smrg** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A 16f220fa62Smrg** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. 17f220fa62Smrg** 18f220fa62Smrg** Original Code. The Original Code is: OpenGL Sample Implementation, 19f220fa62Smrg** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, 20f220fa62Smrg** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. 21f220fa62Smrg** Copyright in any portions created by third parties is as indicated 22f220fa62Smrg** elsewhere herein. All Rights Reserved. 23f220fa62Smrg** 24f220fa62Smrg** Additional Notice Provisions: The application programming interfaces 25f220fa62Smrg** established by SGI in conjunction with the Original Code are The 26f220fa62Smrg** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released 27f220fa62Smrg** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version 28f220fa62Smrg** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X 29f220fa62Smrg** Window System(R) (Version 1.3), released October 19, 1998. This software 30f220fa62Smrg** was created using the OpenGL(R) version 1.2.1 Sample Implementation 31f220fa62Smrg** published by SGI, but has not been independently verified as being 32f220fa62Smrg** compliant with the OpenGL(R) version 1.2.1 Specification. 33f220fa62Smrg** 34f220fa62Smrg*/ 35f220fa62Smrg/* 36f220fa62Smrg*/ 37f220fa62Smrg 38f220fa62Smrg#include <stdlib.h> 39f220fa62Smrg#include <stdio.h> 40f220fa62Smrg#include <math.h> 41f220fa62Smrg#include "glimports.h" 42f220fa62Smrg#include "zlassert.h" 43f220fa62Smrg 44f220fa62Smrg#include "quicksort.h" 45f220fa62Smrg#include "directedLine.h" 46f220fa62Smrg#include "polyDBG.h" 47f220fa62Smrg 48f220fa62Smrg#ifdef __WATCOMC__ 49f220fa62Smrg#pragma warning 726 10 50f220fa62Smrg#endif 51f220fa62Smrg 52f220fa62Smrg//we must return the newLine 53f220fa62SmrgdirectedLine* directedLine::deleteChain(directedLine* begin, directedLine* end) 54f220fa62Smrg{ 55f220fa62Smrg if(begin->head()[0] == end->tail()[0] && 56f220fa62Smrg begin->head()[1] == end->tail()[1] 57f220fa62Smrg ) 58f220fa62Smrg { 59f220fa62Smrg directedLine *ret = begin->prev; 60f220fa62Smrg begin->prev->next = end->next; 61f220fa62Smrg end->next->prev = begin->prev; 62f220fa62Smrg delete begin->sline; 63f220fa62Smrg delete end->sline; 64f220fa62Smrg delete begin; 65f220fa62Smrg delete end; 66f220fa62Smrg 67f220fa62Smrg return ret; 68f220fa62Smrg } 69f220fa62Smrg 70f220fa62Smrg directedLine* newLine; 71f220fa62Smrg sampledLine* sline = new sampledLine(begin->head(), end->tail()); 72f220fa62Smrg newLine = new directedLine(INCREASING, sline); 73f220fa62Smrg directedLine *p = begin->prev; 74f220fa62Smrg directedLine *n = end->next; 75f220fa62Smrg p->next = newLine; 76f220fa62Smrg n->prev = newLine; 77f220fa62Smrg newLine->prev = p; 78f220fa62Smrg newLine->next = n; 79f220fa62Smrg 80f220fa62Smrg delete begin->sline; 81f220fa62Smrg delete end->sline; 82f220fa62Smrg delete begin; 83f220fa62Smrg delete end; 84f220fa62Smrg return newLine; 85f220fa62Smrg} 86f220fa62Smrg 87f220fa62Smrg 88f220fa62Smrgvoid directedLine::deleteSingleLine(directedLine* dline) 89f220fa62Smrg{ 90f220fa62Smrg //make sure that dline->prev->tail is the same as 91f220fa62Smrg //dline->next->head. This is for numerical erros. 92f220fa62Smrg //for example, if we delete a line which is almost degeneate 93f220fa62Smrg //within (epsilon), then we want to make that the polygon after deletion 94f220fa62Smrg //is still a valid polygon 95f220fa62Smrg 96f220fa62Smrg dline->next->head()[0] = dline->prev->tail()[0]; 97f220fa62Smrg dline->next->head()[1] = dline->prev->tail()[1]; 98f220fa62Smrg 99f220fa62Smrg dline->prev->next = dline->next; 100f220fa62Smrg dline->next->prev = dline->prev; 101f220fa62Smrg 102f220fa62Smrg delete dline; 103f220fa62Smrg 104f220fa62Smrg} 105f220fa62Smrg 106f220fa62Smrgstatic Int myequal(Real a[2], Real b[2]) 107f220fa62Smrg{ 108f220fa62Smrg /* 109f220fa62Smrg if(a[0]==b[0] && a[1] == b[1]) 110f220fa62Smrg return 1; 111f220fa62Smrg else 112f220fa62Smrg return 0; 113f220fa62Smrg */ 114f220fa62Smrg 115f220fa62Smrg 116f220fa62Smrg if(fabs(a[0]-b[0]) < 0.00001 && 117f220fa62Smrg fabs(a[1]-b[1]) < 0.00001) 118f220fa62Smrg return 1; 119f220fa62Smrg else 120f220fa62Smrg return 0; 121f220fa62Smrg 122f220fa62Smrg} 123f220fa62Smrg 124f220fa62SmrgdirectedLine* directedLine::deleteDegenerateLines() 125f220fa62Smrg{ 126f220fa62Smrg //if there is only one edge or two edges, don't do anything 127f220fa62Smrg if(this->next == this) 128f220fa62Smrg return this; 129f220fa62Smrg if(this->next == this->prev) 130f220fa62Smrg return this; 131f220fa62Smrg 132f220fa62Smrg //find a nondegenerate line 133f220fa62Smrg directedLine* temp; 134f220fa62Smrg directedLine* first = NULL; 135f220fa62Smrg if(! myequal(head(), tail())) 136f220fa62Smrg /* 137f220fa62Smrg if(head()[0] != tail()[0] || 138f220fa62Smrg head()[1] != tail()[1]) 139f220fa62Smrg */ 140f220fa62Smrg first = this; 141f220fa62Smrg else 142f220fa62Smrg { 143f220fa62Smrg for(temp = this->next; temp != this; temp = temp->next) 144f220fa62Smrg { 145f220fa62Smrg /* 146f220fa62Smrg if(temp->head()[0] != temp->tail()[0] || 147f220fa62Smrg temp->head()[1] != temp->tail()[1]) 148f220fa62Smrg */ 149f220fa62Smrg if(! myequal(temp->head(), temp->tail())) 150f220fa62Smrg { 151f220fa62Smrg first = temp; 152f220fa62Smrg break; 153f220fa62Smrg } 154f220fa62Smrg 155f220fa62Smrg } 156f220fa62Smrg } 157f220fa62Smrg 158f220fa62Smrg //if there are no non-degenerate lines, then we simply return NULL. 159f220fa62Smrg if(first == NULL) 160f220fa62Smrg { 161f220fa62Smrg deleteSinglePolygonWithSline(); 162f220fa62Smrg return NULL; 163f220fa62Smrg } 164f220fa62Smrg 165f220fa62Smrg directedLine* tempNext = NULL; 166f220fa62Smrg for(temp =first->next; temp != first; temp = tempNext) 167f220fa62Smrg { 168f220fa62Smrg tempNext = temp->getNext(); 169f220fa62Smrg/* 170f220fa62Smrg if(temp->head()[0] == temp->tail()[0] && 171f220fa62Smrg temp->head()[1] == temp->tail()[1]) 172f220fa62Smrg*/ 173f220fa62Smrg 174f220fa62Smrg if(myequal(temp->head(), temp->tail())) 175f220fa62Smrg deleteSingleLine(temp); 176f220fa62Smrg } 177f220fa62Smrg return first; 178f220fa62Smrg} 179f220fa62Smrg 180f220fa62SmrgdirectedLine* directedLine::deleteDegenerateLinesAllPolygons() 181f220fa62Smrg{ 182f220fa62Smrg directedLine* temp; 183f220fa62Smrg directedLine *tempNext = NULL; 184f220fa62Smrg directedLine* ret= NULL; 185f220fa62Smrg directedLine* retEnd = NULL; 186f220fa62Smrg for(temp=this; temp != NULL; temp = tempNext) 187f220fa62Smrg { 188f220fa62Smrg tempNext = temp->nextPolygon; 189f220fa62Smrg temp->nextPolygon = NULL; 190f220fa62Smrg if(ret == NULL) 191f220fa62Smrg { 192f220fa62Smrg ret = retEnd = temp->deleteDegenerateLines(); 193f220fa62Smrg 194f220fa62Smrg } 195f220fa62Smrg else 196f220fa62Smrg { 197f220fa62Smrg directedLine *newPolygon = temp->deleteDegenerateLines(); 198f220fa62Smrg if(newPolygon != NULL) 199f220fa62Smrg { 200f220fa62Smrg retEnd->nextPolygon = temp->deleteDegenerateLines(); 201f220fa62Smrg retEnd = retEnd->nextPolygon; 202f220fa62Smrg } 203f220fa62Smrg } 204f220fa62Smrg } 205f220fa62Smrg return ret; 206f220fa62Smrg} 207f220fa62Smrg 208f220fa62SmrgdirectedLine* directedLine::cutIntersectionAllPoly(int &cutOccur) 209f220fa62Smrg{ 210f220fa62Smrg directedLine* temp; 211f220fa62Smrg directedLine *tempNext = NULL; 212f220fa62Smrg directedLine* ret= NULL; 213f220fa62Smrg directedLine* retEnd = NULL; 214f220fa62Smrg cutOccur = 0; 215f220fa62Smrg for(temp=this; temp != NULL; temp = tempNext) 216f220fa62Smrg { 217f220fa62Smrg int eachCutOccur=0; 218f220fa62Smrg tempNext = temp->nextPolygon; 219f220fa62Smrg temp->nextPolygon = NULL; 220f220fa62Smrg if(ret == NULL) 221f220fa62Smrg { 222f220fa62Smrg 223f220fa62Smrg ret = retEnd = DBG_cutIntersectionPoly(temp, eachCutOccur); 224f220fa62Smrg if(eachCutOccur) 225f220fa62Smrg cutOccur = 1; 226f220fa62Smrg } 227f220fa62Smrg else 228f220fa62Smrg { 229f220fa62Smrg 230f220fa62Smrg retEnd->nextPolygon = DBG_cutIntersectionPoly(temp, eachCutOccur); 231f220fa62Smrg retEnd = retEnd->nextPolygon; 232f220fa62Smrg if(eachCutOccur) 233f220fa62Smrg cutOccur = 1; 234f220fa62Smrg } 235f220fa62Smrg } 236f220fa62Smrg return ret; 237f220fa62Smrg} 238f220fa62Smrg 239f220fa62Smrg 240f220fa62Smrgvoid directedLine::deleteSinglePolygonWithSline() 241f220fa62Smrg{ 242f220fa62Smrg directedLine *temp, *tempNext; 243f220fa62Smrg prev->next = NULL; 244f220fa62Smrg for(temp=this; temp != NULL; temp = tempNext) 245f220fa62Smrg { 246f220fa62Smrg tempNext = temp->next; 247f220fa62Smrg delete temp->sline; 248f220fa62Smrg delete temp; 249f220fa62Smrg } 250f220fa62Smrg} 251f220fa62Smrg 252f220fa62Smrgvoid directedLine::deletePolygonListWithSline() 253f220fa62Smrg{ 254f220fa62Smrg directedLine *temp, *tempNext; 255f220fa62Smrg for(temp=this; temp != NULL; temp=tempNext) 256f220fa62Smrg { 257f220fa62Smrg tempNext = temp->nextPolygon; 258f220fa62Smrg temp->deleteSinglePolygonWithSline(); 259f220fa62Smrg } 260f220fa62Smrg} 261f220fa62Smrg 262f220fa62Smrgvoid directedLine::deleteSinglePolygon() 263f220fa62Smrg{ 264f220fa62Smrg directedLine *temp, *tempNext; 265f220fa62Smrg prev->next = NULL; 266f220fa62Smrg for(temp=this; temp != NULL; temp = tempNext) 267f220fa62Smrg { 268f220fa62Smrg tempNext = temp->next; 269f220fa62Smrg delete temp; 270f220fa62Smrg } 271f220fa62Smrg} 272f220fa62Smrg 273f220fa62Smrgvoid directedLine::deletePolygonList() 274f220fa62Smrg{ 275f220fa62Smrg directedLine *temp, *tempNext; 276f220fa62Smrg for(temp=this; temp != NULL; temp=tempNext) 277f220fa62Smrg { 278f220fa62Smrg tempNext = temp->nextPolygon; 279f220fa62Smrg temp->deleteSinglePolygon(); 280f220fa62Smrg } 281f220fa62Smrg} 282f220fa62Smrg 283f220fa62Smrg 284f220fa62Smrg/*a loop by itself*/ 285f220fa62SmrgdirectedLine::directedLine(short dir, sampledLine* sl) 286f220fa62Smrg{ 287f220fa62Smrg direction = dir; 288f220fa62Smrg sline = sl; 289f220fa62Smrg next = this; 290f220fa62Smrg prev = this; 291f220fa62Smrg nextPolygon = NULL; 292f220fa62Smrg// prevPolygon = NULL; 293f220fa62Smrg rootBit = 0;/*important to initilzae to 0 meaning not root yet*/ 294f220fa62Smrg 295f220fa62Smrg rootLink = NULL; 296f220fa62Smrg 297f220fa62Smrg} 298f220fa62Smrg 299f220fa62Smrgvoid directedLine::init(short dir, sampledLine* sl) 300f220fa62Smrg{ 301f220fa62Smrg direction = dir; 302f220fa62Smrg sline = sl; 303f220fa62Smrg} 304f220fa62Smrg 305f220fa62SmrgdirectedLine::directedLine() 306f220fa62Smrg{ 307f220fa62Smrg next = this; 308f220fa62Smrg prev = this; 309f220fa62Smrg nextPolygon = NULL; 310f220fa62Smrg rootBit = 0;/*important to initilzae to 0 meaning not root yet*/ 311f220fa62Smrg rootLink = NULL; 312f220fa62Smrg direction = INCREASING; 313f220fa62Smrg sline = NULL; 314f220fa62Smrg} 315f220fa62Smrg 316f220fa62SmrgdirectedLine::~directedLine() 317f220fa62Smrg{ 318f220fa62Smrg} 319f220fa62Smrg 320f220fa62SmrgReal* directedLine::head() 321f220fa62Smrg{ 322f220fa62Smrg 323f220fa62Smrg return (direction==INCREASING)? (sline->get_points())[0] : (sline->get_points())[sline->get_npoints()-1]; 324f220fa62Smrg} 325f220fa62Smrg 326f220fa62Smrg/*inline*/ Real* directedLine::getVertex(Int i) 327f220fa62Smrg{ 328f220fa62Smrg return (direction==INCREASING)? (sline->get_points())[i] : (sline->get_points())[sline->get_npoints() - 1 -i]; 329f220fa62Smrg} 330f220fa62Smrg 331f220fa62SmrgReal* directedLine::tail() 332f220fa62Smrg{ 333f220fa62Smrg return (direction==DECREASING)? (sline->get_points())[0] : (sline->get_points())[sline->get_npoints()-1]; 334f220fa62Smrg} 335f220fa62Smrg 336f220fa62Smrg /*insert a new line between prev and this*/ 337f220fa62Smrgvoid directedLine::insert(directedLine* nl) 338f220fa62Smrg{ 339f220fa62Smrg nl->next = this; 340f220fa62Smrg nl->prev = prev; 341f220fa62Smrg prev->next = nl; 342f220fa62Smrg prev = nl; 343f220fa62Smrg nl->rootLink = this; /*assuming that 'this' is the root!!!*/ 344f220fa62Smrg} 345f220fa62Smrg 346f220fa62SmrgInt directedLine::numEdges() 347f220fa62Smrg{ 348f220fa62Smrg Int ret=0; 349f220fa62Smrg directedLine* temp; 350f220fa62Smrg if(next == this) return 1; 351f220fa62Smrg 352f220fa62Smrg ret = 1; 353f220fa62Smrg for(temp = next; temp != this; temp = temp->next) 354f220fa62Smrg ret++; 355f220fa62Smrg return ret; 356f220fa62Smrg} 357f220fa62Smrg 358f220fa62SmrgInt directedLine::numEdgesAllPolygons() 359f220fa62Smrg{ 360f220fa62Smrg Int ret=0; 361f220fa62Smrg directedLine* temp; 362f220fa62Smrg for(temp=this; temp!= NULL; temp=temp->nextPolygon) 363f220fa62Smrg { 364f220fa62Smrg ret += temp->numEdges(); 365f220fa62Smrg } 366f220fa62Smrg return ret; 367f220fa62Smrg} 368f220fa62Smrg 369f220fa62Smrg/*return 1 if the double linked list forms a polygon. 370f220fa62Smrg */ 371f220fa62Smrgshort directedLine::isPolygon() 372f220fa62Smrg{ 373f220fa62Smrg directedLine* temp; 374f220fa62Smrg 375f220fa62Smrg /*a polygon contains at least 3 edges*/ 376f220fa62Smrg if(numEdges() <=2) return 0; 377f220fa62Smrg 378f220fa62Smrg /*check this edge*/ 379f220fa62Smrg if(! isConnected()) return 0; 380f220fa62Smrg 381f220fa62Smrg /*check all other edges*/ 382f220fa62Smrg for(temp=next; temp != this; temp = temp->next){ 383f220fa62Smrg if(!isConnected()) return 0; 384f220fa62Smrg } 385f220fa62Smrg return 1; 386f220fa62Smrg} 387f220fa62Smrg 388f220fa62Smrg/*check if the head of this edge is connected to 389f220fa62Smrg *the tail of the prev 390f220fa62Smrg */ 391f220fa62Smrgshort directedLine::isConnected() 392f220fa62Smrg{ 393f220fa62Smrg if( (head()[0] == prev->tail()[0]) && (head()[1] == prev->tail()[1])) 394f220fa62Smrg return 1; 395f220fa62Smrg else 396f220fa62Smrg return 0; 397f220fa62Smrg} 398f220fa62Smrg 399f220fa62SmrgInt compV2InY(Real A[2], Real B[2]) 400f220fa62Smrg{ 401f220fa62Smrg if(A[1] < B[1]) return -1; 402f220fa62Smrg if(A[1] == B[1] && A[0] < B[0]) return -1; 403f220fa62Smrg if(A[1] == B[1] && A[0] == B[0]) return 0; 404f220fa62Smrg return 1; 405f220fa62Smrg} 406f220fa62Smrg 407f220fa62SmrgInt compV2InX(Real A[2], Real B[2]) 408f220fa62Smrg{ 409f220fa62Smrg if(A[0] < B[0]) return -1; 410f220fa62Smrg if(A[0] == B[0] && A[1] < B[1]) return -1; 411f220fa62Smrg if(A[0] == B[0] && A[1] == B[1]) return 0; 412f220fa62Smrg return 1; 413f220fa62Smrg} 414f220fa62Smrg 415f220fa62Smrg/*compare two vertices NOT lines! 416f220fa62Smrg *A vertex is the head of a directed line. 417f220fa62Smrg *(x_1, y_1) <= (x_2, y_2) if 418f220fa62Smrg *either y_1 < y_2 419f220fa62Smrg *or y_1 == y_2 && x_1 < x_2. 420f220fa62Smrg *return -1 if this->head() <= nl->head(), 421f220fa62Smrg *return 1 otherwise 422f220fa62Smrg */ 423f220fa62SmrgInt directedLine::compInY(directedLine* nl) 424f220fa62Smrg{ 425f220fa62Smrg if(head()[1] < nl->head()[1]) return -1; 426f220fa62Smrg if(head()[1] == nl->head()[1] && head()[0] < nl->head()[0]) return -1; 427f220fa62Smrg return 1; 428f220fa62Smrg} 429f220fa62Smrg 430f220fa62Smrg/*compare two vertices NOT lines! 431f220fa62Smrg *A vertex is the head of a directed line. 432f220fa62Smrg *(x_1, y_1) <= (x_2, y_2) if 433f220fa62Smrg *either x_1 < x_2 434f220fa62Smrg *or x_1 == x_2 && y_1 < y_2. 435f220fa62Smrg *return -1 if this->head() <= nl->head(), 436f220fa62Smrg *return 1 otherwise 437f220fa62Smrg */ 438f220fa62SmrgInt directedLine::compInX(directedLine* nl) 439f220fa62Smrg{ 440f220fa62Smrg if(head()[0] < nl->head()[0]) return -1; 441f220fa62Smrg if(head()[0] == nl->head()[0] && head()[1] < nl->head()[1]) return -1; 442f220fa62Smrg return 1; 443f220fa62Smrg} 444f220fa62Smrg 445f220fa62Smrg/*used by sort precedures 446f220fa62Smrg */ 447f220fa62Smrgstatic Int compInY2(directedLine* v1, directedLine* v2) 448f220fa62Smrg{ 449f220fa62Smrg return v1->compInY(v2); 450f220fa62Smrg} 451f220fa62Smrg#ifdef NOT_USED 452f220fa62Smrgstatic Int compInX(directedLine* v1, directedLine* v2) 453f220fa62Smrg{ 454f220fa62Smrg return v1->compInX(v2); 455f220fa62Smrg} 456f220fa62Smrg#endif 457f220fa62Smrg 458f220fa62Smrg/*sort all the vertices NOT the lines! 459f220fa62Smrg *a vertex is the head of a directed line 460f220fa62Smrg */ 461f220fa62SmrgdirectedLine** directedLine::sortAllPolygons() 462f220fa62Smrg{ 463f220fa62Smrg Int total_num_edges = 0; 464f220fa62Smrg directedLine** array = toArrayAllPolygons(total_num_edges); 465f220fa62Smrg quicksort( (void**)array, 0, total_num_edges-1, (Int (*)(void *, void *)) compInY2); 466f220fa62Smrg 467f220fa62Smrg return array; 468f220fa62Smrg} 469f220fa62Smrg 470f220fa62Smrgvoid directedLine::printSingle() 471f220fa62Smrg{ 472f220fa62Smrg if(direction == INCREASING) 473f220fa62Smrg printf("direction is INCREASING\n"); 474f220fa62Smrg else 475f220fa62Smrg printf("direction is DECREASING\n"); 476f220fa62Smrg printf("head=%f,%f)\n", head()[0], head()[1]); 477f220fa62Smrg sline->print(); 478f220fa62Smrg} 479f220fa62Smrg 480f220fa62Smrg/*print one polygon*/ 481f220fa62Smrgvoid directedLine::printList() 482f220fa62Smrg{ 483f220fa62Smrg directedLine* temp; 484f220fa62Smrg printSingle(); 485f220fa62Smrg for(temp = next; temp!=this; temp=temp->next) 486f220fa62Smrg temp->printSingle(); 487f220fa62Smrg} 488f220fa62Smrg 489f220fa62Smrg/*print all the polygons*/ 490f220fa62Smrgvoid directedLine::printAllPolygons() 491f220fa62Smrg{ 492f220fa62Smrg directedLine *temp; 493f220fa62Smrg for(temp = this; temp!=NULL; temp = temp->nextPolygon) 494f220fa62Smrg { 495f220fa62Smrg printf("polygon:\n"); 496f220fa62Smrg temp->printList(); 497f220fa62Smrg } 498f220fa62Smrg} 499f220fa62Smrg 500f220fa62Smrg/*insert this polygon into the head of the old polygon List*/ 501f220fa62SmrgdirectedLine* directedLine::insertPolygon(directedLine* oldList) 502f220fa62Smrg{ 503f220fa62Smrg /*this polygon is a root*/ 504f220fa62Smrg setRootBit(); 505f220fa62Smrg if(oldList == NULL) return this; 506f220fa62Smrg nextPolygon = oldList; 507f220fa62Smrg/* oldList->prevPolygon = this;*/ 508f220fa62Smrg return this; 509f220fa62Smrg} 510f220fa62Smrg 511f220fa62Smrg/*cutoff means delete. but we don't deallocate any space, 512f220fa62Smrg *so we use cutoff instead of delete 513f220fa62Smrg */ 514f220fa62SmrgdirectedLine* directedLine::cutoffPolygon(directedLine *p) 515f220fa62Smrg{ 516f220fa62Smrg directedLine* temp; 517f220fa62Smrg directedLine* prev_polygon = NULL; 518f220fa62Smrg if(p == NULL) return this; 519f220fa62Smrg 520f220fa62Smrg for(temp=this; temp != p; temp = temp->nextPolygon) 521f220fa62Smrg { 522f220fa62Smrg if(temp == NULL) 523f220fa62Smrg { 524f220fa62Smrg fprintf(stderr, "in cutoffPolygon, not found\n"); 525f220fa62Smrg exit(1); 526f220fa62Smrg } 527f220fa62Smrg prev_polygon = temp; 528f220fa62Smrg } 529f220fa62Smrg 530f220fa62Smrg/* prev_polygon = p->prevPolygon;*/ 531f220fa62Smrg 532f220fa62Smrg p->resetRootBit(); 533f220fa62Smrg if(prev_polygon == NULL) /*this is the one to cutoff*/ 534f220fa62Smrg return nextPolygon; 535f220fa62Smrg else { 536f220fa62Smrg prev_polygon->nextPolygon = p->nextPolygon; 537f220fa62Smrg return this; 538f220fa62Smrg } 539f220fa62Smrg} 540f220fa62Smrg 541f220fa62SmrgInt directedLine::numPolygons() 542f220fa62Smrg{ 543f220fa62Smrg if(nextPolygon == NULL) return 1; 544f220fa62Smrg else return 1+nextPolygon->numPolygons(); 545f220fa62Smrg} 546f220fa62Smrg 547f220fa62Smrg 548f220fa62Smrg/*let array[index ...] denote 549f220fa62Smrg *all the edges in this polygon 550f220fa62Smrg *return the next available index of array. 551f220fa62Smrg */ 552f220fa62SmrgInt directedLine::toArraySinglePolygon(directedLine** array, Int index) 553f220fa62Smrg{ 554f220fa62Smrg directedLine *temp; 555f220fa62Smrg array[index++] = this; 556f220fa62Smrg for(temp = next; temp != this; temp = temp->next) 557f220fa62Smrg { 558f220fa62Smrg array[index++] = temp; 559f220fa62Smrg } 560f220fa62Smrg return index; 561f220fa62Smrg} 562f220fa62Smrg 563f220fa62Smrg/*the space is allocated. The caller is responsible for 564f220fa62Smrg *deallocate the space. 565f220fa62Smrg *total_num_edges is set to be the total number of edges of all polygons 566f220fa62Smrg */ 567f220fa62SmrgdirectedLine** directedLine::toArrayAllPolygons(Int& total_num_edges) 568f220fa62Smrg{ 569f220fa62Smrg total_num_edges=numEdgesAllPolygons(); 570f220fa62Smrg directedLine** ret = (directedLine**) malloc(sizeof(directedLine*) * total_num_edges); 571f220fa62Smrg assert(ret); 572f220fa62Smrg 573f220fa62Smrg directedLine *temp; 574f220fa62Smrg Int index = 0; 575f220fa62Smrg for(temp=this; temp != NULL; temp=temp->nextPolygon) { 576f220fa62Smrg index = temp->toArraySinglePolygon(ret, index); 577f220fa62Smrg } 578f220fa62Smrg return ret; 579f220fa62Smrg} 580f220fa62Smrg 581f220fa62Smrg/*assume the polygon is a simple polygon, return 582f220fa62Smrg *the area enclosed by it. 583f220fa62Smrg *if thee order is counterclock wise, the area is positive. 584f220fa62Smrg */ 585f220fa62SmrgReal directedLine::polyArea() 586f220fa62Smrg{ 587f220fa62Smrg directedLine* temp; 588f220fa62Smrg Real ret=0.0; 589f220fa62Smrg Real x1,y1,x2,y2; 590f220fa62Smrg x1 = this->head()[0]; 591f220fa62Smrg y1 = this->head()[1]; 592f220fa62Smrg x2 = this->next->head()[0]; 593f220fa62Smrg y2 = this->next->head()[1]; 594f220fa62Smrg ret = -(x2*y1-x1*y2); 595f220fa62Smrg for(temp=this->next; temp!=this; temp = temp->next) 596f220fa62Smrg { 597f220fa62Smrg x1 = temp->head()[0]; 598f220fa62Smrg y1 = temp->head()[1]; 599f220fa62Smrg x2 = temp->next->head()[0]; 600f220fa62Smrg y2 = temp->next->head()[1]; 601f220fa62Smrg ret += -( x2*y1-x1*y2); 602f220fa62Smrg } 603f220fa62Smrg return Real(0.5)*ret; 604f220fa62Smrg} 605f220fa62Smrg 606f220fa62Smrg/*******************split or combine polygons begin********************/ 607f220fa62Smrg/*conect a diagonal of a single simple polygon or two simple polygons. 608f220fa62Smrg *If the two vertices v1 (head) and v2 (head) are in the same simple polygon, 609f220fa62Smrg *then we actually split the simple polygon into two polygons. 610f220fa62Smrg *If instead two vertices velong to two difference polygons, 611f220fa62Smrg *then we combine the two polygons into one polygon. 612f220fa62Smrg *It is upto the caller to decide whether this is a split or a 613f220fa62Smrg *combination. 614f220fa62Smrg * 615f220fa62Smrg *Case Split: 616f220fa62Smrg *split a single simple polygon into two simple polygons by 617f220fa62Smrg *connecting a diagonal (two vertices). 618f220fa62Smrg *v1, v2: the two vertices are the head() of the two directedLines. 619f220fa62Smrg * this routine generates one new sampledLine which is returned in 620f220fa62Smrg *generatedLine, 621f220fa62Smrg *and it generates two directedLines returned in ret_p1 and ret_p2. 622f220fa62Smrg *ret_p1 and ret_p2 are used as the entry to the two new polygons. 623f220fa62Smrg *Notice the caller should not deallocate the space of v2 and v2 after 624f220fa62Smrg *calling this function, since all of the edges are connected to 625f220fa62Smrg *ret_p1 or ret_p2. 626f220fa62Smrg * 627f220fa62Smrg *combine: 628f220fa62Smrg *combine two simpolygons into one by connecting one diagonal. 629f220fa62Smrg *the returned polygon is returned in ret_p1. 630f220fa62Smrg */ 631f220fa62Smrg/*ARGSUSED*/ 632f220fa62Smrgvoid directedLine::connectDiagonal(directedLine* v1, directedLine* v2, 633f220fa62Smrg directedLine** ret_p1, 634f220fa62Smrg directedLine** ret_p2, 635f220fa62Smrg sampledLine** generatedLine, 636f220fa62Smrg directedLine* polygonList ) 637f220fa62Smrg{ 638f220fa62Smrg sampledLine *nsline = new sampledLine(2); 639f220fa62Smrg 640f220fa62Smrg 641f220fa62Smrg 642f220fa62Smrg nsline->setPoint(0, v1->head()); 643f220fa62Smrg nsline->setPoint(1, v2->head()); 644f220fa62Smrg 645f220fa62Smrg 646f220fa62Smrg 647f220fa62Smrg /*the increasing line is from v1 head to v2 head*/ 648f220fa62Smrg directedLine* newLineInc = new directedLine(INCREASING, nsline); 649f220fa62Smrg 650f220fa62Smrg 651f220fa62Smrg 652f220fa62Smrg directedLine* newLineDec = new directedLine(DECREASING, nsline); 653f220fa62Smrg 654f220fa62Smrg 655f220fa62Smrg directedLine* v1Prev = v1->prev; 656f220fa62Smrg directedLine* v2Prev = v2->prev; 657f220fa62Smrg 658f220fa62Smrg v1 ->prev = newLineDec; 659f220fa62Smrg v2Prev ->next = newLineDec; 660f220fa62Smrg newLineDec->next = v1; 661f220fa62Smrg newLineDec->prev = v2Prev; 662f220fa62Smrg 663f220fa62Smrg v2 ->prev = newLineInc; 664f220fa62Smrg v1Prev ->next = newLineInc; 665f220fa62Smrg newLineInc->next = v2; 666f220fa62Smrg newLineInc->prev = v1Prev; 667f220fa62Smrg 668f220fa62Smrg *ret_p1 = newLineDec; 669f220fa62Smrg *ret_p2 = newLineInc; 670f220fa62Smrg *generatedLine = nsline; 671f220fa62Smrg} 672f220fa62Smrg 673f220fa62Smrg//see the function connectDiangle 674f220fa62Smrg/*ARGSUSED*/ 675f220fa62Smrgvoid directedLine::connectDiagonal_2slines(directedLine* v1, directedLine* v2, 676f220fa62Smrg directedLine** ret_p1, 677f220fa62Smrg directedLine** ret_p2, 678f220fa62Smrg directedLine* polygonList ) 679f220fa62Smrg{ 680f220fa62Smrg sampledLine *nsline = new sampledLine(2); 681f220fa62Smrg sampledLine *nsline2 = new sampledLine(2); 682f220fa62Smrg 683f220fa62Smrg nsline->setPoint(0, v1->head()); 684f220fa62Smrg nsline->setPoint(1, v2->head()); 685f220fa62Smrg nsline2->setPoint(0, v1->head()); 686f220fa62Smrg nsline2->setPoint(1, v2->head()); 687f220fa62Smrg 688f220fa62Smrg /*the increasing line is from v1 head to v2 head*/ 689f220fa62Smrg directedLine* newLineInc = new directedLine(INCREASING, nsline); 690f220fa62Smrg 691f220fa62Smrg directedLine* newLineDec = new directedLine(DECREASING, nsline2); 692f220fa62Smrg 693f220fa62Smrg directedLine* v1Prev = v1->prev; 694f220fa62Smrg directedLine* v2Prev = v2->prev; 695f220fa62Smrg 696f220fa62Smrg v1 ->prev = newLineDec; 697f220fa62Smrg v2Prev ->next = newLineDec; 698f220fa62Smrg newLineDec->next = v1; 699f220fa62Smrg newLineDec->prev = v2Prev; 700f220fa62Smrg 701f220fa62Smrg v2 ->prev = newLineInc; 702f220fa62Smrg v1Prev ->next = newLineInc; 703f220fa62Smrg newLineInc->next = v2; 704f220fa62Smrg newLineInc->prev = v1Prev; 705f220fa62Smrg 706f220fa62Smrg *ret_p1 = newLineDec; 707f220fa62Smrg *ret_p2 = newLineInc; 708f220fa62Smrg 709f220fa62Smrg} 710f220fa62Smrg 711f220fa62SmrgInt directedLine::samePolygon(directedLine* v1, directedLine* v2) 712f220fa62Smrg{ 713f220fa62Smrg if(v1 == v2) return 1; 714f220fa62Smrg directedLine *temp; 715f220fa62Smrg for(temp = v1->next; temp != v1; temp = temp->next) 716f220fa62Smrg { 717f220fa62Smrg if(temp == v2) return 1; 718f220fa62Smrg } 719f220fa62Smrg return 0; 720f220fa62Smrg} 721f220fa62Smrg 722f220fa62SmrgdirectedLine* directedLine::findRoot() 723f220fa62Smrg{ 724f220fa62Smrg if(rootBit) return this; 725f220fa62Smrg directedLine* temp; 726f220fa62Smrg for(temp = next; temp != this; temp = temp->next) 727f220fa62Smrg if(temp -> rootBit ) return temp; 728f220fa62Smrg return NULL; /*should not happen*/ 729f220fa62Smrg} 730f220fa62Smrg 731f220fa62SmrgdirectedLine* directedLine::rootLinkFindRoot() 732f220fa62Smrg{ 733f220fa62Smrg directedLine* tempRoot; 734f220fa62Smrg directedLine* tempLink; 735f220fa62Smrg tempRoot = this; 736f220fa62Smrg tempLink = rootLink; 737f220fa62Smrg while(tempLink != NULL){ 738f220fa62Smrg tempRoot = tempLink; 739f220fa62Smrg tempLink = tempRoot->rootLink; 740f220fa62Smrg } 741f220fa62Smrg return tempRoot; 742f220fa62Smrg} 743f220fa62Smrg 744f220fa62Smrg/*******************split or combine polygons end********************/ 745f220fa62Smrg 746f220fa62Smrg/*****************IO stuff begin*******************/ 747f220fa62Smrg 748f220fa62Smrg/*format: 749f220fa62Smrg *#polygons 750f220fa62Smrg * #vertices 751f220fa62Smrg * vertices 752f220fa62Smrg * #vertices 753f220fa62Smrg * vertices 754f220fa62Smrg *... 755f220fa62Smrg */ 756f220fa62Smrgvoid directedLine::writeAllPolygons(char* filename) 757f220fa62Smrg{ 758f220fa62Smrg FILE* fp = fopen(filename, "w"); 759f220fa62Smrg assert(fp); 760f220fa62Smrg Int nPolygons = numPolygons(); 761f220fa62Smrg directedLine *root; 762f220fa62Smrg fprintf(fp, "%i\n", nPolygons); 763f220fa62Smrg for(root = this; root != NULL; root = root->nextPolygon) 764f220fa62Smrg { 765f220fa62Smrg directedLine *temp; 766f220fa62Smrg Int npoints=0; 767f220fa62Smrg npoints = root->get_npoints()-1; 768f220fa62Smrg for(temp = root->next; temp != root; temp=temp->next) 769f220fa62Smrg npoints += temp->get_npoints()-1; 770f220fa62Smrg fprintf(fp, "%i\n", npoints/*root->numEdges()*/); 771f220fa62Smrg 772f220fa62Smrg 773f220fa62Smrg for(Int i=0; i<root->get_npoints()-1; i++){ 774f220fa62Smrg fprintf(fp, "%f ", root->getVertex(i)[0]); 775f220fa62Smrg fprintf(fp, "%f ", root->getVertex(i)[1]); 776f220fa62Smrg } 777f220fa62Smrg 778f220fa62Smrg for(temp=root->next; temp != root; temp = temp->next) 779f220fa62Smrg { 780f220fa62Smrg for(Int i=0; i<temp->get_npoints()-1; i++){ 781f220fa62Smrg 782f220fa62Smrg fprintf(fp, "%f ", temp->getVertex(i)[0]); 783f220fa62Smrg fprintf(fp, "%f ", temp->getVertex(i)[1]); 784f220fa62Smrg } 785f220fa62Smrg fprintf(fp,"\n"); 786f220fa62Smrg } 787f220fa62Smrg fprintf(fp, "\n"); 788f220fa62Smrg } 789f220fa62Smrg fclose(fp); 790f220fa62Smrg} 791f220fa62Smrg 792f220fa62SmrgdirectedLine* readAllPolygons(char* filename) 793f220fa62Smrg{ 794f220fa62Smrg Int i,j; 795f220fa62Smrg FILE* fp = fopen(filename, "r"); 796f220fa62Smrg Int nPolygons; 797f220fa62Smrg int result; 798f220fa62Smrg 799f220fa62Smrg assert(fp); 800f220fa62Smrg result = fscanf(fp, "%i", &nPolygons); 801f220fa62Smrg assert(result != EOF); 802f220fa62Smrg directedLine *ret = NULL; 803f220fa62Smrg 804f220fa62Smrg for(i=0; i<nPolygons; i++) 805f220fa62Smrg { 806f220fa62Smrg Int nEdges; 807f220fa62Smrg result = fscanf(fp, "%i", &nEdges); 808f220fa62Smrg assert(result != EOF); 809f220fa62Smrg Real vert[2][2] = { { 0 } }; 810f220fa62Smrg Real VV[2][2]; 811f220fa62Smrg /*the first two vertices*/ 812f220fa62Smrg result = fscanf(fp, "%f", &(vert[0][0])); 813f220fa62Smrg assert(result != EOF); 814f220fa62Smrg result = fscanf(fp, "%f", &(vert[0][1])); 815f220fa62Smrg assert(result != EOF); 816f220fa62Smrg result = fscanf(fp, "%f", &(vert[1][0])); 817f220fa62Smrg assert(result != EOF); 818f220fa62Smrg result = fscanf(fp, "%f", &(vert[1][1])); 819f220fa62Smrg assert(result != EOF); 820f220fa62Smrg VV[1][0] = vert[0][0]; 821f220fa62Smrg VV[1][1] = vert[0][1]; 822f220fa62Smrg sampledLine *sLine = new sampledLine(2, vert); 823f220fa62Smrg directedLine *thisPoly = new directedLine(INCREASING, sLine); 824f220fa62SmrgthisPoly->rootLinkSet(NULL); 825f220fa62Smrg 826f220fa62Smrg directedLine *dLine; 827f220fa62Smrg for(j=2; j<nEdges; j++) 828f220fa62Smrg { 829f220fa62Smrg vert[0][0]=vert[1][0]; 830f220fa62Smrg vert[0][1]=vert[1][1]; 831f220fa62Smrg result = fscanf(fp, "%f", &(vert[1][0])); 832f220fa62Smrg assert(result != EOF); 833f220fa62Smrg result = fscanf(fp, "%f", &(vert[1][1])); 834f220fa62Smrg assert(result != EOF); 835f220fa62Smrg sLine = new sampledLine(2,vert); 836f220fa62Smrg dLine = new directedLine(INCREASING, sLine); 837f220fa62SmrgdLine->rootLinkSet(thisPoly); 838f220fa62Smrg thisPoly->insert(dLine); 839f220fa62Smrg } 840f220fa62Smrg 841f220fa62Smrg VV[0][0]=vert[1][0]; 842f220fa62Smrg VV[0][1]=vert[1][1]; 843f220fa62Smrg sLine = new sampledLine(2,VV); 844f220fa62Smrg dLine = new directedLine(INCREASING, sLine); 845f220fa62SmrgdLine->rootLinkSet(thisPoly); 846f220fa62Smrg thisPoly->insert(dLine); 847f220fa62Smrg 848f220fa62Smrg ret = thisPoly->insertPolygon(ret); 849f220fa62Smrg } 850f220fa62Smrg fclose(fp); 851f220fa62Smrg return ret; 852f220fa62Smrg} 853f220fa62Smrg 854f220fa62Smrg 855f220fa62Smrg 856f220fa62Smrg 857f220fa62Smrg 858f220fa62Smrg 859f220fa62Smrg 860f220fa62Smrg 861