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 "zlassert.h" 42f220fa62Smrg#include "polyDBG.h" 43f220fa62Smrg 44f220fa62Smrg#ifdef __WATCOMC__ 45f220fa62Smrg#pragma warning 14 10 46f220fa62Smrg#pragma warning 391 10 47f220fa62Smrg#pragma warning 726 10 48f220fa62Smrg#endif 49f220fa62Smrg 50f220fa62Smrgstatic Real area(Real A[2], Real B[2], Real C[2]) 51f220fa62Smrg{ 52f220fa62Smrg Real Bx, By, Cx, Cy; 53f220fa62Smrg Bx = B[0] - A[0]; 54f220fa62Smrg By = B[1] - A[1]; 55f220fa62Smrg Cx = C[0] - A[0]; 56f220fa62Smrg Cy = C[1] - A[1]; 57f220fa62Smrg return Bx*Cy - Cx*By; 58f220fa62Smrg} 59f220fa62Smrg 60f220fa62SmrgInt DBG_isConvex(directedLine *poly) 61f220fa62Smrg{ 62f220fa62Smrg directedLine* temp; 63f220fa62Smrg if(area(poly->head(), poly->tail(), poly->getNext()->tail()) < 0.00000) 64f220fa62Smrg return 0; 65f220fa62Smrg for(temp = poly->getNext(); temp != poly; temp = temp->getNext()) 66f220fa62Smrg { 67f220fa62Smrg if(area(temp->head(), temp->tail(), temp->getNext()->tail()) < 0.00000) 68f220fa62Smrg return 0; 69f220fa62Smrg } 70f220fa62Smrg return 1; 71f220fa62Smrg} 72f220fa62Smrg 73f220fa62SmrgInt DBG_is_U_monotone(directedLine* poly) 74f220fa62Smrg{ 75f220fa62Smrg Int n_changes = 0; 76f220fa62Smrg Int prev_sign; 77f220fa62Smrg Int cur_sign; 78f220fa62Smrg directedLine* temp; 79f220fa62Smrg cur_sign = compV2InX(poly->tail(), poly->head()); 80f220fa62Smrg 81f220fa62Smrg n_changes = (compV2InX(poly->getPrev()->tail(), poly->getPrev()->head()) 82f220fa62Smrg != cur_sign); 83f220fa62Smrg 84f220fa62Smrg for(temp = poly->getNext(); temp != poly; temp = temp->getNext()) 85f220fa62Smrg { 86f220fa62Smrg prev_sign = cur_sign; 87f220fa62Smrg cur_sign = compV2InX(temp->tail(), temp->head()); 88f220fa62Smrg 89f220fa62Smrg if(cur_sign != prev_sign) 90f220fa62Smrg n_changes++; 91f220fa62Smrg } 92f220fa62Smrg 93f220fa62Smrg if(n_changes ==2) return 1; 94f220fa62Smrg else return 0; 95f220fa62Smrg} 96f220fa62Smrg 97f220fa62Smrg/*if u-monotone, and there is a long horizontal edge*/ 98f220fa62SmrgInt DBG_is_U_direction(directedLine* poly) 99f220fa62Smrg{ 100f220fa62Smrg/* 101f220fa62Smrg if(! DBG_is_U_monotone(poly)) 102f220fa62Smrg return 0; 103f220fa62Smrg*/ 104f220fa62Smrg Int V_count = 0; 105f220fa62Smrg Int U_count = 0; 106f220fa62Smrg directedLine* temp; 107f220fa62Smrg if( fabs(poly->head()[0] - poly->tail()[0]) <= fabs(poly->head()[1]-poly->tail()[1])) 108f220fa62Smrg V_count += poly->get_npoints(); 109f220fa62Smrg else 110f220fa62Smrg U_count += poly->get_npoints(); 111f220fa62Smrg /* 112f220fa62Smrg else if(poly->head()[1] == poly->tail()[1]) 113f220fa62Smrg U_count += poly->get_npoints(); 114f220fa62Smrg */ 115f220fa62Smrg for(temp = poly->getNext(); temp != poly; temp = temp->getNext()) 116f220fa62Smrg { 117f220fa62Smrg if( fabs(temp->head()[0] - temp->tail()[0]) <= fabs(temp->head()[1]-temp->tail()[1])) 118f220fa62Smrg V_count += temp->get_npoints(); 119f220fa62Smrg else 120f220fa62Smrg U_count += temp->get_npoints(); 121f220fa62Smrg /* 122f220fa62Smrg if(temp->head()[0] == temp->tail()[0]) 123f220fa62Smrg V_count += temp->get_npoints(); 124f220fa62Smrg else if(temp->head()[1] == temp->tail()[1]) 125f220fa62Smrg U_count += temp->get_npoints(); 126f220fa62Smrg */ 127f220fa62Smrg } 128f220fa62Smrg 129f220fa62Smrg if(U_count > V_count) return 1; 130f220fa62Smrg else return 0; 131f220fa62Smrg} 132f220fa62Smrg 133f220fa62Smrg/*given two line segments, determine whether 134f220fa62Smrg *they intersect each other or not. 135f220fa62Smrg *return 1 if they do, 136f220fa62Smrg *return 0 otherwise 137f220fa62Smrg */ 138f220fa62SmrgInt DBG_edgesIntersect(directedLine* l1, directedLine* l2) 139f220fa62Smrg{ 140f220fa62Smrg if(l1->getNext() == l2) 141f220fa62Smrg { 142f220fa62Smrg if(area(l1->head(), l1->tail(), l2->tail()) == 0) //colinear 143f220fa62Smrg { 144f220fa62Smrg if( (l1->tail()[0] - l1->head()[0])*(l2->tail()[0]-l2->head()[0]) + 145f220fa62Smrg (l1->tail()[1] - l1->head()[1])*(l2->tail()[1]-l2->head()[1]) >=0) 146f220fa62Smrg return 0; //not intersect 147f220fa62Smrg else 148f220fa62Smrg return 1; 149f220fa62Smrg } 150f220fa62Smrg //else we use the normal code 151f220fa62Smrg } 152f220fa62Smrg else if(l1->getPrev() == l2) 153f220fa62Smrg { 154f220fa62Smrg if(area(l2->head(), l2->tail(), l1->tail()) == 0) //colinear 155f220fa62Smrg { 156f220fa62Smrg if( (l2->tail()[0] - l2->head()[0])*(l1->tail()[0]-l1->head()[0]) + 157f220fa62Smrg (l2->tail()[1] - l2->head()[1])*(l1->tail()[1]-l1->head()[1]) >=0) 158f220fa62Smrg return 0; //not intersect 159f220fa62Smrg else 160f220fa62Smrg return 1; 161f220fa62Smrg } 162f220fa62Smrg //else we use the normal code 163f220fa62Smrg } 164f220fa62Smrg else //the two edges are not connected 165f220fa62Smrg { 166f220fa62Smrg if((l1->head()[0] == l2->head()[0] && 167f220fa62Smrg l1->head()[1] == l2->head()[1]) || 168f220fa62Smrg (l1->tail()[0] == l2->tail()[0] && 169f220fa62Smrg l1->tail()[1] == l2->tail()[1])) 170f220fa62Smrg return 1; 171f220fa62Smrg 172f220fa62Smrg } 173f220fa62Smrg 174f220fa62Smrg 175f220fa62Smrg if( 176f220fa62Smrg ( 177f220fa62Smrg area(l1->head(), l1->tail(), l2->head()) 178f220fa62Smrg * 179f220fa62Smrg area(l1->head(), l1->tail(), l2->tail()) 180f220fa62Smrg < 0 181f220fa62Smrg ) 182f220fa62Smrg && 183f220fa62Smrg ( 184f220fa62Smrg area(l2->head(), l2->tail(), l1->head()) 185f220fa62Smrg *area(l2->head(), l2->tail(), l1->tail()) 186f220fa62Smrg < 0 187f220fa62Smrg ) 188f220fa62Smrg ) 189f220fa62Smrg return 1; 190f220fa62Smrg else 191f220fa62Smrg return 0; 192f220fa62Smrg} 193f220fa62Smrg 194f220fa62Smrg/*whether AB and CD intersect 195f220fa62Smrg *return 1 if they do 196f220fa62Smrg *retur 0 otheriwse 197f220fa62Smrg */ 198f220fa62SmrgInt DBG_edgesIntersectGen(Real A[2], Real B[2], Real C[2], Real D[2]) 199f220fa62Smrg{ 200f220fa62Smrg if( 201f220fa62Smrg ( 202f220fa62Smrg area(A, B, C) * area(A,B,D) <0 203f220fa62Smrg ) 204f220fa62Smrg && 205f220fa62Smrg ( 206f220fa62Smrg area(C,D,A) * area(C,D,B) < 0 207f220fa62Smrg ) 208f220fa62Smrg ) 209f220fa62Smrg return 1; 210f220fa62Smrg else 211f220fa62Smrg return 0; 212f220fa62Smrg} 213f220fa62Smrg 214f220fa62Smrg/*determien whether (A,B) interesect chain[start] to [end] 215f220fa62Smrg */ 216f220fa62SmrgInt DBG_intersectChain(vertexArray* chain, Int start, Int end, Real A[2], Real B[2]) 217f220fa62Smrg{ 218f220fa62Smrg Int i; 219f220fa62Smrg for(i=start; i<=end-2; i++) 220f220fa62Smrg if(DBG_edgesIntersectGen(chain->getVertex(i), chain->getVertex(i+1), A, B)) 221f220fa62Smrg return 1; 222f220fa62Smrg 223f220fa62Smrg return 0; 224f220fa62Smrg} 225f220fa62Smrg 226f220fa62Smrg/*determine whether a polygon intersect itself or not 227f220fa62Smrg *return 1 is it does, 228f220fa62Smrg * 0 otherwise 229f220fa62Smrg */ 230f220fa62SmrgInt DBG_polygonSelfIntersect(directedLine* poly) 231f220fa62Smrg{ 232f220fa62Smrg directedLine* temp1; 233f220fa62Smrg directedLine* temp2; 234f220fa62Smrg temp1=poly; 235f220fa62Smrg for(temp2=temp1->getNext(); temp2 != temp1; temp2=temp2->getNext()) 236f220fa62Smrg { 237f220fa62Smrg if(DBG_edgesIntersect(temp1, temp2)) 238f220fa62Smrg { 239f220fa62Smrg return 1; 240f220fa62Smrg } 241f220fa62Smrg 242f220fa62Smrg } 243f220fa62Smrg 244f220fa62Smrg for(temp1=poly->getNext(); temp1 != poly; temp1 = temp1->getNext()) 245f220fa62Smrg for(temp2=temp1->getNext(); temp2 != temp1; temp2=temp2->getNext()) 246f220fa62Smrg { 247f220fa62Smrg if(DBG_edgesIntersect(temp1, temp2)) 248f220fa62Smrg { 249f220fa62Smrg return 1; 250f220fa62Smrg } 251f220fa62Smrg } 252f220fa62Smrg return 0; 253f220fa62Smrg} 254f220fa62Smrg 255f220fa62Smrg/*check whether a line segment intersects a polygon 256f220fa62Smrg */ 257f220fa62SmrgInt DBG_edgeIntersectPoly(directedLine* edge, directedLine* poly) 258f220fa62Smrg{ 259f220fa62Smrg directedLine* temp; 260f220fa62Smrg if(DBG_edgesIntersect(edge, poly)) 261f220fa62Smrg return 1; 262f220fa62Smrg for(temp=poly->getNext(); temp != poly; temp=temp->getNext()) 263f220fa62Smrg if(DBG_edgesIntersect(edge, temp)) 264f220fa62Smrg return 1; 265f220fa62Smrg return 0; 266f220fa62Smrg} 267f220fa62Smrg 268f220fa62Smrg/*check whether two polygons intersect 269f220fa62Smrg */ 270f220fa62SmrgInt DBG_polygonsIntersect(directedLine* p1, directedLine* p2) 271f220fa62Smrg{ 272f220fa62Smrg directedLine* temp; 273f220fa62Smrg if(DBG_edgeIntersectPoly(p1, p2)) 274f220fa62Smrg return 1; 275f220fa62Smrg for(temp=p1->getNext(); temp!= p1; temp = temp->getNext()) 276f220fa62Smrg if(DBG_edgeIntersectPoly(temp, p2)) 277f220fa62Smrg return 1; 278f220fa62Smrg return 0; 279f220fa62Smrg} 280f220fa62Smrg 281f220fa62Smrg/*check whether there are polygons intersecting each other in 282f220fa62Smrg *a list of polygons 283f220fa62Smrg */ 284f220fa62SmrgInt DBG_polygonListIntersect(directedLine* pList) 285f220fa62Smrg{ 286f220fa62Smrg directedLine *temp; 287f220fa62Smrg for(temp=pList; temp != NULL; temp = temp->getNextPolygon()) 288f220fa62Smrg if(DBG_polygonSelfIntersect(temp)) 289f220fa62Smrg return 1; 290f220fa62Smrg directedLine* temp2; 291f220fa62Smrg for(temp=pList; temp!=NULL; temp=temp->getNextPolygon()) 292f220fa62Smrg { 293f220fa62Smrg for(temp2=temp->getNextPolygon(); temp2 != NULL; temp2=temp2->getNextPolygon()) 294f220fa62Smrg if(DBG_polygonsIntersect(temp, temp2)) 295f220fa62Smrg return 1; 296f220fa62Smrg } 297f220fa62Smrg 298f220fa62Smrg return 0; 299f220fa62Smrg} 300f220fa62Smrg 301f220fa62Smrg 302f220fa62SmrgInt DBG_isCounterclockwise(directedLine* poly) 303f220fa62Smrg{ 304f220fa62Smrg return (poly->polyArea() > 0); 305f220fa62Smrg} 306f220fa62Smrg 307f220fa62Smrg/*ray: v0 with direction (dx,dy). 308f220fa62Smrg *edge: v1-v2. 309f220fa62Smrg * the extra point v10[2] is given for the information at 310f220fa62Smrg *v1. Basically this edge is connectd to edge 311f220fa62Smrg * v10-v1. If v1 is on the ray, 312f220fa62Smrg * then we need v10 to determine whether this ray intersects 313f220fa62Smrg * the edge or not (that is, return 1 or return 0). 314f220fa62Smrg * If v1 is on the ray, then if v2 and v10 are on the same side of the ray, 315f220fa62Smrg * we return 0, otherwise return 1. 316f220fa62Smrg *For v2, if v2 is on the ray, we always return 0. 317f220fa62Smrg *Notice that v1 and v2 are not symmetric. So the edge is directed!!! 318f220fa62Smrg * The purpose for this convention is such that: a point is inside a polygon 319f220fa62Smrg * if and only if it intersets with odd number of edges. 320f220fa62Smrg */ 321f220fa62SmrgInt DBG_rayIntersectEdge(Real v0[2], Real dx, Real dy, Real v10[2], Real v1[2], Real v2[2]) 322f220fa62Smrg{ 323f220fa62Smrg/* 324f220fa62Smrgif( (v1[1] >= v0[1] && v2[1]<= v0[1] ) 325f220fa62Smrg ||(v2[1] >= v0[1] && v1[1]<= v0[1] ) 326f220fa62Smrg ) 327f220fa62Smrg printf("rayIntersectEdge, *********\n"); 328f220fa62Smrg*/ 329f220fa62Smrg 330f220fa62Smrg Real denom = (v2[0]-v1[0])*(-dy) - (v2[1]-v1[1]) * (-dx); 331f220fa62Smrg Real nomRay = (v2[0]-v1[0]) * (v0[1] - v1[1]) - (v2[1]-v1[1])*(v0[0]-v1[0]); 332f220fa62Smrg Real nomEdge = (v0[0]-v1[0]) * (-dy) - (v0[1]-v1[1])*(-dx); 333f220fa62Smrg 334f220fa62Smrg 335f220fa62Smrg /*if the ray is parallel to the edge, return 0: not intersect*/ 336f220fa62Smrg if(denom == 0.0) 337f220fa62Smrg return 0; 338f220fa62Smrg 339f220fa62Smrg /*if v0 is on the edge, return 0: not intersect*/ 340f220fa62Smrg if(nomRay == 0.0) 341f220fa62Smrg return 0; 342f220fa62Smrg 343f220fa62Smrg /*if v1 is on the positive ray, and the neighbor of v1 crosses the ray 344f220fa62Smrg *return 1: intersect 345f220fa62Smrg */ 346f220fa62Smrg if(nomEdge == 0) 347f220fa62Smrg { /*v1 is on the positive or negative ray*/ 348f220fa62Smrg 349f220fa62Smrg/* 350f220fa62Smrg printf("v1 is on the ray\n"); 351f220fa62Smrg*/ 352f220fa62Smrg 353f220fa62Smrg if(dx*(v1[0]-v0[0])>=0 && dy*(v1[1]-v0[1])>=0) /*v1 on positive ray*/ 354f220fa62Smrg { 355f220fa62Smrg if(area(v0, v1, v10) * area(v0, v1, v2) >0) 356f220fa62Smrg return 0; 357f220fa62Smrg else 358f220fa62Smrg return 1; 359f220fa62Smrg } 360f220fa62Smrg else /*v1 on negative ray*/ 361f220fa62Smrg return 0; 362f220fa62Smrg } 363f220fa62Smrg 364f220fa62Smrg /*if v2 is on the ray, always return 0: not intersect*/ 365f220fa62Smrg if(nomEdge == denom) { 366f220fa62Smrg/* printf("v2 is on the ray\n");*/ 367f220fa62Smrg return 0; 368f220fa62Smrg } 369f220fa62Smrg 370f220fa62Smrg /*finally */ 371f220fa62Smrg if(denom*nomRay>0 && denom*nomEdge>0 && nomEdge/denom <=1.0) 372f220fa62Smrg return 1; 373f220fa62Smrg return 0; 374f220fa62Smrg} 375f220fa62Smrg 376f220fa62Smrg 377f220fa62Smrg/*return the number of intersections*/ 378f220fa62SmrgInt DBG_rayIntersectPoly(Real v0[2], Real dx, Real dy, directedLine* poly) 379f220fa62Smrg{ 380f220fa62Smrg directedLine* temp; 381f220fa62Smrg Int count=0; 382f220fa62Smrg if(DBG_rayIntersectEdge(v0, dx, dy, poly->getPrev()->head(), poly->head(), poly->tail())) 383f220fa62Smrg count++; 384f220fa62Smrg 385f220fa62Smrg for(temp=poly->getNext(); temp != poly; temp = temp->getNext()) 386f220fa62Smrg if(DBG_rayIntersectEdge(v0, dx, dy, temp->getPrev()->head(), temp->head(), temp->tail())) 387f220fa62Smrg count++; 388f220fa62Smrg/*printf("ray intersect poly: count=%i\n", count);*/ 389f220fa62Smrg return count; 390f220fa62Smrg} 391f220fa62Smrg 392f220fa62SmrgInt DBG_pointInsidePoly(Real v[2], directedLine* poly) 393f220fa62Smrg{ 394f220fa62Smrg/* 395f220fa62Smrgprintf("enter pointInsidePoly , v=(%f,%f)\n", v[0], v[1]); 396f220fa62Smrgprintf("the polygon is\n"); 397f220fa62Smrgpoly->printList(); 398f220fa62Smrg*/ 399f220fa62Smrg /*for debug purpose*/ 400f220fa62Smrg assert( (DBG_rayIntersectPoly(v,1,0,poly) % 2 ) 401f220fa62Smrg == (DBG_rayIntersectPoly(v,1,Real(0.1234), poly) % 2 ) 402f220fa62Smrg ); 403f220fa62Smrg if(DBG_rayIntersectPoly(v, 1, 0, poly) % 2 == 1) 404f220fa62Smrg return 1; 405f220fa62Smrg else 406f220fa62Smrg return 0; 407f220fa62Smrg} 408f220fa62Smrg 409f220fa62Smrg/*return the number of polygons which contain thie polygon 410f220fa62Smrg * as a subset 411f220fa62Smrg */ 412f220fa62SmrgInt DBG_enclosingPolygons(directedLine* poly, directedLine* list) 413f220fa62Smrg{ 414f220fa62Smrg directedLine* temp; 415f220fa62Smrg Int count=0; 416f220fa62Smrg/* 417f220fa62Smrgprintf("%i\n", DBG_pointInsidePoly(poly->head(), 418f220fa62Smrg list->getNextPolygon() 419f220fa62Smrg ->getNextPolygon() 420f220fa62Smrg ->getNextPolygon() 421f220fa62Smrg ->getNextPolygon() 422f220fa62Smrg)); 423f220fa62Smrg*/ 424f220fa62Smrg 425f220fa62Smrg for(temp = list; temp != NULL; temp = temp->getNextPolygon()) 426f220fa62Smrg { 427f220fa62Smrg if(poly != temp) 428f220fa62Smrg if(DBG_pointInsidePoly(poly->head(), temp)) 429f220fa62Smrg count++; 430f220fa62Smrg/* printf("count=%i\n", count);*/ 431f220fa62Smrg } 432f220fa62Smrg return count; 433f220fa62Smrg} 434f220fa62Smrg 435f220fa62Smrgvoid DBG_reverse(directedLine* poly) 436f220fa62Smrg{ 437f220fa62Smrg if(poly->getDirection() == INCREASING) 438f220fa62Smrg poly->putDirection(DECREASING); 439f220fa62Smrg else 440f220fa62Smrg poly->putDirection(INCREASING); 441f220fa62Smrg 442f220fa62Smrg directedLine* oldNext = poly->getNext(); 443f220fa62Smrg poly->putNext(poly->getPrev()); 444f220fa62Smrg poly->putPrev(oldNext); 445f220fa62Smrg 446f220fa62Smrg directedLine* temp; 447f220fa62Smrg for(temp=oldNext; temp!=poly; temp = oldNext) 448f220fa62Smrg { 449f220fa62Smrg if(temp->getDirection() == INCREASING) 450f220fa62Smrg temp->putDirection(DECREASING); 451f220fa62Smrg else 452f220fa62Smrg temp->putDirection(INCREASING); 453f220fa62Smrg 454f220fa62Smrg oldNext = temp->getNext(); 455f220fa62Smrg temp->putNext(temp->getPrev()); 456f220fa62Smrg temp->putPrev(oldNext); 457f220fa62Smrg } 458f220fa62Smrg printf("reverse done\n"); 459f220fa62Smrg} 460f220fa62Smrg 461f220fa62SmrgInt DBG_checkConnectivity(directedLine *polygon) 462f220fa62Smrg{ 463f220fa62Smrg if(polygon == NULL) return 1; 464f220fa62Smrg directedLine* temp; 465f220fa62Smrg if(polygon->head()[0] != polygon->getPrev()->tail()[0] || 466f220fa62Smrg polygon->head()[1] != polygon->getPrev()->tail()[1]) 467f220fa62Smrg return 0; 468f220fa62Smrg for(temp=polygon->getNext(); temp != polygon; temp=temp->getNext()) 469f220fa62Smrg { 470f220fa62Smrg if(temp->head()[0] != temp->getPrev()->tail()[0] || 471f220fa62Smrg temp->head()[1] != temp->getPrev()->tail()[1]) 472f220fa62Smrg return 0; 473f220fa62Smrg } 474f220fa62Smrg return 1; 475f220fa62Smrg} 476f220fa62Smrg 477f220fa62Smrg/*print out error message. 478f220fa62Smrg *If it cannot modify the polygon list to make it satify the 479f220fa62Smrg *requirements, return 1. 480f220fa62Smrg *otherwise modify the polygon list, and return 0 481f220fa62Smrg */ 482f220fa62SmrgInt DBG_check(directedLine *polyList) 483f220fa62Smrg{ 484f220fa62Smrg directedLine* temp; 485f220fa62Smrg if(polyList == NULL) return 0; 486f220fa62Smrg 487f220fa62Smrg /*if there are intersections, print out error message 488f220fa62Smrg */ 489f220fa62Smrg if(DBG_polygonListIntersect(polyList)) 490f220fa62Smrg { 491f220fa62Smrg fprintf(stderr, "DBG_check: there are self intersections, don't know to modify the polygons\n"); 492f220fa62Smrg return 1; 493f220fa62Smrg } 494f220fa62Smrg 495f220fa62Smrg /*check the connectivity of each polygon*/ 496f220fa62Smrg for(temp = polyList; temp!= NULL; temp = temp ->getNextPolygon()) 497f220fa62Smrg { 498f220fa62Smrg if(! DBG_checkConnectivity(temp)) 499f220fa62Smrg { 500f220fa62Smrg fprintf(stderr, "DBG_check, polygon not connected\n"); 501f220fa62Smrg return 1; 502f220fa62Smrg } 503f220fa62Smrg } 504f220fa62Smrg 505f220fa62Smrg /*check the orientation of each polygon*/ 506f220fa62Smrg for(temp = polyList; temp!= NULL; temp = temp ->getNextPolygon()) 507f220fa62Smrg { 508f220fa62Smrg 509f220fa62Smrg 510f220fa62Smrg Int correctDir; 511f220fa62Smrg 512f220fa62Smrg if( DBG_enclosingPolygons(temp, polyList) % 2 == 0) 513f220fa62Smrg correctDir = 1; /*counterclockwise*/ 514f220fa62Smrg else 515f220fa62Smrg correctDir = 0; /*clockwise*/ 516f220fa62Smrg 517f220fa62Smrg Int actualDir = DBG_isCounterclockwise(temp); 518f220fa62Smrg 519f220fa62Smrg if(correctDir != actualDir) 520f220fa62Smrg { 521f220fa62Smrg fprintf(stderr, "DBG_check: polygon with incorrect orientations. reversed\n"); 522f220fa62Smrg 523f220fa62Smrg DBG_reverse(temp); 524f220fa62Smrg } 525f220fa62Smrg 526f220fa62Smrg } 527f220fa62Smrg return 0; 528f220fa62Smrg} 529f220fa62Smrg 530f220fa62Smrg/**************handle self intersections*****************/ 531f220fa62Smrg//determine whether e interects [begin, end] or not 532f220fa62Smrgstatic directedLine* DBG_edgeIntersectChainD(directedLine *e, 533f220fa62Smrg directedLine *begin, directedLine *end) 534f220fa62Smrg{ 535f220fa62Smrg directedLine *temp; 536f220fa62Smrg for(temp=begin; temp != end; temp = temp->getNext()) 537f220fa62Smrg { 538f220fa62Smrg if(DBG_edgesIntersect(e, temp)) 539f220fa62Smrg return temp; 540f220fa62Smrg } 541f220fa62Smrg if(DBG_edgesIntersect(e, end)) 542f220fa62Smrg return end; 543f220fa62Smrg return NULL; 544f220fa62Smrg} 545f220fa62Smrg 546f220fa62Smrg//given a polygon, cut the edges off and finally obtain a 547f220fa62Smrg//a polygon without intersections. The cut-off edges are 548f220fa62Smrg//dealloated. The new polygon is returned. 549f220fa62SmrgdirectedLine* DBG_cutIntersectionPoly(directedLine *polygon, int& cutOccur) 550f220fa62Smrg{ 551f220fa62Smrg directedLine *begin, *end, *next; 552f220fa62Smrg begin = polygon; 553f220fa62Smrg end = polygon; 554f220fa62Smrg cutOccur = 0; 555f220fa62Smrg while( (next = end->getNext()) != begin) 556f220fa62Smrg { 557f220fa62Smrg directedLine *interc = NULL; 558f220fa62Smrg if( (interc = DBG_edgeIntersectChainD(next, begin, end))) 559f220fa62Smrg { 560f220fa62Smrg int fixed = 0; 561f220fa62Smrg if(DBG_edgesIntersect(next, interc->getNext())) 562f220fa62Smrg { 563f220fa62Smrg //trying to fix it 564f220fa62Smrg Real buf[2]; 565f220fa62Smrg int i; 566f220fa62Smrg Int n=5; 567f220fa62Smrg buf[0] = interc->tail()[0]; 568f220fa62Smrg buf[1] = interc->tail()[1]; 569f220fa62Smrg 570f220fa62Smrg for(i=1; i<n; i++) 571f220fa62Smrg { 572f220fa62Smrg Real r = ((Real)i) / ((Real) n); 573f220fa62Smrg Real u = (1-r) * interc->head()[0] + r * interc->tail()[0]; 574f220fa62Smrg Real v = (1-r) * interc->head()[1] + r * interc->tail()[1]; 575f220fa62Smrg interc->tail()[0] = interc->getNext()->head()[0] = u; 576f220fa62Smrg interc->tail()[1] = interc->getNext()->head()[1] = v; 577f220fa62Smrg if( (! DBG_edgesIntersect(next, interc)) && 578f220fa62Smrg (! DBG_edgesIntersect(next, interc->getNext()))) 579f220fa62Smrg break; //we fixed it 580f220fa62Smrg } 581f220fa62Smrg if(i==n) // we didn't fix it 582f220fa62Smrg { 583f220fa62Smrg fixed = 0; 584f220fa62Smrg //back to original 585f220fa62Smrg interc->tail()[0] = interc->getNext()->head()[0] = buf[0]; 586f220fa62Smrg interc->tail()[1] = interc->getNext()->head()[1] = buf[1]; 587f220fa62Smrg } 588f220fa62Smrg else 589f220fa62Smrg { 590f220fa62Smrg fixed = 1; 591f220fa62Smrg } 592f220fa62Smrg } 593f220fa62Smrg if(fixed == 0) 594f220fa62Smrg { 595f220fa62Smrg cutOccur = 1; 596f220fa62Smrg begin->deleteSingleLine(next); 597f220fa62Smrg 598f220fa62Smrg if(begin != end) 599f220fa62Smrg { 600f220fa62Smrg if(DBG_polygonSelfIntersect(begin)) 601f220fa62Smrg { 602f220fa62Smrg directedLine* newEnd = end->getPrev(); 603f220fa62Smrg begin->deleteSingleLine(end); 604f220fa62Smrg end = newEnd; 605f220fa62Smrg } 606f220fa62Smrg } 607f220fa62Smrg } 608f220fa62Smrg else 609f220fa62Smrg { 610f220fa62Smrg end = end->getNext(); 611f220fa62Smrg } 612f220fa62Smrg } 613f220fa62Smrg else 614f220fa62Smrg { 615f220fa62Smrg end = end->getNext(); 616f220fa62Smrg } 617f220fa62Smrg } 618f220fa62Smrg return begin; 619f220fa62Smrg} 620f220fa62Smrg 621f220fa62Smrg//given a polygon, cut the edges off and finally obtain a 622f220fa62Smrg//a polygon without intersections. The cut-off edges are 623f220fa62Smrg//dealloated. The new polygon is returned. 624f220fa62Smrg#if 0 // UNUSED 625f220fa62Smrgstatic directedLine* DBG_cutIntersectionPoly_notwork(directedLine *polygon) 626f220fa62Smrg{ 627f220fa62Smrg directedLine *crt;//current polygon 628f220fa62Smrg directedLine *begin; 629f220fa62Smrg directedLine *end; 630f220fa62Smrg directedLine *temp; 631f220fa62Smrg crt = polygon; 632f220fa62Smrg int find=0; 633f220fa62Smrg while(1) 634f220fa62Smrg { 635f220fa62Smrg//printf("loop\n"); 636f220fa62Smrg //if there are less than 3 edges, we should stop 637f220fa62Smrg if(crt->getPrev()->getPrev() == crt) 638f220fa62Smrg return NULL; 639f220fa62Smrg 640f220fa62Smrg if(DBG_edgesIntersect(crt, crt->getNext()) || 641f220fa62Smrg (crt->head()[0] == crt->getNext()->tail()[0] && 642f220fa62Smrg crt->head()[1] == crt->getNext()->tail()[1]) 643f220fa62Smrg ) 644f220fa62Smrg { 645f220fa62Smrg find = 1; 646f220fa62Smrg crt=crt->deleteChain(crt, crt->getNext()); 647f220fa62Smrg } 648f220fa62Smrg else 649f220fa62Smrg { 650f220fa62Smrg //now we know crt and crt->getNext do not intersect 651f220fa62Smrg begin = crt; 652f220fa62Smrg end = crt->getNext(); 653f220fa62Smrg//printf("begin=(%f,%f)\n", begin->head()[0], begin->head()[1]); 654f220fa62Smrg//printf("end=(%f,%f)\n", end->head()[0], end->head()[1]); 655f220fa62Smrg for(temp=end->getNext(); temp!=begin; temp= temp->getNext()) 656f220fa62Smrg { 657f220fa62Smrg//printf("temp=(%f,%f)\n", temp->head()[0], temp->head()[1]); 658f220fa62Smrg directedLine *intersect = DBG_edgeIntersectChainD(temp, begin, end); 659f220fa62Smrg if(intersect != NULL) 660f220fa62Smrg { 661f220fa62Smrg crt = crt->deleteChain(intersect, temp); 662f220fa62Smrg find=1; 663f220fa62Smrg break; //the for loop 664f220fa62Smrg } 665f220fa62Smrg else 666f220fa62Smrg { 667f220fa62Smrg end = temp; 668f220fa62Smrg } 669f220fa62Smrg } 670f220fa62Smrg } 671f220fa62Smrg if(find == 0) 672f220fa62Smrg return crt; 673f220fa62Smrg else 674f220fa62Smrg find = 0; //go to next loop 675f220fa62Smrg} 676f220fa62Smrg} 677f220fa62Smrg#endif 678f220fa62Smrg 679f220fa62SmrgdirectedLine* DBG_cutIntersectionAllPoly(directedLine* list) 680f220fa62Smrg{ 681f220fa62Smrg directedLine* temp; 682f220fa62Smrg directedLine* tempNext=NULL; 683f220fa62Smrg directedLine* ret = NULL; 684f220fa62Smrg int cutOccur=0; 685f220fa62Smrg for(temp=list; temp != NULL; temp = tempNext) 686f220fa62Smrg { 687f220fa62Smrg directedLine *left; 688f220fa62Smrg tempNext = temp->getNextPolygon(); 689f220fa62Smrg 690f220fa62Smrg left = DBG_cutIntersectionPoly(temp, cutOccur); 691f220fa62Smrg if(left != NULL) 692f220fa62Smrg ret=left->insertPolygon(ret); 693f220fa62Smrg } 694f220fa62Smrg return ret; 695f220fa62Smrg} 696f220fa62Smrg 697f220fa62SmrgsampledLine* DBG_collectSampledLinesAllPoly(directedLine *polygonList) 698f220fa62Smrg{ 699f220fa62Smrg directedLine *temp; 700f220fa62Smrg sampledLine* tempHead = NULL; 701f220fa62Smrg sampledLine* tempTail = NULL; 702f220fa62Smrg sampledLine* cHead = NULL; 703f220fa62Smrg sampledLine* cTail = NULL; 704f220fa62Smrg 705f220fa62Smrg if(polygonList == NULL) 706f220fa62Smrg return NULL; 707f220fa62Smrg 708f220fa62Smrg DBG_collectSampledLinesPoly(polygonList, cHead, cTail); 709f220fa62Smrg 710f220fa62Smrg assert(cHead); 711f220fa62Smrg assert(cTail); 712f220fa62Smrg for(temp = polygonList->getNextPolygon(); temp != NULL; temp = temp->getNextPolygon()) 713f220fa62Smrg { 714f220fa62Smrg DBG_collectSampledLinesPoly(temp, tempHead, tempTail); 715f220fa62Smrg cTail->insert(tempHead); 716f220fa62Smrg cTail = tempTail; 717f220fa62Smrg } 718f220fa62Smrg return cHead; 719f220fa62Smrg} 720f220fa62Smrg 721f220fa62Smrgvoid DBG_collectSampledLinesPoly(directedLine *polygon, sampledLine*& retHead, sampledLine*& retTail) 722f220fa62Smrg{ 723f220fa62Smrg directedLine *temp; 724f220fa62Smrg retHead = NULL; 725f220fa62Smrg retTail = NULL; 726f220fa62Smrg if(polygon == NULL) 727f220fa62Smrg return; 728f220fa62Smrg 729f220fa62Smrg retHead = retTail = polygon->getSampledLine(); 730f220fa62Smrg for(temp = polygon->getNext(); temp != polygon; temp=temp->getNext()) 731f220fa62Smrg { 732f220fa62Smrg retHead = temp->getSampledLine()->insert(retHead); 733f220fa62Smrg } 734f220fa62Smrg} 735