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 "gluos.h" 39f220fa62Smrg#include <stdlib.h> 40f220fa62Smrg#include <stdio.h> 41f220fa62Smrg#include <GL/gl.h> 42f220fa62Smrg 43f220fa62Smrg#include "glimports.h" 44f220fa62Smrg#include "zlassert.h" 45f220fa62Smrg 46f220fa62Smrg#include "monoChain.h" 47f220fa62Smrg#include "quicksort.h" 48f220fa62Smrg#include "searchTree.h" 49f220fa62Smrg#include "polyUtil.h" 50f220fa62Smrg 51f220fa62Smrg#ifndef max 52f220fa62Smrg#define max(a,b) ((a>b)? a:b) 53f220fa62Smrg#endif 54f220fa62Smrg#ifndef min 55f220fa62Smrg#define min(a,b) ((a>b)? b:a) 56f220fa62Smrg#endif 57f220fa62Smrg 58f220fa62Smrgextern Int isCusp(directedLine *v); 59f220fa62Smrgextern Int deleteRepeatDiagonals(Int num_diagonals, directedLine** diagonal_vertices, directedLine** new_vertices); 60f220fa62Smrg 61f220fa62Smrg//for debug purpose only 62f220fa62Smrg#if 0 // UNUSED 63f220fa62Smrgstatic void drawDiagonals(Int num_diagonals, directedLine** diagonal_vertices) 64f220fa62Smrg{ 65f220fa62Smrg Int i; 66f220fa62Smrg for(i=0; i<num_diagonals; i++) 67f220fa62Smrg { 68f220fa62Smrg glBegin(GL_LINE); 69f220fa62Smrg glVertex2fv(diagonal_vertices[2*i]->head()); 70f220fa62Smrg glVertex2fv(diagonal_vertices[2*i+1]->head()); 71f220fa62Smrg glEnd(); 72f220fa62Smrg } 73f220fa62Smrg} 74f220fa62Smrg#endif 75f220fa62Smrg 76f220fa62Smrg/*given (x_1, y_1) and (x_2, y_2), and y 77f220fa62Smrg *return x such that (x,y) is on the line 78f220fa62Smrg */ 79f220fa62Smrginline Real intersectHoriz(Real x1, Real y1, Real x2, Real y2, Real y) 80f220fa62Smrg{ 81f220fa62Smrg return ((y2==y1)? (x1+x2)*0.5 : x1 + ((y-y1)/(y2-y1)) * (x2-x1)); 82f220fa62Smrg} 83f220fa62Smrg 84f220fa62Smrg//compare the heads of the two chains 85f220fa62Smrgstatic int compChainHeadInY(monoChain* mc1, monoChain* mc2) 86f220fa62Smrg{ 87f220fa62Smrg return compV2InY(mc1->getHead()->head(), mc2->getHead()->head()); 88f220fa62Smrg} 89f220fa62Smrg 90f220fa62SmrgmonoChain::monoChain(directedLine* cHead, directedLine* cTail) 91f220fa62Smrg{ 92f220fa62Smrg chainHead = cHead; 93f220fa62Smrg chainTail = cTail; 94f220fa62Smrg next = this; 95f220fa62Smrg prev = this; 96f220fa62Smrg 97f220fa62Smrg nextPolygon = NULL; 98f220fa62Smrg 99f220fa62Smrg //compute bounding box 100f220fa62Smrg directedLine* temp; 101f220fa62Smrg minX = maxX = chainTail->head()[0]; 102f220fa62Smrg minY = maxY = chainTail->head()[1]; 103f220fa62Smrg 104f220fa62Smrg for(temp=chainHead; temp!=cTail; temp = temp->getNext()) 105f220fa62Smrg { 106f220fa62Smrg if(temp->head()[0] < minX) 107f220fa62Smrg minX = temp->head()[0]; 108f220fa62Smrg if(temp->head()[0] > maxX) 109f220fa62Smrg maxX = temp->head()[0]; 110f220fa62Smrg 111f220fa62Smrg if(temp->head()[1] < minY) 112f220fa62Smrg minY = temp->head()[1]; 113f220fa62Smrg if(temp->head()[1] > maxY) 114f220fa62Smrg maxY = temp->head()[1]; 115f220fa62Smrg } 116f220fa62Smrg 117f220fa62Smrg //check whether the chain is increasing or decreasing 118f220fa62Smrg if(chainHead->compInY(chainTail) <0) 119f220fa62Smrg isIncrease = 1; 120f220fa62Smrg else 121f220fa62Smrg isIncrease = 0; 122f220fa62Smrg 123f220fa62Smrg //initilize currrent, this is used for accelerating search 124f220fa62Smrg if(isIncrease) 125f220fa62Smrg current = chainHead; 126f220fa62Smrg else 127f220fa62Smrg current = chainTail; 128f220fa62Smrg 129f220fa62Smrg isKey = 0; 130f220fa62Smrg keyY = 0; 131f220fa62Smrg} 132f220fa62Smrg 133f220fa62Smrg//insert a new line between prev and this 134f220fa62Smrgvoid monoChain::insert(monoChain* nc) 135f220fa62Smrg{ 136f220fa62Smrg nc->next = this; 137f220fa62Smrg nc->prev = prev; 138f220fa62Smrg prev->next = nc; 139f220fa62Smrg prev = nc; 140f220fa62Smrg} 141f220fa62Smrg 142f220fa62Smrgvoid monoChain::deleteLoop() 143f220fa62Smrg{ 144f220fa62Smrg monoChain *temp, *tempNext; 145f220fa62Smrg prev->next = NULL; 146f220fa62Smrg for(temp=this; temp != NULL; temp = tempNext) 147f220fa62Smrg { 148f220fa62Smrg tempNext = temp->next; 149f220fa62Smrg delete temp; 150f220fa62Smrg } 151f220fa62Smrg} 152f220fa62Smrg 153f220fa62Smrgvoid monoChain::deleteLoopList() 154f220fa62Smrg{ 155f220fa62Smrg monoChain *temp, *tempNext; 156f220fa62Smrg for(temp=this; temp != NULL; temp = tempNext) 157f220fa62Smrg { 158f220fa62Smrg tempNext = temp->nextPolygon; 159f220fa62Smrg temp->deleteLoop(); 160f220fa62Smrg } 161f220fa62Smrg} 162f220fa62Smrg 163f220fa62SmrgInt monoChain::toArraySingleLoop(monoChain** array, Int index) 164f220fa62Smrg{ 165f220fa62Smrg monoChain *temp; 166f220fa62Smrg array[index++] = this; 167f220fa62Smrg for(temp = next; temp != this; temp = temp->next) 168f220fa62Smrg { 169f220fa62Smrg array[index++] = temp; 170f220fa62Smrg } 171f220fa62Smrg return index; 172f220fa62Smrg} 173f220fa62Smrg 174f220fa62SmrgmonoChain** monoChain::toArrayAllLoops(Int& num_chains) 175f220fa62Smrg{ 176f220fa62Smrg num_chains = numChainsAllLoops(); 177f220fa62Smrg monoChain **ret = (monoChain**) malloc(sizeof(monoChain*) * num_chains); 178f220fa62Smrg assert(ret); 179f220fa62Smrg monoChain *temp; 180f220fa62Smrg Int index = 0; 181f220fa62Smrg for(temp = this; temp != NULL; temp=temp->nextPolygon){ 182f220fa62Smrg index = temp->toArraySingleLoop(ret, index); 183f220fa62Smrg } 184f220fa62Smrg return ret; 185f220fa62Smrg} 186f220fa62Smrg 187f220fa62SmrgInt monoChain::numChainsSingleLoop() 188f220fa62Smrg{ 189f220fa62Smrg Int ret=0; 190f220fa62Smrg monoChain* temp; 191f220fa62Smrg if(next == this) return 1; 192f220fa62Smrg ret = 1; 193f220fa62Smrg for(temp=next; temp != this; temp = temp->next) 194f220fa62Smrg ret++; 195f220fa62Smrg return ret; 196f220fa62Smrg} 197f220fa62Smrg 198f220fa62SmrgInt monoChain::numChainsAllLoops() 199f220fa62Smrg{ 200f220fa62Smrg Int ret=0; 201f220fa62Smrg monoChain *temp; 202f220fa62Smrg for(temp =this; temp != NULL; temp = temp->nextPolygon) 203f220fa62Smrg ret += temp->numChainsSingleLoop(); 204f220fa62Smrg return ret; 205f220fa62Smrg} 206f220fa62Smrg 207f220fa62Smrg//update 'current' 208f220fa62SmrgReal monoChain::chainIntersectHoriz(Real y) 209f220fa62Smrg{ 210f220fa62Smrg directedLine* temp; 211f220fa62Smrg if(isIncrease) 212f220fa62Smrg { 213f220fa62Smrg for(temp= current; temp != chainTail; temp = temp->getNext()) 214f220fa62Smrg { 215f220fa62Smrg if(temp->head()[1] > y) 216f220fa62Smrg break; 217f220fa62Smrg } 218f220fa62Smrg current = temp->getPrev(); 219f220fa62Smrg } 220f220fa62Smrg else 221f220fa62Smrg { 222f220fa62Smrg for(temp = current; temp != chainHead; temp = temp->getPrev()) 223f220fa62Smrg { 224f220fa62Smrg if(temp->head()[1] > y) 225f220fa62Smrg break; 226f220fa62Smrg } 227f220fa62Smrg current = temp->getNext(); 228f220fa62Smrg } 229f220fa62Smrg return intersectHoriz(current->head()[0], current->head()[1], current->tail()[0], current->tail()[1], y); 230f220fa62Smrg} 231f220fa62Smrg 232f220fa62SmrgmonoChain* directedLineLoopToMonoChainLoop(directedLine* loop) 233f220fa62Smrg{ 234f220fa62Smrg directedLine *temp; 235f220fa62Smrg monoChain *ret=NULL; 236f220fa62Smrg 237f220fa62Smrg //find the first cusp 238f220fa62Smrg directedLine *prevCusp=NULL; 239f220fa62Smrg directedLine *firstCusp; 240f220fa62Smrg 241f220fa62Smrg if(isCusp(loop)) 242f220fa62Smrg prevCusp = loop; 243f220fa62Smrg else 244f220fa62Smrg { 245f220fa62Smrg for(temp = loop->getNext(); temp != loop; temp = temp->getNext()) 246f220fa62Smrg if(isCusp(temp)) 247f220fa62Smrg break; 248f220fa62Smrg prevCusp = temp; 249f220fa62Smrg } 250f220fa62Smrg firstCusp = prevCusp; 251f220fa62Smrg//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]); 252f220fa62Smrg 253f220fa62Smrg for(temp = prevCusp->getNext(); temp != loop; temp = temp->getNext()) 254f220fa62Smrg { 255f220fa62Smrg if(isCusp(temp)) 256f220fa62Smrg { 257f220fa62Smrg//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]); 258f220fa62Smrg if(ret == NULL) 259f220fa62Smrg { 260f220fa62Smrg ret = new monoChain(prevCusp, temp); 261f220fa62Smrg } 262f220fa62Smrg else 263f220fa62Smrg ret->insert(new monoChain(prevCusp, temp)); 264f220fa62Smrg prevCusp = temp; 265f220fa62Smrg } 266f220fa62Smrg } 267f220fa62Smrg assert(ret); 268f220fa62Smrg ret->insert(new monoChain(prevCusp, firstCusp)); 269f220fa62Smrg 270f220fa62Smrg return ret; 271f220fa62Smrg} 272f220fa62Smrg 273f220fa62SmrgmonoChain* directedLineLoopListToMonoChainLoopList(directedLine* list) 274f220fa62Smrg{ 275f220fa62Smrg directedLine* temp; 276f220fa62Smrg monoChain* mc; 277f220fa62Smrg monoChain* mcEnd; 278f220fa62Smrg mc = directedLineLoopToMonoChainLoop(list); 279f220fa62Smrg mcEnd = mc; 280f220fa62Smrg for(temp = list->getNextPolygon(); temp != NULL; temp = temp->getNextPolygon()) 281f220fa62Smrg { 282f220fa62Smrg monoChain *newLoop = directedLineLoopToMonoChainLoop(temp); 283f220fa62Smrg mcEnd->setNextPolygon(newLoop); 284f220fa62Smrg mcEnd = newLoop; 285f220fa62Smrg } 286f220fa62Smrg return mc; 287f220fa62Smrg} 288f220fa62Smrg 289f220fa62Smrg/*compare two edges of a polygon. 290f220fa62Smrg *edge A < edge B if there is a horizontal line so that the intersection 291f220fa62Smrg *with A is to the left of the intersection with B. 292f220fa62Smrg *This function is used in sweepY for the dynamic search tree insertion to 293f220fa62Smrg *order the edges. 294f220fa62Smrg * Implementation: (x_1,y_1) and (x_2, y_2) 295f220fa62Smrg */ 296f220fa62Smrgstatic Int compEdges(directedLine *e1, directedLine *e2) 297f220fa62Smrg{ 298f220fa62Smrg Real* head1 = e1->head(); 299f220fa62Smrg Real* tail1 = e1->tail(); 300f220fa62Smrg Real* head2 = e2->head(); 301f220fa62Smrg Real* tail2 = e2->tail(); 302f220fa62Smrg/* 303f220fa62Smrg Real h10 = head1[0]; 304f220fa62Smrg Real h11 = head1[1]; 305f220fa62Smrg Real t10 = tail1[0]; 306f220fa62Smrg Real t11 = tail1[1]; 307f220fa62Smrg Real h20 = head2[0]; 308f220fa62Smrg Real h21 = head2[1]; 309f220fa62Smrg Real t20 = tail2[0]; 310f220fa62Smrg Real t21 = tail2[1]; 311f220fa62Smrg*/ 312f220fa62Smrg Real e1_Ymax, e1_Ymin, e2_Ymax, e2_Ymin; 313f220fa62Smrg/* 314f220fa62Smrg if(h11>t11) { 315f220fa62Smrg e1_Ymax= h11; 316f220fa62Smrg e1_Ymin= t11; 317f220fa62Smrg } 318f220fa62Smrg else{ 319f220fa62Smrg e1_Ymax = t11; 320f220fa62Smrg e1_Ymin = h11; 321f220fa62Smrg } 322f220fa62Smrg 323f220fa62Smrg if(h21>t21) { 324f220fa62Smrg e2_Ymax= h21; 325f220fa62Smrg e2_Ymin= t21; 326f220fa62Smrg } 327f220fa62Smrg else{ 328f220fa62Smrg e2_Ymax = t21; 329f220fa62Smrg e2_Ymin = h21; 330f220fa62Smrg } 331f220fa62Smrg*/ 332f220fa62Smrg 333f220fa62Smrg if(head1[1]>tail1[1]) { 334f220fa62Smrg e1_Ymax= head1[1]; 335f220fa62Smrg e1_Ymin= tail1[1]; 336f220fa62Smrg } 337f220fa62Smrg else{ 338f220fa62Smrg e1_Ymax = tail1[1]; 339f220fa62Smrg e1_Ymin = head1[1]; 340f220fa62Smrg } 341f220fa62Smrg 342f220fa62Smrg if(head2[1]>tail2[1]) { 343f220fa62Smrg e2_Ymax= head2[1]; 344f220fa62Smrg e2_Ymin= tail2[1]; 345f220fa62Smrg } 346f220fa62Smrg else{ 347f220fa62Smrg e2_Ymax = tail2[1]; 348f220fa62Smrg e2_Ymin = head2[1]; 349f220fa62Smrg } 350f220fa62Smrg 351f220fa62Smrg 352f220fa62Smrg /*Real e1_Ymax = max(head1[1], tail1[1]);*/ /*max(e1->head()[1], e1->tail()[1]);*/ 353f220fa62Smrg /*Real e1_Ymin = min(head1[1], tail1[1]);*/ /*min(e1->head()[1], e1->tail()[1]);*/ 354f220fa62Smrg /*Real e2_Ymax = max(head2[1], tail2[1]);*/ /*max(e2->head()[1], e2->tail()[1]);*/ 355f220fa62Smrg /*Real e2_Ymin = min(head2[1], tail2[1]);*/ /*min(e2->head()[1], e2->tail()[1]);*/ 356f220fa62Smrg 357f220fa62Smrg Real Ymax = min(e1_Ymax, e2_Ymax); 358f220fa62Smrg Real Ymin = max(e1_Ymin, e2_Ymin); 359f220fa62Smrg 360f220fa62Smrg Real y = 0.5*(Ymax + Ymin); 361f220fa62Smrg 362f220fa62Smrg/* Real x1 = intersectHoriz(e1->head()[0], e1->head()[1], e1->tail()[0], e1->tail()[1], y); 363f220fa62Smrg Real x2 = intersectHoriz(e2->head()[0], e2->head()[1], e2->tail()[0], e2->tail()[1], y); 364f220fa62Smrg*/ 365f220fa62Smrg/* 366f220fa62Smrg Real x1 = intersectHoriz(h10, h11, t10, t11, y); 367f220fa62Smrg Real x2 = intersectHoriz(h20, h21, t20, t21, y); 368f220fa62Smrg*/ 369f220fa62Smrg Real x1 = intersectHoriz(head1[0], head1[1], tail1[0], tail1[1], y); 370f220fa62Smrg Real x2 = intersectHoriz(head2[0], head2[1], tail2[0], tail2[1], y); 371f220fa62Smrg 372f220fa62Smrg if(x1<= x2) return -1; 373f220fa62Smrg else return 1; 374f220fa62Smrg} 375f220fa62Smrg 376f220fa62SmrgInt compChains(monoChain* mc1, monoChain* mc2) 377f220fa62Smrg{ 378f220fa62Smrg Real y; 379f220fa62Smrg assert(mc1->isKey || mc2->isKey); 380f220fa62Smrg if(mc1->isKey) 381f220fa62Smrg y = mc1->keyY; 382f220fa62Smrg else 383f220fa62Smrg y = mc2->keyY; 384f220fa62Smrg directedLine *d1 = mc1->find(y); 385f220fa62Smrg directedLine *d2 = mc2->find(y); 386f220fa62Smrg mc2->find(y); 387f220fa62Smrg// Real x1 = mc1->chainIntersectHoriz(y); 388f220fa62Smrg// Real x2 = mc2->chainIntersectHoriz(y); 389f220fa62Smrg return compEdges(d1, d2); 390f220fa62Smrg} 391f220fa62Smrg 392f220fa62Smrg//this function modifies current for efficiency 393f220fa62SmrgdirectedLine* monoChain::find(Real y) 394f220fa62Smrg{ 395f220fa62Smrg directedLine *ret; 396f220fa62Smrg directedLine *temp; 397f220fa62Smrg assert(current->head()[1] <= y); 398f220fa62Smrg if(isIncrease) 399f220fa62Smrg { 400f220fa62Smrg assert(chainTail->head()[1] >=y); 401f220fa62Smrg for(temp=current; temp!=chainTail; temp = temp->getNext()) 402f220fa62Smrg { 403f220fa62Smrg if(temp->head()[1] > y) 404f220fa62Smrg break; 405f220fa62Smrg } 406f220fa62Smrg current = temp->getPrev(); 407f220fa62Smrg ret = current; 408f220fa62Smrg } 409f220fa62Smrg else 410f220fa62Smrg { 411f220fa62Smrg for(temp=current; temp != chainHead; temp = temp->getPrev()) 412f220fa62Smrg { 413f220fa62Smrg if(temp->head()[1] > y) 414f220fa62Smrg break; 415f220fa62Smrg } 416f220fa62Smrg current = temp->getNext(); 417f220fa62Smrg ret = temp; 418f220fa62Smrg } 419f220fa62Smrg return ret; 420f220fa62Smrg} 421f220fa62Smrg 422f220fa62Smrgvoid monoChain::printOneChain() 423f220fa62Smrg{ 424f220fa62Smrg directedLine* temp; 425f220fa62Smrg for(temp = chainHead; temp != chainTail; temp = temp->getNext()) 426f220fa62Smrg { 427f220fa62Smrg printf("(%f,%f) ", temp->head()[0], temp->head()[1]); 428f220fa62Smrg } 429f220fa62Smrg printf("(%f,%f) \n", chainTail->head()[0], chainTail->head()[1]); 430f220fa62Smrg} 431f220fa62Smrg 432f220fa62Smrgvoid monoChain::printChainLoop() 433f220fa62Smrg{ 434f220fa62Smrg monoChain* temp; 435f220fa62Smrg this->printOneChain(); 436f220fa62Smrg for(temp = next; temp != this; temp = temp->next) 437f220fa62Smrg { 438f220fa62Smrg temp->printOneChain(); 439f220fa62Smrg } 440f220fa62Smrg printf("\n"); 441f220fa62Smrg} 442f220fa62Smrg 443f220fa62Smrgvoid monoChain::printAllLoops() 444f220fa62Smrg{ 445f220fa62Smrg monoChain* temp; 446f220fa62Smrg for(temp=this; temp != NULL; temp = temp->nextPolygon) 447f220fa62Smrg temp->printChainLoop(); 448f220fa62Smrg} 449f220fa62Smrg 450f220fa62Smrg//return 1 if error occures 451f220fa62SmrgInt MC_sweepY(Int nVertices, monoChain** sortedVertices, sweepRange** ret_ranges) 452f220fa62Smrg{ 453f220fa62Smrg Int i; 454f220fa62Smrg Real keyY; 455f220fa62Smrg Int errOccur=0; 456f220fa62Smrg//printf("enter MC_sweepY\n"); 457f220fa62Smrg//printf("nVertices=%i\n", nVertices); 458f220fa62Smrg /*for each vertex in the sorted list, update the binary search tree. 459f220fa62Smrg *and store the range information for each vertex. 460f220fa62Smrg */ 461f220fa62Smrg treeNode* searchTree = NULL; 462f220fa62Smrg//printf("nVertices=%i\n", nVertices); 463f220fa62Smrg for(i=0; i<nVertices; i++) 464f220fa62Smrg { 465f220fa62Smrg monoChain* vert = sortedVertices[i]; 466f220fa62Smrg keyY = vert->getHead()->head()[1]; //the sweep line 467f220fa62Smrg directedLine *dline = vert->getHead(); 468f220fa62Smrg directedLine *dlinePrev = dline->getPrev(); 469f220fa62Smrg if(isBelow(dline, dline) && isBelow(dline, dlinePrev)) 470f220fa62Smrg { 471f220fa62Smrg//printf("case 1\n"); 472f220fa62Smrg //this<v and prev < v 473f220fa62Smrg //delete both edges 474f220fa62Smrg vert->isKey = 1; 475f220fa62Smrg vert->keyY = keyY; 476f220fa62Smrg treeNode* thisNode = TreeNodeFind(searchTree, vert, (Int (*) (void *, void *))compChains); 477f220fa62Smrg vert->isKey = 0; 478f220fa62Smrg 479f220fa62Smrg vert->getPrev()->isKey = 1; 480f220fa62Smrg vert->getPrev()->keyY = keyY; 481f220fa62Smrg treeNode* prevNode = TreeNodeFind(searchTree, vert->getPrev(), (Int (*) (void *, void *))compChains); 482f220fa62Smrg vert->getPrev()->isKey = 0; 483f220fa62Smrg 484f220fa62Smrg if(cuspType(dline) == 1)//interior cusp 485f220fa62Smrg { 486f220fa62Smrg 487f220fa62Smrg treeNode* leftEdge = TreeNodePredecessor(prevNode); 488f220fa62Smrg treeNode* rightEdge = TreeNodeSuccessor(thisNode); 489f220fa62Smrg if(leftEdge == NULL || rightEdge == NULL) 490f220fa62Smrg { 491f220fa62Smrg errOccur = 1; 492f220fa62Smrg goto JUMP_HERE; 493f220fa62Smrg } 494f220fa62Smrg 495f220fa62Smrg directedLine* leftEdgeDline = ((monoChain* ) leftEdge->key)->find(keyY); 496f220fa62Smrg 497f220fa62Smrg 498f220fa62Smrg 499f220fa62Smrg directedLine* rightEdgeDline = ((monoChain* ) rightEdge->key)->find(keyY); 500f220fa62Smrg 501f220fa62Smrg ret_ranges[i] = sweepRangeMake(leftEdgeDline, 1, rightEdgeDline, 1); 502f220fa62Smrg } 503f220fa62Smrg else /*exterior cusp*/ 504f220fa62Smrg { 505f220fa62Smrg ret_ranges[i] = sweepRangeMake( dline, 1, dlinePrev, 1); 506f220fa62Smrg } 507f220fa62Smrg 508f220fa62Smrg searchTree = TreeNodeDeleteSingleNode(searchTree, thisNode); 509f220fa62Smrg searchTree = TreeNodeDeleteSingleNode(searchTree, prevNode); 510f220fa62Smrg 511f220fa62Smrg } 512f220fa62Smrg else if(isAbove(dline, dline) && isAbove(dline, dlinePrev)) 513f220fa62Smrg { 514f220fa62Smrg//printf("case 2\n"); 515f220fa62Smrg //insert both edges 516f220fa62Smrg treeNode* thisNode = TreeNodeMake(vert); 517f220fa62Smrg treeNode* prevNode = TreeNodeMake(vert->getPrev()); 518f220fa62Smrg 519f220fa62Smrg vert->isKey = 1; 520f220fa62Smrg vert->keyY = keyY; 521f220fa62Smrg searchTree = TreeNodeInsert(searchTree, thisNode, (Int (*) (void *, void *))compChains); 522f220fa62Smrg vert->isKey = 0; 523f220fa62Smrg 524f220fa62Smrg vert->getPrev()->isKey = 1; 525f220fa62Smrg vert->getPrev()->keyY = keyY; 526f220fa62Smrg searchTree = TreeNodeInsert(searchTree, prevNode, (Int (*) (void *, void *))compChains); 527f220fa62Smrg vert->getPrev()->isKey = 0; 528f220fa62Smrg 529f220fa62Smrg if(cuspType(dline) == 1) //interior cusp 530f220fa62Smrg { 531f220fa62Smrg//printf("cuspType is 1\n"); 532f220fa62Smrg treeNode* leftEdge = TreeNodePredecessor(thisNode); 533f220fa62Smrg treeNode* rightEdge = TreeNodeSuccessor(prevNode); 534f220fa62Smrg if(leftEdge == NULL || rightEdge == NULL) 535f220fa62Smrg { 536f220fa62Smrg errOccur = 1; 537f220fa62Smrg goto JUMP_HERE; 538f220fa62Smrg } 539f220fa62Smrg//printf("leftEdge is %i, rightEdge is %i\n", leftEdge, rightEdge); 540f220fa62Smrg directedLine* leftEdgeDline = ((monoChain*) leftEdge->key)->find(keyY); 541f220fa62Smrg directedLine* rightEdgeDline = ((monoChain*) rightEdge->key)->find(keyY); 542f220fa62Smrg ret_ranges[i] = sweepRangeMake( leftEdgeDline, 1, rightEdgeDline, 1); 543f220fa62Smrg } 544f220fa62Smrg else //exterior cusp 545f220fa62Smrg { 546f220fa62Smrg//printf("cuspType is not 1\n"); 547f220fa62Smrg ret_ranges[i] = sweepRangeMake(dlinePrev, 1, dline, 1); 548f220fa62Smrg } 549f220fa62Smrg } 550f220fa62Smrg else 551f220fa62Smrg { 552f220fa62Smrg//printf("%i,%i\n", isAbove(dline, dline), isAbove(dline, dlinePrev)); 553f220fa62Smrg errOccur = 1; 554f220fa62Smrg goto JUMP_HERE; 555f220fa62Smrg 556f220fa62Smrg fprintf(stderr, "error in MC_sweepY\n"); 557f220fa62Smrg exit(1); 558f220fa62Smrg } 559f220fa62Smrg } 560f220fa62Smrg 561f220fa62Smrg JUMP_HERE: 562f220fa62Smrg //finally clean up space: delete the search tree 563f220fa62Smrg TreeNodeDeleteWholeTree(searchTree); 564f220fa62Smrg return errOccur; 565f220fa62Smrg} 566f220fa62Smrg 567f220fa62Smrgvoid MC_findDiagonals(Int total_num_edges, monoChain** sortedVertices, 568f220fa62Smrg sweepRange** ranges, Int& num_diagonals, 569f220fa62Smrg directedLine** diagonal_vertices) 570f220fa62Smrg{ 571f220fa62Smrg Int i,j,k; 572f220fa62Smrg k=0; 573f220fa62Smrg //reset 'current' of all the monoChains 574f220fa62Smrg for(i=0; i<total_num_edges; i++) 575f220fa62Smrg sortedVertices[i]->resetCurrent(); 576f220fa62Smrg 577f220fa62Smrg for(i=0; i<total_num_edges; i++) 578f220fa62Smrg { 579f220fa62Smrg directedLine* vert = sortedVertices[i]->getHead(); 580f220fa62Smrg directedLine* thisEdge = vert; 581f220fa62Smrg directedLine* prevEdge = vert->getPrev(); 582f220fa62Smrg if(isBelow(vert, thisEdge) && isBelow(vert, prevEdge) && compEdges(prevEdge, thisEdge)<0) 583f220fa62Smrg { 584f220fa62Smrg //this is an upward interior cusp 585f220fa62Smrg diagonal_vertices[k++] = vert; 586f220fa62Smrg 587f220fa62Smrg directedLine* leftEdge = ranges[i]->left; 588f220fa62Smrg directedLine* rightEdge = ranges[i]->right; 589f220fa62Smrg 590f220fa62Smrg directedLine* leftVert = leftEdge; 591f220fa62Smrg directedLine* rightVert = rightEdge->getNext(); 592f220fa62Smrg assert(leftVert->head()[1] >= vert->head()[1]); 593f220fa62Smrg assert(rightVert->head()[1] >= vert->head()[1]); 594f220fa62Smrg directedLine* minVert = (leftVert->head()[1] <= rightVert->head()[1])?leftVert:rightVert; 595f220fa62Smrg Int found = 0; 596f220fa62Smrg for(j=i+1; j<total_num_edges; j++) 597f220fa62Smrg { 598f220fa62Smrg if(sortedVertices[j]->getHead()->head()[1] > minVert->head()[1]) 599f220fa62Smrg break; 600f220fa62Smrg 601f220fa62Smrg if(sweepRangeEqual(ranges[i], ranges[j])) 602f220fa62Smrg { 603f220fa62Smrg found = 1; 604f220fa62Smrg break; 605f220fa62Smrg } 606f220fa62Smrg } 607f220fa62Smrg 608f220fa62Smrg if(found) 609f220fa62Smrg diagonal_vertices[k++] = sortedVertices[j]->getHead(); 610f220fa62Smrg else 611f220fa62Smrg diagonal_vertices[k++] = minVert; 612f220fa62Smrg } 613f220fa62Smrg else if(isAbove(vert, thisEdge) && isAbove(vert, prevEdge) && compEdges(prevEdge, thisEdge)>0) 614f220fa62Smrg { 615f220fa62Smrg //downward interior cusp 616f220fa62Smrg diagonal_vertices[k++] = vert; 617f220fa62Smrg directedLine* leftEdge = ranges[i]->left; 618f220fa62Smrg directedLine* rightEdge = ranges[i]->right; 619f220fa62Smrg directedLine* leftVert = leftEdge->getNext(); 620f220fa62Smrg directedLine* rightVert = rightEdge; 621f220fa62Smrg assert(leftVert->head()[1] <= vert->head()[1]); 622f220fa62Smrg assert(rightVert->head()[1] <= vert->head()[1]); 623f220fa62Smrg directedLine* maxVert = (leftVert->head()[1] > rightVert->head()[1])? leftVert:rightVert; 624f220fa62Smrg Int found=0; 625f220fa62Smrg for(j=i-1; j>=0; j--) 626f220fa62Smrg { 627f220fa62Smrg if(sortedVertices[j]->getHead()->head()[1] < maxVert->head()[1]) 628f220fa62Smrg break; 629f220fa62Smrg if(sweepRangeEqual(ranges[i], ranges[j])) 630f220fa62Smrg { 631f220fa62Smrg found = 1; 632f220fa62Smrg break; 633f220fa62Smrg } 634f220fa62Smrg } 635f220fa62Smrg if(found) 636f220fa62Smrg diagonal_vertices[k++] = sortedVertices[j]->getHead(); 637f220fa62Smrg else 638f220fa62Smrg diagonal_vertices[k++] = maxVert; 639f220fa62Smrg } 640f220fa62Smrg } 641f220fa62Smrg num_diagonals = k/2; 642f220fa62Smrg} 643f220fa62Smrg 644f220fa62Smrg 645f220fa62Smrg 646f220fa62Smrg 647f220fa62SmrgdirectedLine* MC_partitionY(directedLine *polygons, sampledLine **retSampledLines) 648f220fa62Smrg{ 649f220fa62Smrg//printf("enter mc_partitionY\n"); 650f220fa62Smrg Int total_num_chains = 0; 651f220fa62Smrg monoChain* loopList = directedLineLoopListToMonoChainLoopList(polygons); 652f220fa62Smrg monoChain** array = loopList->toArrayAllLoops(total_num_chains); 653f220fa62Smrg 654f220fa62Smrg if(total_num_chains<=2) //there is just one single monotone polygon 655f220fa62Smrg { 656f220fa62Smrg loopList->deleteLoopList(); 657f220fa62Smrg free(array); 658f220fa62Smrg *retSampledLines = NULL; 659f220fa62Smrg return polygons; 660f220fa62Smrg } 661f220fa62Smrg 662f220fa62Smrg//loopList->printAllLoops(); 663f220fa62Smrg//printf("total_num_chains=%i\n", total_num_chains); 664f220fa62Smrg quicksort( (void**)array, 0, total_num_chains-1, (Int (*)(void*, void*))compChainHeadInY); 665f220fa62Smrg//printf("after quicksort\n"); 666f220fa62Smrg 667f220fa62Smrg sweepRange** ranges = (sweepRange**)malloc(sizeof(sweepRange*) * (total_num_chains)); 668f220fa62Smrg assert(ranges); 669f220fa62Smrg 670f220fa62Smrg if(MC_sweepY(total_num_chains, array, ranges)) 671f220fa62Smrg { 672f220fa62Smrg loopList->deleteLoopList(); 673f220fa62Smrg free(array); 674f220fa62Smrg *retSampledLines = NULL; 675f220fa62Smrg return NULL; 676f220fa62Smrg } 677f220fa62Smrg//printf("after MC_sweepY\n"); 678f220fa62Smrg 679f220fa62Smrg 680f220fa62Smrg Int num_diagonals; 681f220fa62Smrg /*number diagonals is < total_num_edges*total_num_edges*/ 682f220fa62Smrg directedLine** diagonal_vertices = (directedLine**) malloc(sizeof(directedLine*) * total_num_chains*2/*total_num_edges*/); 683f220fa62Smrg assert(diagonal_vertices); 684f220fa62Smrg 685f220fa62Smrg//printf("before call MC_findDiagonales\n"); 686f220fa62Smrg 687f220fa62Smrg MC_findDiagonals(total_num_chains, array, ranges, num_diagonals, diagonal_vertices); 688f220fa62Smrg//printf("after call MC_findDia, num_diagnla=%i\n", num_diagonals); 689f220fa62Smrg 690f220fa62Smrg directedLine* ret_polygons = polygons; 691f220fa62Smrg sampledLine* newSampledLines = NULL; 692f220fa62Smrg Int i,k; 693f220fa62Smrg 694f220fa62Smrg num_diagonals=deleteRepeatDiagonals(num_diagonals, diagonal_vertices, diagonal_vertices); 695f220fa62Smrg 696f220fa62Smrg 697f220fa62Smrg 698f220fa62Smrg//drawDiagonals(num_diagonals, diagonal_vertices); 699f220fa62Smrg//printf("diagoanls are \n"); 700f220fa62Smrg//for(i=0; i<num_diagonals; i++) 701f220fa62Smrg// { 702f220fa62Smrg// printf("(%f,%f)\n", diagonal_vertices[2*i]->head()[0], diagonal_vertices[2*i]->head()[1]); 703f220fa62Smrg// printf("**(%f,%f)\n", diagonal_vertices[2*i+1]->head()[0], diagonal_vertices[2*i+1]->head()[1]); 704f220fa62Smrg// } 705f220fa62Smrg 706f220fa62Smrg Int *removedDiagonals=(Int*)malloc(sizeof(Int) * num_diagonals); 707f220fa62Smrg for(i=0; i<num_diagonals; i++) 708f220fa62Smrg removedDiagonals[i] = 0; 709f220fa62Smrg// printf("first pass\n"); 710f220fa62Smrg 711f220fa62Smrg 712f220fa62Smrg for(i=0,k=0; i<num_diagonals; i++,k+=2) 713f220fa62Smrg { 714f220fa62Smrg 715f220fa62Smrg 716f220fa62Smrg directedLine* v1=diagonal_vertices[k]; 717f220fa62Smrg directedLine* v2=diagonal_vertices[k+1]; 718f220fa62Smrg directedLine* ret_p1; 719f220fa62Smrg directedLine* ret_p2; 720f220fa62Smrg 721f220fa62Smrg /*we ahve to determine whether v1 and v2 belong to the same polygon before 722f220fa62Smrg *their structure are modified by connectDiagonal(). 723f220fa62Smrg */ 724f220fa62Smrg/* 725f220fa62Smrg directedLine *root1 = v1->findRoot(); 726f220fa62Smrg directedLine *root2 = v2->findRoot(); 727f220fa62Smrg assert(root1); 728f220fa62Smrg assert(root2); 729f220fa62Smrg*/ 730f220fa62Smrg 731f220fa62SmrgdirectedLine* root1 = v1->rootLinkFindRoot(); 732f220fa62SmrgdirectedLine* root2 = v2->rootLinkFindRoot(); 733f220fa62Smrg 734f220fa62Smrg if(root1 != root2) 735f220fa62Smrg { 736f220fa62Smrg 737f220fa62Smrg removedDiagonals[i] = 1; 738f220fa62Smrg sampledLine* generatedLine; 739f220fa62Smrg 740f220fa62Smrg 741f220fa62Smrg 742f220fa62Smrg v1->connectDiagonal(v1,v2, &ret_p1, &ret_p2, &generatedLine, ret_polygons); 743f220fa62Smrg 744f220fa62Smrg 745f220fa62Smrg 746f220fa62Smrg newSampledLines = generatedLine->insert(newSampledLines); 747f220fa62Smrg/* 748f220fa62Smrg ret_polygons = ret_polygons->cutoffPolygon(root1); 749f220fa62Smrg 750f220fa62Smrg ret_polygons = ret_polygons->cutoffPolygon(root2); 751f220fa62Smrg ret_polygons = ret_p1->insertPolygon(ret_polygons); 752f220fa62Smrgroot1->rootLinkSet(ret_p1); 753f220fa62Smrgroot2->rootLinkSet(ret_p1); 754f220fa62Smrgret_p1->rootLinkSet(NULL); 755f220fa62Smrgret_p2->rootLinkSet(ret_p1); 756f220fa62Smrg*/ 757f220fa62Smrg ret_polygons = ret_polygons->cutoffPolygon(root2); 758f220fa62Smrg 759f220fa62Smrg 760f220fa62Smrg 761f220fa62Smrgroot2->rootLinkSet(root1); 762f220fa62Smrgret_p1->rootLinkSet(root1); 763f220fa62Smrgret_p2->rootLinkSet(root1); 764f220fa62Smrg 765f220fa62Smrg /*now that we have connected the diagonal v1 and v2, 766f220fa62Smrg *we have to check those unprocessed diagonals which 767f220fa62Smrg *have v1 or v2 as an end point. Notice that the head of v1 768f220fa62Smrg *has the same coodinates as the head of v2->prev, and the head of 769f220fa62Smrg *v2 has the same coordinate as the head of v1->prev. 770f220fa62Smrg *Suppose these is a diagonal (v1, x). If (v1,x) is still a valid 771f220fa62Smrg *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 772f220fa62Smrg *replaced by (v2->prev, x), that is, x is on the left of 773f220fa62Smrg * v2->prev->prev->head, v2->prev->head, v2->prev->tail. 774f220fa62Smrg */ 775f220fa62Smrg Int ii, kk; 776f220fa62Smrg for(ii=0, kk=0; ii<num_diagonals; ii++, kk+=2) 777f220fa62Smrg if( removedDiagonals[ii]==0) 778f220fa62Smrg { 779f220fa62Smrg directedLine* d1=diagonal_vertices[kk]; 780f220fa62Smrg directedLine* d2=diagonal_vertices[kk+1]; 781f220fa62Smrg /*check d1, and replace diagonal_vertices[kk] if necessary*/ 782f220fa62Smrg if(d1 == v1) { 783f220fa62Smrg /*check if d2 is to left of v1->prev->head:v1->head:v1->tail*/ 784f220fa62Smrg if(! pointLeft2Lines(v1->getPrev()->head(), 785f220fa62Smrg v1->head(), v1->tail(), d2->head())) 786f220fa62Smrg { 787f220fa62Smrg/* 788f220fa62Smrg assert(pointLeft2Lines(v2->getPrev()->getPrev()->head(), 789f220fa62Smrg v2->getPrev()->head(), 790f220fa62Smrg v2->getPrev()->tail(), d2->head())); 791f220fa62Smrg*/ 792f220fa62Smrg diagonal_vertices[kk] = v2->getPrev(); 793f220fa62Smrg } 794f220fa62Smrg } 795f220fa62Smrg if(d1 == v2) { 796f220fa62Smrg /*check if d2 is to left of v2->prev->head:v2->head:v2->tail*/ 797f220fa62Smrg if(! pointLeft2Lines(v2->getPrev()->head(), 798f220fa62Smrg v2->head(), v2->tail(), d2->head())) 799f220fa62Smrg { 800f220fa62Smrg/* 801f220fa62Smrg assert(pointLeft2Lines(v1->getPrev()->getPrev()->head(), 802f220fa62Smrg v1->getPrev()->head(), 803f220fa62Smrg v1->getPrev()->tail(), d2->head())); 804f220fa62Smrg*/ 805f220fa62Smrg diagonal_vertices[kk] = v1->getPrev(); 806f220fa62Smrg } 807f220fa62Smrg } 808f220fa62Smrg /*check d2 and replace diagonal_vertices[k+1] if necessary*/ 809f220fa62Smrg if(d2 == v1) { 810f220fa62Smrg /*check if d1 is to left of v1->prev->head:v1->head:v1->tail*/ 811f220fa62Smrg if(! pointLeft2Lines(v1->getPrev()->head(), 812f220fa62Smrg v1->head(), v1->tail(), d1->head())) 813f220fa62Smrg { 814f220fa62Smrg/* assert(pointLeft2Lines(v2->getPrev()->getPrev()->head(), 815f220fa62Smrg v2->getPrev()->head(), 816f220fa62Smrg v2->getPrev()->tail(), d1->head())); 817f220fa62Smrg*/ 818f220fa62Smrg diagonal_vertices[kk+1] = v2->getPrev(); 819f220fa62Smrg } 820f220fa62Smrg } 821f220fa62Smrg if(d2 == v2) { 822f220fa62Smrg /*check if d1 is to left of v2->prev->head:v2->head:v2->tail*/ 823f220fa62Smrg if(! pointLeft2Lines(v2->getPrev()->head(), 824f220fa62Smrg v2->head(), v2->tail(), d1->head())) 825f220fa62Smrg { 826f220fa62Smrg/* assert(pointLeft2Lines(v1->getPrev()->getPrev()->head(), 827f220fa62Smrg v1->getPrev()->head(), 828f220fa62Smrg v1->getPrev()->tail(), d1->head())); 829f220fa62Smrg*/ 830f220fa62Smrg diagonal_vertices[kk+1] = v1->getPrev(); 831f220fa62Smrg } 832f220fa62Smrg } 833f220fa62Smrg } 834f220fa62Smrg}/*end if (root1 not equal to root 2)*/ 835f220fa62Smrg} 836f220fa62Smrg 837f220fa62Smrg /*second pass, now all diagoals should belong to the same polygon*/ 838f220fa62Smrg//printf("second pass: \n"); 839f220fa62Smrg 840f220fa62Smrg// for(i=0; i<num_diagonals; i++) 841f220fa62Smrg// printf("%i ", removedDiagonals[i]); 842f220fa62Smrg 843f220fa62Smrg 844f220fa62Smrg for(i=0,k=0; i<num_diagonals; i++, k += 2) 845f220fa62Smrg if(removedDiagonals[i] == 0) 846f220fa62Smrg { 847f220fa62Smrg 848f220fa62Smrg 849f220fa62Smrg directedLine* v1=diagonal_vertices[k]; 850f220fa62Smrg directedLine* v2=diagonal_vertices[k+1]; 851f220fa62Smrg 852f220fa62Smrg 853f220fa62Smrg 854f220fa62Smrg directedLine* ret_p1; 855f220fa62Smrg directedLine* ret_p2; 856f220fa62Smrg 857f220fa62Smrg /*we ahve to determine whether v1 and v2 belong to the same polygon before 858f220fa62Smrg *their structure are modified by connectDiagonal(). 859f220fa62Smrg */ 860f220fa62Smrg directedLine *root1 = v1->findRoot(); 861f220fa62Smrg/* 862f220fa62Smrg directedLine *root2 = v2->findRoot(); 863f220fa62Smrg 864f220fa62Smrg 865f220fa62Smrg 866f220fa62Smrg assert(root1); 867f220fa62Smrg assert(root2); 868f220fa62Smrg assert(root1 == root2); 869f220fa62Smrg */ 870f220fa62Smrg sampledLine* generatedLine; 871f220fa62Smrg 872f220fa62Smrg 873f220fa62Smrg 874f220fa62Smrg v1->connectDiagonal(v1,v2, &ret_p1, &ret_p2, &generatedLine, ret_polygons); 875f220fa62Smrg newSampledLines = generatedLine->insert(newSampledLines); 876f220fa62Smrg 877f220fa62Smrg ret_polygons = ret_polygons->cutoffPolygon(root1); 878f220fa62Smrg 879f220fa62Smrg ret_polygons = ret_p1->insertPolygon(ret_polygons); 880f220fa62Smrg 881f220fa62Smrg ret_polygons = ret_p2->insertPolygon(ret_polygons); 882f220fa62Smrg 883f220fa62Smrg 884f220fa62Smrg 885f220fa62Smrg for(Int j=i+1; j<num_diagonals; j++) 886f220fa62Smrg { 887f220fa62Smrg if(removedDiagonals[j] ==0) 888f220fa62Smrg { 889f220fa62Smrg 890f220fa62Smrg directedLine* temp1=diagonal_vertices[2*j]; 891f220fa62Smrg directedLine* temp2=diagonal_vertices[2*j+1]; 892f220fa62Smrg if(temp1==v1 || temp1==v2 || temp2==v1 || temp2==v2) 893f220fa62Smrg if(! temp1->samePolygon(temp1, temp2)) 894f220fa62Smrg { 895f220fa62Smrg /*if temp1 and temp2 are in different polygons, 896f220fa62Smrg *then one of them must be v1 or v2. 897f220fa62Smrg */ 898f220fa62Smrg 899f220fa62Smrg 900f220fa62Smrg 901f220fa62Smrg assert(temp1==v1 || temp1 == v2 || temp2==v1 || temp2 ==v2); 902f220fa62Smrg if(temp1==v1) 903f220fa62Smrg { 904f220fa62Smrg diagonal_vertices[2*j] = v2->getPrev(); 905f220fa62Smrg } 906f220fa62Smrg if(temp2==v1) 907f220fa62Smrg { 908f220fa62Smrg diagonal_vertices[2*j+1] = v2->getPrev(); 909f220fa62Smrg } 910f220fa62Smrg if(temp1==v2) 911f220fa62Smrg { 912f220fa62Smrg diagonal_vertices[2*j] = v1->getPrev(); 913f220fa62Smrg } 914f220fa62Smrg if(temp2==v2) 915f220fa62Smrg { 916f220fa62Smrg diagonal_vertices[2*j+1] = v1->getPrev(); 917f220fa62Smrg } 918f220fa62Smrg } 919f220fa62Smrg } 920f220fa62Smrg } 921f220fa62Smrg 922f220fa62Smrg } 923f220fa62Smrg 924f220fa62Smrg 925f220fa62Smrg //clean up 926f220fa62Smrg loopList->deleteLoopList(); 927f220fa62Smrg free(array); 928f220fa62Smrg free(ranges); 929f220fa62Smrg free(diagonal_vertices); 930f220fa62Smrg free(removedDiagonals); 931f220fa62Smrg 932f220fa62Smrg *retSampledLines = newSampledLines; 933f220fa62Smrg return ret_polygons; 934f220fa62Smrg} 935f220fa62Smrg 936f220fa62Smrg 937