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