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