Advertisement
Guest User

Untitled

a guest
Nov 19th, 2012
30
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 79.37 KB | None | 0 0
  1. /*
  2. ===========================================================================
  3.  
  4. Project:   Generic Polygon Clipper
  5.  
  6.            A new algorithm for calculating the difference, intersection,
  7.            exclusive-or or union of arbitrary polygon sets.
  8.  
  9. File:      gpc.c
  10. Author:    Alan Murta (email: gpc@cs.man.ac.uk)
  11. Version:   2.32
  12. Date:      17th December 2004
  13.  
  14. Copyright: (C) Advanced Interfaces Group,
  15.            University of Manchester.
  16.  
  17.            This software is free for non-commercial use. It may be copied,
  18.            modified, and redistributed provided that this copyright notice
  19.            is preserved on all copies. The intellectual property rights of
  20.            the algorithms used reside with the University of Manchester
  21.            Advanced Interfaces Group.
  22.  
  23.            You may not use this software, in whole or in part, in support
  24.            of any commercial product without the express consent of the
  25.            author.
  26.  
  27.            There is no warranty or other guarantee of fitness of this
  28.            software for any purpose. It is provided solely "as is".
  29.  
  30. ===========================================================================
  31. */
  32.  
  33.  
  34. /*
  35. ===========================================================================
  36.                                 Includes
  37. ===========================================================================
  38. */
  39.  
  40. #include "gpc.h"
  41. #include <stdlib.h>
  42. #include <float.h>
  43. #include <math.h>
  44.  
  45.  
  46. /*
  47. ===========================================================================
  48.                                 Constants
  49. ===========================================================================
  50. */
  51.  
  52. #ifndef TRUE
  53. #define FALSE              0
  54. #define TRUE               1
  55. #endif
  56.  
  57. #define LEFT               0
  58. #define RIGHT              1
  59.  
  60. #define ABOVE              0
  61. #define BELOW              1
  62.  
  63. #define CLIP               0
  64. #define SUBJ               1
  65.  
  66. #define INVERT_TRISTRIPS   FALSE
  67.  
  68.  
  69. /*
  70. ===========================================================================
  71.                                  Macros
  72. ===========================================================================
  73. */
  74.  
  75. #define EQ(a, b)           (fabs((a) - (b)) <= GPC_EPSILON)
  76.  
  77. #define PREV_INDEX(i, n)   ((i - 1 + n) % n)
  78. #define NEXT_INDEX(i, n)   ((i + 1    ) % n)
  79.  
  80. #define OPTIMAL(v, i, n)   ((v[PREV_INDEX(i, n)].y != v[i].y) || \
  81.                             (v[NEXT_INDEX(i, n)].y != v[i].y))
  82.  
  83. #define FWD_MIN(v, i, n)   ((v[PREV_INDEX(i, n)].vertex.y >= v[i].vertex.y) \
  84.                          && (v[NEXT_INDEX(i, n)].vertex.y > v[i].vertex.y))
  85.  
  86. #define NOT_FMAX(v, i, n)   (v[NEXT_INDEX(i, n)].vertex.y > v[i].vertex.y)
  87.  
  88. #define REV_MIN(v, i, n)   ((v[PREV_INDEX(i, n)].vertex.y > v[i].vertex.y) \
  89.                          && (v[NEXT_INDEX(i, n)].vertex.y >= v[i].vertex.y))
  90.  
  91. #define NOT_RMAX(v, i, n)   (v[PREV_INDEX(i, n)].vertex.y > v[i].vertex.y)
  92.  
  93. #define VERTEX(e,p,s,x,y)  {add_vertex(&((e)->outp[(p)]->v[(s)]), x, y); \
  94.                             (e)->outp[(p)]->active++;}
  95.  
  96. #define P_EDGE(d,e,p,i,j)  {(d)= (e); \
  97.                             do {(d)= (d)->prev;} while (!(d)->outp[(p)]); \
  98.                             (i)= (d)->bot.x + (d)->dx * ((j)-(d)->bot.y);}
  99.  
  100. #define N_EDGE(d,e,p,i,j)  {(d)= (e); \
  101.                             do {(d)= (d)->next;} while (!(d)->outp[(p)]); \
  102.                             (i)= (d)->bot.x + (d)->dx * ((j)-(d)->bot.y);}
  103.  
  104. #define MALLOC(p, b, s, t) {if ((b) > 0) { \
  105.                             p= (t*)malloc(b); if (!(p)) { \
  106.                             fprintf(stderr, "gpc malloc failure: %s\n", s); \
  107.                             exit(0);}} else p= NULL;}
  108.  
  109. #define FREE(p)            {if (p) {free(p); (p)= NULL;}}
  110.  
  111. /*
  112. ===========================================================================
  113.                             Private Data Types
  114. ===========================================================================
  115. */
  116.  
  117. typedef enum                        /* Edge intersection classes         */
  118. {
  119.   NUL,                              /* Empty non-intersection            */
  120.   EMX,                              /* External maximum                  */
  121.   ELI,                              /* External left intermediate        */
  122.   TED,                              /* Top edge                          */
  123.   ERI,                              /* External right intermediate       */
  124.   RED,                              /* Right edge                        */
  125.   IMM,                              /* Internal maximum and minimum      */
  126.   IMN,                              /* Internal minimum                  */
  127.   EMN,                              /* External minimum                  */
  128.   EMM,                              /* External maximum and minimum      */
  129.   LED,                              /* Left edge                         */
  130.   ILI,                              /* Internal left intermediate        */
  131.   BED,                              /* Bottom edge                       */
  132.   IRI,                              /* Internal right intermediate       */
  133.   IMX,                              /* Internal maximum                  */
  134.   FUL                               /* Full non-intersection             */
  135. } vertex_type;
  136.  
  137. typedef enum                        /* Horizontal edge states            */
  138. {
  139.   NH,                               /* No horizontal edge                */
  140.   BH,                               /* Bottom horizontal edge            */
  141.   TH                                /* Top horizontal edge               */
  142. } h_state;
  143.  
  144. typedef enum                        /* Edge bundle state                 */
  145. {
  146.   UNBUNDLED,                        /* Isolated edge not within a bundle */
  147.   BUNDLE_HEAD,                      /* Bundle head node                  */
  148.   BUNDLE_TAIL                       /* Passive bundle tail node          */
  149. } bundle_state;
  150.  
  151. typedef struct v_shape              /* Internal vertex list datatype     */
  152. {
  153.   double              x;            /* X coordinate component            */
  154.   double              y;            /* Y coordinate component            */
  155.   struct v_shape     *next;         /* Pointer to next vertex in list    */
  156. } vertex_node;
  157.  
  158. typedef struct p_shape              /* Internal contour / tristrip type  */
  159. {
  160.   int                 active;       /* Active flag / vertex count        */
  161.   int                 hole;         /* Hole / external contour flag      */
  162.   vertex_node        *v[2];         /* Left and right vertex list ptrs   */
  163.   struct p_shape     *next;         /* Pointer to next polygon contour   */
  164.   struct p_shape     *proxy;        /* Pointer to actual structure used  */
  165. } polygon_node;
  166.  
  167. typedef struct edge_shape
  168. {
  169.   gpc_vertex          vertex;       /* Piggy-backed contour vertex data  */
  170.   gpc_vertex          bot;          /* Edge lower (x, y) coordinate      */
  171.   gpc_vertex          top;          /* Edge upper (x, y) coordinate      */
  172.   double              xb;           /* Scanbeam bottom x coordinate      */
  173.   double              xt;           /* Scanbeam top x coordinate         */
  174.   double              dx;           /* Change in x for a unit y increase */
  175.   int                 type;         /* Clip / subject edge flag          */
  176.   int                 bundle[2][2]; /* Bundle edge flags                 */
  177.   int                 bside[2];     /* Bundle left / right indicators    */
  178.   bundle_state        bstate[2];    /* Edge bundle state                 */
  179.   polygon_node       *outp[2];      /* Output polygon / tristrip pointer */
  180.   struct edge_shape  *prev;         /* Previous edge in the AET          */
  181.   struct edge_shape  *next;         /* Next edge in the AET              */
  182.   struct edge_shape  *pred;         /* Edge connected at the lower end   */
  183.   struct edge_shape  *succ;         /* Edge connected at the upper end   */
  184.   struct edge_shape  *next_bound;   /* Pointer to next bound in LMT      */
  185. } edge_node;
  186.  
  187. typedef struct lmt_shape            /* Local minima table                */
  188. {
  189.   double              y;            /* Y coordinate at local minimum     */
  190.   edge_node          *first_bound;  /* Pointer to bound list             */
  191.   struct lmt_shape   *next;         /* Pointer to next local minimum     */
  192. } lmt_node;
  193.  
  194. typedef struct sbt_t_shape          /* Scanbeam tree                     */
  195. {
  196.   double              y;            /* Scanbeam node y value             */
  197.   struct sbt_t_shape *less;         /* Pointer to nodes with lower y     */
  198.   struct sbt_t_shape *more;         /* Pointer to nodes with higher y    */
  199. } sb_tree;
  200.  
  201. typedef struct it_shape             /* Intersection table                */
  202. {
  203.   edge_node          *ie[2];        /* Intersecting edge (bundle) pair   */
  204.   gpc_vertex          point;        /* Point of intersection             */
  205.   struct it_shape    *next;         /* The next intersection table node  */
  206. } it_node;
  207.  
  208. typedef struct st_shape             /* Sorted edge table                 */
  209. {
  210.   edge_node          *edge;         /* Pointer to AET edge               */
  211.   double              xb;           /* Scanbeam bottom x coordinate      */
  212.   double              xt;           /* Scanbeam top x coordinate         */
  213.   double              dx;           /* Change in x for a unit y increase */
  214.   struct st_shape    *prev;         /* Previous edge in sorted list      */
  215. } st_node;
  216.  
  217. typedef struct bbox_shape           /* Contour axis-aligned bounding box */
  218. {
  219.   double             xmin;          /* Minimum x coordinate              */
  220.   double             ymin;          /* Minimum y coordinate              */
  221.   double             xmax;          /* Maximum x coordinate              */
  222.   double             ymax;          /* Maximum y coordinate              */
  223. } bbox;
  224.  
  225.  
  226. /*
  227. ===========================================================================
  228.                                Global Data
  229. ===========================================================================
  230. */
  231.  
  232. /* Horizontal edge state transitions within scanbeam boundary */
  233. const h_state next_h_state[3][6]=
  234. {
  235.   /*        ABOVE     BELOW     CROSS */
  236.   /*        L   R     L   R     L   R */  
  237.   /* NH */ {BH, TH,   TH, BH,   NH, NH},
  238.   /* BH */ {NH, NH,   NH, NH,   TH, TH},
  239.   /* TH */ {NH, NH,   NH, NH,   BH, BH}
  240. };
  241.  
  242.  
  243. /*
  244. ===========================================================================
  245.                              Private Functions
  246. ===========================================================================
  247. */
  248.  
  249. static void reset_it(it_node **it)
  250. {
  251.   it_node *itn;
  252.  
  253.   while (*it)
  254.   {
  255.     itn= (*it)->next;
  256.     FREE(*it);
  257.     *it= itn;
  258.   }
  259. }
  260.  
  261.  
  262. static void reset_lmt(lmt_node **lmt)
  263. {
  264.   lmt_node *lmtn;
  265.  
  266.   while (*lmt)
  267.   {
  268.     lmtn= (*lmt)->next;
  269.     FREE(*lmt);
  270.     *lmt= lmtn;
  271.   }
  272. }
  273.  
  274.  
  275. static void insert_bound(edge_node **b, edge_node *e)
  276. {
  277.   edge_node *existing_bound;
  278.  
  279.   if (!*b)
  280.   {
  281.     /* Link node e to the tail of the list */
  282.     *b= e;
  283.   }
  284.   else
  285.   {
  286.     /* Do primary sort on the x field */
  287.     if (e[0].bot.x < (*b)[0].bot.x)
  288.     {
  289.       /* Insert a new node mid-list */
  290.       existing_bound= *b;
  291.       *b= e;
  292.       (*b)->next_bound= existing_bound;
  293.     }
  294.     else
  295.     {
  296.       if (e[0].bot.x == (*b)[0].bot.x)
  297.       {
  298.         /* Do secondary sort on the dx field */
  299.         if (e[0].dx < (*b)[0].dx)
  300.         {
  301.           /* Insert a new node mid-list */
  302.           existing_bound= *b;
  303.           *b= e;
  304.           (*b)->next_bound= existing_bound;
  305.         }
  306.         else
  307.         {
  308.           /* Head further down the list */
  309.           insert_bound(&((*b)->next_bound), e);
  310.         }
  311.       }
  312.       else
  313.       {
  314.         /* Head further down the list */
  315.         insert_bound(&((*b)->next_bound), e);
  316.       }
  317.     }
  318.   }
  319. }
  320.  
  321.  
  322. static edge_node **bound_list(lmt_node **lmt, double y)
  323. {
  324.   lmt_node *existing_node;
  325.  
  326.   if (!*lmt)
  327.   {
  328.     /* Add node onto the tail end of the LMT */
  329.     MALLOC(*lmt, sizeof(lmt_node), "LMT insertion", lmt_node);
  330.     (*lmt)->y= y;
  331.     (*lmt)->first_bound= NULL;
  332.     (*lmt)->next= NULL;
  333.     return &((*lmt)->first_bound);
  334.   }
  335.   else
  336.     if (y < (*lmt)->y)
  337.     {
  338.       /* Insert a new LMT node before the current node */
  339.       existing_node= *lmt;
  340.       MALLOC(*lmt, sizeof(lmt_node), "LMT insertion", lmt_node);
  341.       (*lmt)->y= y;
  342.       (*lmt)->first_bound= NULL;
  343.       (*lmt)->next= existing_node;
  344.       return &((*lmt)->first_bound);
  345.     }
  346.     else
  347.       if (y > (*lmt)->y)
  348.         /* Head further up the LMT */
  349.         return bound_list(&((*lmt)->next), y);
  350.       else
  351.         /* Use this existing LMT node */
  352.         return &((*lmt)->first_bound);
  353. }
  354.  
  355.  
  356. static void add_to_sbtree(int *entries, sb_tree **sbtree, double y)
  357. {
  358.   if (!*sbtree)
  359.   {
  360.     /* Add a new tree node here */
  361.     MALLOC(*sbtree, sizeof(sb_tree), "scanbeam tree insertion", sb_tree);
  362.     (*sbtree)->y= y;
  363.     (*sbtree)->less= NULL;
  364.     (*sbtree)->more= NULL;
  365.     (*entries)++;
  366.   }
  367.   else
  368.   {
  369.     if ((*sbtree)->y > y)
  370.     {
  371.     /* Head into the 'less' sub-tree */
  372.       add_to_sbtree(entries, &((*sbtree)->less), y);
  373.     }
  374.     else
  375.     {
  376.       if ((*sbtree)->y < y)
  377.       {
  378.         /* Head into the 'more' sub-tree */
  379.         add_to_sbtree(entries, &((*sbtree)->more), y);
  380.       }
  381.     }
  382.   }
  383. }
  384.  
  385.  
  386. static void build_sbt(int *entries, double *sbt, sb_tree *sbtree)
  387. {
  388.   if (sbtree->less)
  389.     build_sbt(entries, sbt, sbtree->less);
  390.   sbt[*entries]= sbtree->y;
  391.   (*entries)++;
  392.   if (sbtree->more)
  393.     build_sbt(entries, sbt, sbtree->more);
  394. }
  395.  
  396.  
  397. static void free_sbtree(sb_tree **sbtree)
  398. {
  399.   if (*sbtree)
  400.   {
  401.     free_sbtree(&((*sbtree)->less));
  402.     free_sbtree(&((*sbtree)->more));
  403.     FREE(*sbtree);
  404.   }
  405. }
  406.  
  407.  
  408. static int count_optimal_vertices(gpc_vertex_list c)
  409. {
  410.   int result= 0, i;
  411.  
  412.   /* Ignore non-contributing contours */
  413.   if (c.num_vertices > 0)
  414.   {
  415.     for (i= 0; i < c.num_vertices; i++)
  416.       /* Ignore superfluous vertices embedded in horizontal edges */
  417.       if (OPTIMAL(c.vertex, i, c.num_vertices))
  418.         result++;
  419.   }
  420.   return result;
  421. }
  422.  
  423.  
  424. static edge_node *build_lmt(lmt_node **lmt, sb_tree **sbtree,
  425.                             int *sbt_entries, gpc_polygon *p, int type,
  426.                             gpc_op op)
  427. {
  428.   int          c, i, min, max, num_edges, v, num_vertices;
  429.   int          total_vertices= 0, e_index=0;
  430.   edge_node   *e, *edge_table;
  431.  
  432.   for (c= 0; c < p->num_contours; c++)
  433.     total_vertices+= count_optimal_vertices(p->contour[c]);
  434.  
  435.   /* Create the entire input polygon edge table in one go */
  436.   MALLOC(edge_table, total_vertices * sizeof(edge_node),
  437.          "edge table creation", edge_node);
  438.  
  439.   for (c= 0; c < p->num_contours; c++)
  440.   {
  441.     if (p->contour[c].num_vertices < 0)
  442.     {
  443.       /* Ignore the non-contributing contour and repair the vertex count */
  444.       p->contour[c].num_vertices= -p->contour[c].num_vertices;
  445.     }
  446.     else
  447.     {
  448.       /* Perform contour optimisation */
  449.       num_vertices= 0;
  450.       for (i= 0; i < p->contour[c].num_vertices; i++)
  451.         if (OPTIMAL(p->contour[c].vertex, i, p->contour[c].num_vertices))
  452.         {
  453.           edge_table[num_vertices].vertex.x= p->contour[c].vertex[i].x;
  454.           edge_table[num_vertices].vertex.y= p->contour[c].vertex[i].y;
  455.  
  456.           /* Record vertex in the scanbeam table */
  457.           add_to_sbtree(sbt_entries, sbtree,
  458.                         edge_table[num_vertices].vertex.y);
  459.  
  460.           num_vertices++;
  461.         }
  462.  
  463.       /* Do the contour forward pass */
  464.       for (min= 0; min < num_vertices; min++)
  465.       {
  466.         /* If a forward local minimum... */
  467.         if (FWD_MIN(edge_table, min, num_vertices))
  468.         {
  469.           /* Search for the next local maximum... */
  470.           num_edges= 1;
  471.           max= NEXT_INDEX(min, num_vertices);
  472.           while (NOT_FMAX(edge_table, max, num_vertices))
  473.           {
  474.             num_edges++;
  475.             max= NEXT_INDEX(max, num_vertices);
  476.           }
  477.  
  478.           /* Build the next edge list */
  479.           e= &edge_table[e_index];
  480.           e_index+= num_edges;
  481.           v= min;
  482.           e[0].bstate[BELOW]= UNBUNDLED;
  483.           e[0].bundle[BELOW][CLIP]= FALSE;
  484.           e[0].bundle[BELOW][SUBJ]= FALSE;
  485.           for (i= 0; i < num_edges; i++)
  486.           {
  487.             e[i].xb= edge_table[v].vertex.x;
  488.             e[i].bot.x= edge_table[v].vertex.x;
  489.             e[i].bot.y= edge_table[v].vertex.y;
  490.  
  491.             v= NEXT_INDEX(v, num_vertices);
  492.  
  493.             e[i].top.x= edge_table[v].vertex.x;
  494.             e[i].top.y= edge_table[v].vertex.y;
  495.             e[i].dx= (edge_table[v].vertex.x - e[i].bot.x) /
  496.                        (e[i].top.y - e[i].bot.y);
  497.             e[i].type= type;
  498.             e[i].outp[ABOVE]= NULL;
  499.             e[i].outp[BELOW]= NULL;
  500.             e[i].next= NULL;
  501.             e[i].prev= NULL;
  502.             e[i].succ= ((num_edges > 1) && (i < (num_edges - 1))) ?
  503.                        &(e[i + 1]) : NULL;
  504.             e[i].pred= ((num_edges > 1) && (i > 0)) ? &(e[i - 1]) : NULL;
  505.             e[i].next_bound= NULL;
  506.             e[i].bside[CLIP]= (op == GPC_DIFF) ? RIGHT : LEFT;
  507.             e[i].bside[SUBJ]= LEFT;
  508.           }
  509.           insert_bound(bound_list(lmt, edge_table[min].vertex.y), e);
  510.         }
  511.       }
  512.  
  513.       /* Do the contour reverse pass */
  514.       for (min= 0; min < num_vertices; min++)
  515.       {
  516.       /* If a reverse local minimum... */
  517.         if (REV_MIN(edge_table, min, num_vertices))
  518.         {
  519.           /* Search for the previous local maximum... */
  520.           num_edges= 1;
  521.           max= PREV_INDEX(min, num_vertices);
  522.           while (NOT_RMAX(edge_table, max, num_vertices))
  523.           {
  524.             num_edges++;
  525.             max= PREV_INDEX(max, num_vertices);
  526.           }
  527.  
  528.           /* Build the previous edge list */
  529.           e= &edge_table[e_index];
  530.           e_index+= num_edges;
  531.           v= min;
  532.           e[0].bstate[BELOW]= UNBUNDLED;
  533.           e[0].bundle[BELOW][CLIP]= FALSE;
  534.           e[0].bundle[BELOW][SUBJ]= FALSE;
  535.           for (i= 0; i < num_edges; i++)
  536.           {
  537.             e[i].xb= edge_table[v].vertex.x;
  538.             e[i].bot.x= edge_table[v].vertex.x;
  539.             e[i].bot.y= edge_table[v].vertex.y;
  540.  
  541.             v= PREV_INDEX(v, num_vertices);
  542.  
  543.             e[i].top.x= edge_table[v].vertex.x;
  544.             e[i].top.y= edge_table[v].vertex.y;
  545.             e[i].dx= (edge_table[v].vertex.x - e[i].bot.x) /
  546.                        (e[i].top.y - e[i].bot.y);
  547.             e[i].type= type;
  548.             e[i].outp[ABOVE]= NULL;
  549.             e[i].outp[BELOW]= NULL;
  550.             e[i].next= NULL;
  551.             e[i].prev= NULL;
  552.             e[i].succ= ((num_edges > 1) && (i < (num_edges - 1))) ?
  553.                        &(e[i + 1]) : NULL;
  554.             e[i].pred= ((num_edges > 1) && (i > 0)) ? &(e[i - 1]) : NULL;
  555.             e[i].next_bound= NULL;
  556.             e[i].bside[CLIP]= (op == GPC_DIFF) ? RIGHT : LEFT;
  557.             e[i].bside[SUBJ]= LEFT;
  558.           }
  559.           insert_bound(bound_list(lmt, edge_table[min].vertex.y), e);
  560.         }
  561.       }
  562.     }
  563.   }
  564.   return edge_table;
  565. }
  566.  
  567.  
  568. static void add_edge_to_aet(edge_node **aet, edge_node *edge, edge_node *prev)
  569. {
  570.   if (!*aet)
  571.   {
  572.     /* Append edge onto the tail end of the AET */
  573.     *aet= edge;
  574.     edge->prev= prev;
  575.     edge->next= NULL;
  576.   }
  577.   else
  578.   {
  579.     /* Do primary sort on the xb field */
  580.     if (edge->xb < (*aet)->xb)
  581.     {
  582.       /* Insert edge here (before the AET edge) */
  583.       edge->prev= prev;
  584.       edge->next= *aet;
  585.       (*aet)->prev= edge;
  586.       *aet= edge;
  587.     }
  588.     else
  589.     {
  590.       if (edge->xb == (*aet)->xb)
  591.       {
  592.         /* Do secondary sort on the dx field */
  593.         if (edge->dx < (*aet)->dx)
  594.         {
  595.           /* Insert edge here (before the AET edge) */
  596.           edge->prev= prev;
  597.           edge->next= *aet;
  598.           (*aet)->prev= edge;
  599.           *aet= edge;
  600.         }
  601.         else
  602.         {
  603.           /* Head further into the AET */
  604.           add_edge_to_aet(&((*aet)->next), edge, *aet);
  605.         }
  606.       }
  607.       else
  608.       {
  609.         /* Head further into the AET */
  610.         add_edge_to_aet(&((*aet)->next), edge, *aet);
  611.       }
  612.     }
  613.   }
  614. }
  615.  
  616.  
  617. static void add_intersection(it_node **it, edge_node *edge0, edge_node *edge1,
  618.                              double x, double y)
  619. {
  620.   it_node *existing_node;
  621.  
  622.   if (!*it)
  623.   {
  624.     /* Append a new node to the tail of the list */
  625.     MALLOC(*it, sizeof(it_node), "IT insertion", it_node);
  626.     (*it)->ie[0]= edge0;
  627.     (*it)->ie[1]= edge1;
  628.     (*it)->point.x= x;
  629.     (*it)->point.y= y;
  630.     (*it)->next= NULL;
  631.   }
  632.   else
  633.   {
  634.     if ((*it)->point.y > y)
  635.     {
  636.       /* Insert a new node mid-list */
  637.       existing_node= *it;
  638.       MALLOC(*it, sizeof(it_node), "IT insertion", it_node);
  639.       (*it)->ie[0]= edge0;
  640.       (*it)->ie[1]= edge1;
  641.       (*it)->point.x= x;
  642.       (*it)->point.y= y;
  643.       (*it)->next= existing_node;
  644.     }
  645.     else
  646.       /* Head further down the list */
  647.       add_intersection(&((*it)->next), edge0, edge1, x, y);
  648.   }
  649. }
  650.  
  651.  
  652. static void add_st_edge(st_node **st, it_node **it, edge_node *edge,
  653.                         double dy)
  654. {
  655.   st_node *existing_node;
  656.   double   den, r, x, y;
  657.  
  658.   if (!*st)
  659.   {
  660.     /* Append edge onto the tail end of the ST */
  661.     MALLOC(*st, sizeof(st_node), "ST insertion", st_node);
  662.     (*st)->edge= edge;
  663.     (*st)->xb= edge->xb;
  664.     (*st)->xt= edge->xt;
  665.     (*st)->dx= edge->dx;
  666.     (*st)->prev= NULL;
  667.   }
  668.   else
  669.   {
  670.     den= ((*st)->xt - (*st)->xb) - (edge->xt - edge->xb);
  671.  
  672.     /* If new edge and ST edge don't cross */
  673.     if ((edge->xt >= (*st)->xt) || (edge->dx == (*st)->dx) ||
  674.         (fabs(den) <= DBL_EPSILON))
  675.     {
  676.       /* No intersection - insert edge here (before the ST edge) */
  677.       existing_node= *st;
  678.       MALLOC(*st, sizeof(st_node), "ST insertion", st_node);
  679.       (*st)->edge= edge;
  680.       (*st)->xb= edge->xb;
  681.       (*st)->xt= edge->xt;
  682.       (*st)->dx= edge->dx;
  683.       (*st)->prev= existing_node;
  684.     }
  685.     else
  686.     {
  687.       /* Compute intersection between new edge and ST edge */
  688.       r= (edge->xb - (*st)->xb) / den;
  689.       x= (*st)->xb + r * ((*st)->xt - (*st)->xb);
  690.       y= r * dy;
  691.  
  692.       /* Insert the edge pointers and the intersection point in the IT */
  693.       add_intersection(it, (*st)->edge, edge, x, y);
  694.  
  695.       /* Head further into the ST */
  696.       add_st_edge(&((*st)->prev), it, edge, dy);
  697.     }
  698.   }
  699. }
  700.  
  701.  
  702. static void build_intersection_table(it_node **it, edge_node *aet, double dy)
  703. {
  704.   st_node   *st, *stp;
  705.   edge_node *edge;
  706.  
  707.   /* Build intersection table for the current scanbeam */
  708.   reset_it(it);
  709.   st= NULL;
  710.  
  711.   /* Process each AET edge */
  712.   for (edge= aet; edge; edge= edge->next)
  713.   {
  714.     if ((edge->bstate[ABOVE] == BUNDLE_HEAD) ||
  715.          edge->bundle[ABOVE][CLIP] || edge->bundle[ABOVE][SUBJ])
  716.       add_st_edge(&st, it, edge, dy);
  717.   }
  718.  
  719.   /* Free the sorted edge table */
  720.   while (st)
  721.   {
  722.     stp= st->prev;
  723.     FREE(st);
  724.     st= stp;
  725.   }
  726. }
  727.  
  728. static int count_contours(polygon_node *polygon)
  729. {
  730.   int          nc, nv;
  731.   vertex_node *v, *nextv;
  732.  
  733.   for (nc= 0; polygon; polygon= polygon->next)
  734.     if (polygon->active)
  735.     {
  736.       /* Count the vertices in the current contour */
  737.       nv= 0;
  738.       for (v= polygon->proxy->v[LEFT]; v; v= v->next)
  739.         nv++;
  740.  
  741.       /* Record valid vertex counts in the active field */
  742.       if (nv > 2)
  743.       {
  744.         polygon->active= nv;
  745.         nc++;
  746.       }
  747.       else
  748.       {
  749.         /* Invalid contour: just free the heap */
  750.         for (v= polygon->proxy->v[LEFT]; v; v= nextv)
  751.         {
  752.           nextv= v->next;
  753.           FREE(v);
  754.         }
  755.         polygon->active= 0;
  756.       }
  757.     }
  758.   return nc;
  759. }
  760.  
  761.  
  762. static void add_left(polygon_node *p, double x, double y)
  763. {
  764.   vertex_node *nv;
  765.  
  766.   /* Create a new vertex node and set its fields */
  767.   MALLOC(nv, sizeof(vertex_node), "vertex node creation", vertex_node);
  768.   nv->x= x;
  769.   nv->y= y;
  770.  
  771.   /* Add vertex nv to the left end of the polygon's vertex list */
  772.   nv->next= p->proxy->v[LEFT];
  773.  
  774.   /* Update proxy->[LEFT] to point to nv */
  775.   p->proxy->v[LEFT]= nv;
  776. }
  777.  
  778.  
  779. static void merge_left(polygon_node *p, polygon_node *q, polygon_node *list)
  780. {
  781.   polygon_node *target;
  782.  
  783.   /* Label contour as a hole */
  784.   q->proxy->hole= TRUE;
  785.  
  786.   if (p->proxy != q->proxy)
  787.   {
  788.     /* Assign p's vertex list to the left end of q's list */
  789.     p->proxy->v[RIGHT]->next= q->proxy->v[LEFT];
  790.     q->proxy->v[LEFT]= p->proxy->v[LEFT];
  791.  
  792.     /* Redirect any p->proxy references to q->proxy */
  793.    
  794.     for (target= p->proxy; list; list= list->next)
  795.     {
  796.       if (list->proxy == target)
  797.       {
  798.         list->active= FALSE;
  799.         list->proxy= q->proxy;
  800.       }
  801.     }
  802.   }
  803. }
  804.  
  805.  
  806. static void add_right(polygon_node *p, double x, double y)
  807. {
  808.   vertex_node *nv;
  809.  
  810.   /* Create a new vertex node and set its fields */
  811.   MALLOC(nv, sizeof(vertex_node), "vertex node creation", vertex_node);
  812.   nv->x= x;
  813.   nv->y= y;
  814.   nv->next= NULL;
  815.  
  816.   /* Add vertex nv to the right end of the polygon's vertex list */
  817.   p->proxy->v[RIGHT]->next= nv;
  818.  
  819.   /* Update proxy->v[RIGHT] to point to nv */
  820.   p->proxy->v[RIGHT]= nv;
  821. }
  822.  
  823.  
  824. static void merge_right(polygon_node *p, polygon_node *q, polygon_node *list)
  825. {
  826.   polygon_node *target;
  827.  
  828.   /* Label contour as external */
  829.   q->proxy->hole= FALSE;
  830.  
  831.   if (p->proxy != q->proxy)
  832.   {
  833.     /* Assign p's vertex list to the right end of q's list */
  834.     q->proxy->v[RIGHT]->next= p->proxy->v[LEFT];
  835.     q->proxy->v[RIGHT]= p->proxy->v[RIGHT];
  836.  
  837.     /* Redirect any p->proxy references to q->proxy */
  838.     for (target= p->proxy; list; list= list->next)
  839.     {
  840.       if (list->proxy == target)
  841.       {
  842.         list->active= FALSE;
  843.         list->proxy= q->proxy;
  844.       }
  845.     }
  846.   }
  847. }
  848.  
  849.  
  850. static void add_local_min(polygon_node **p, edge_node *edge,
  851.                           double x, double y)
  852. {
  853.   polygon_node *existing_min;
  854.   vertex_node  *nv;
  855.  
  856.   existing_min= *p;
  857.  
  858.   MALLOC(*p, sizeof(polygon_node), "polygon node creation", polygon_node);
  859.  
  860.   /* Create a new vertex node and set its fields */
  861.   MALLOC(nv, sizeof(vertex_node), "vertex node creation", vertex_node);
  862.   nv->x= x;
  863.   nv->y= y;
  864.   nv->next= NULL;
  865.  
  866.   /* Initialise proxy to point to p itself */
  867.   (*p)->proxy= (*p);
  868.   (*p)->active= TRUE;
  869.   (*p)->next= existing_min;
  870.  
  871.   /* Make v[LEFT] and v[RIGHT] point to new vertex nv */
  872.   (*p)->v[LEFT]= nv;
  873.   (*p)->v[RIGHT]= nv;
  874.  
  875.   /* Assign polygon p to the edge */
  876.   edge->outp[ABOVE]= *p;
  877. }
  878.  
  879.  
  880. static int count_tristrips(polygon_node *tn)
  881. {
  882.   int total;
  883.  
  884.   for (total= 0; tn; tn= tn->next)
  885.     if (tn->active > 2)
  886.       total++;
  887.   return total;
  888. }
  889.  
  890.  
  891. static void add_vertex(vertex_node **t, double x, double y)
  892. {
  893.   if (!(*t))
  894.   {
  895.     MALLOC(*t, sizeof(vertex_node), "tristrip vertex creation", vertex_node);
  896.     (*t)->x= x;
  897.     (*t)->y= y;
  898.     (*t)->next= NULL;
  899.   }
  900.   else
  901.     /* Head further down the list */
  902.     add_vertex(&((*t)->next), x, y);
  903. }
  904.  
  905.  
  906. static void new_tristrip(polygon_node **tn, edge_node *edge,
  907.                          double x, double y)
  908. {
  909.   if (!(*tn))
  910.   {
  911.     MALLOC(*tn, sizeof(polygon_node), "tristrip node creation", polygon_node);
  912.     (*tn)->next= NULL;
  913.     (*tn)->v[LEFT]= NULL;
  914.     (*tn)->v[RIGHT]= NULL;
  915.     (*tn)->active= 1;
  916.     add_vertex(&((*tn)->v[LEFT]), x, y);
  917.     edge->outp[ABOVE]= *tn;
  918.   }
  919.   else
  920.     /* Head further down the list */
  921.     new_tristrip(&((*tn)->next), edge, x, y);
  922. }
  923.  
  924.  
  925. static bbox *create_contour_bboxes(gpc_polygon *p)
  926. {
  927.   bbox *box;
  928.   int   c, v;
  929.  
  930.   MALLOC(box, p->num_contours * sizeof(bbox), "Bounding box creation", bbox);
  931.  
  932.   /* Construct contour bounding boxes */
  933.   for (c= 0; c < p->num_contours; c++)
  934.   {
  935.     /* Initialise bounding box extent */
  936.     box[c].xmin= DBL_MAX;
  937.     box[c].ymin= DBL_MAX;
  938.     box[c].xmax= -DBL_MAX;
  939.     box[c].ymax= -DBL_MAX;
  940.  
  941.     for (v= 0; v < p->contour[c].num_vertices; v++)
  942.     {
  943.       /* Adjust bounding box */
  944.       if (p->contour[c].vertex[v].x < box[c].xmin)
  945.         box[c].xmin= p->contour[c].vertex[v].x;
  946.       if (p->contour[c].vertex[v].y < box[c].ymin)
  947.         box[c].ymin= p->contour[c].vertex[v].y;
  948.       if (p->contour[c].vertex[v].x > box[c].xmax)
  949.         box[c].xmax= p->contour[c].vertex[v].x;
  950.       if (p->contour[c].vertex[v].y > box[c].ymax)
  951.           box[c].ymax= p->contour[c].vertex[v].y;
  952.     }
  953.   }
  954.   return box;  
  955. }
  956.  
  957.  
  958. static void minimax_test(gpc_polygon *subj, gpc_polygon *clip, gpc_op op)
  959. {
  960.   bbox *s_bbox, *c_bbox;
  961.   int   s, c, *o_table, overlap;
  962.  
  963.   s_bbox= create_contour_bboxes(subj);
  964.   c_bbox= create_contour_bboxes(clip);
  965.  
  966.   MALLOC(o_table, subj->num_contours * clip->num_contours * sizeof(int),
  967.          "overlap table creation", int);
  968.  
  969.   /* Check all subject contour bounding boxes against clip boxes */
  970.   for (s= 0; s < subj->num_contours; s++)
  971.     for (c= 0; c < clip->num_contours; c++)
  972.       o_table[c * subj->num_contours + s]=
  973.              (!((s_bbox[s].xmax < c_bbox[c].xmin) ||
  974.                 (s_bbox[s].xmin > c_bbox[c].xmax))) &&
  975.              (!((s_bbox[s].ymax < c_bbox[c].ymin) ||
  976.                 (s_bbox[s].ymin > c_bbox[c].ymax)));
  977.  
  978.   /* For each clip contour, search for any subject contour overlaps */
  979.   for (c= 0; c < clip->num_contours; c++)
  980.   {
  981.     overlap= 0;
  982.     for (s= 0; (!overlap) && (s < subj->num_contours); s++)
  983.       overlap= o_table[c * subj->num_contours + s];
  984.  
  985.     if (!overlap)
  986.       /* Flag non contributing status by negating vertex count */
  987.       clip->contour[c].num_vertices = -clip->contour[c].num_vertices;
  988.   }  
  989.  
  990.   if (op == GPC_INT)
  991.   {  
  992.     /* For each subject contour, search for any clip contour overlaps */
  993.     for (s= 0; s < subj->num_contours; s++)
  994.     {
  995.       overlap= 0;
  996.       for (c= 0; (!overlap) && (c < clip->num_contours); c++)
  997.         overlap= o_table[c * subj->num_contours + s];
  998.  
  999.       if (!overlap)
  1000.         /* Flag non contributing status by negating vertex count */
  1001.         subj->contour[s].num_vertices = -subj->contour[s].num_vertices;
  1002.     }  
  1003.   }
  1004.  
  1005.   FREE(s_bbox);
  1006.   FREE(c_bbox);
  1007.   FREE(o_table);
  1008. }
  1009.  
  1010.  
  1011. /*
  1012. ===========================================================================
  1013.                              Public Functions
  1014. ===========================================================================
  1015. */
  1016.  
  1017. void gpc_free_polygon(gpc_polygon *p)
  1018. {
  1019.   int c;
  1020.  
  1021.   for (c= 0; c < p->num_contours; c++)
  1022.     FREE(p->contour[c].vertex);
  1023.   FREE(p->hole);
  1024.   FREE(p->contour);
  1025.   p->num_contours= 0;
  1026. }
  1027.  
  1028.  
  1029. void gpc_read_polygon(FILE *fp, int read_hole_flags, gpc_polygon *p)
  1030. {
  1031.   int c, v;
  1032.  
  1033.   fscanf(fp, "%d", &(p->num_contours));
  1034.   MALLOC(p->hole, p->num_contours * sizeof(int),
  1035.          "hole flag array creation", int);
  1036.   MALLOC(p->contour, p->num_contours
  1037.          * sizeof(gpc_vertex_list), "contour creation", gpc_vertex_list);
  1038.   for (c= 0; c < p->num_contours; c++)
  1039.   {
  1040.     fscanf(fp, "%d", &(p->contour[c].num_vertices));
  1041.  
  1042.     if (read_hole_flags)
  1043.       fscanf(fp, "%d", &(p->hole[c]));
  1044.     else
  1045.       p->hole[c]= FALSE; /* Assume all contours to be external */
  1046.  
  1047.     MALLOC(p->contour[c].vertex, p->contour[c].num_vertices
  1048.            * sizeof(gpc_vertex), "vertex creation", gpc_vertex);
  1049.     for (v= 0; v < p->contour[c].num_vertices; v++)
  1050.       fscanf(fp, "%lf %lf", &(p->contour[c].vertex[v].x),
  1051.                             &(p->contour[c].vertex[v].y));
  1052.   }
  1053. }
  1054.  
  1055.  
  1056. void gpc_write_polygon(FILE *fp, int write_hole_flags, gpc_polygon *p)
  1057. {
  1058.   int c, v;
  1059.  
  1060.   fprintf(fp, "%d\n", p->num_contours);
  1061.   for (c= 0; c < p->num_contours; c++)
  1062.   {
  1063.     fprintf(fp, "%d\n", p->contour[c].num_vertices);
  1064.  
  1065.     if (write_hole_flags)
  1066.       fprintf(fp, "%d\n", p->hole[c]);
  1067.    
  1068.     for (v= 0; v < p->contour[c].num_vertices; v++)
  1069.       fprintf(fp, "% .*lf % .*lf\n",
  1070.               DBL_DIG, p->contour[c].vertex[v].x,
  1071.               DBL_DIG, p->contour[c].vertex[v].y);
  1072.   }
  1073. }
  1074.  
  1075.  
  1076. void gpc_add_contour(gpc_polygon *p, gpc_vertex_list *new_contour, int hole)
  1077. {
  1078.   int             *extended_hole, c, v;
  1079.   gpc_vertex_list *extended_contour;
  1080.  
  1081.   /* Create an extended hole array */
  1082.   MALLOC(extended_hole, (p->num_contours + 1)
  1083.          * sizeof(int), "contour hole addition", int);
  1084.  
  1085.   /* Create an extended contour array */
  1086.   MALLOC(extended_contour, (p->num_contours + 1)
  1087.          * sizeof(gpc_vertex_list), "contour addition", gpc_vertex_list);
  1088.  
  1089.   /* Copy the old contour and hole data into the extended arrays */
  1090.   for (c= 0; c < p->num_contours; c++)
  1091.   {
  1092.     extended_hole[c]= p->hole[c];
  1093.     extended_contour[c]= p->contour[c];
  1094.   }
  1095.  
  1096.   /* Copy the new contour and hole onto the end of the extended arrays */
  1097.   c= p->num_contours;
  1098.   extended_hole[c]= hole;
  1099.   extended_contour[c].num_vertices= new_contour->num_vertices;
  1100.   MALLOC(extended_contour[c].vertex, new_contour->num_vertices
  1101.          * sizeof(gpc_vertex), "contour addition", gpc_vertex);
  1102.   for (v= 0; v < new_contour->num_vertices; v++)
  1103.     extended_contour[c].vertex[v]= new_contour->vertex[v];
  1104.  
  1105.   /* Dispose of the old contour */
  1106.   FREE(p->contour);
  1107.   FREE(p->hole);
  1108.  
  1109.   /* Update the polygon information */
  1110.   p->num_contours++;
  1111.   p->hole= extended_hole;
  1112.   p->contour= extended_contour;
  1113. }
  1114.  
  1115.  
  1116. void gpc_polygon_clip(gpc_op op, gpc_polygon *subj, gpc_polygon *clip,
  1117.                       gpc_polygon *result)
  1118. {
  1119.   sb_tree       *sbtree= NULL;
  1120.   it_node       *it= NULL, *intersect;
  1121.   edge_node     *edge, *prev_edge, *next_edge, *succ_edge, *e0, *e1;
  1122.   edge_node     *aet= NULL, *c_heap= NULL, *s_heap= NULL;
  1123.   lmt_node      *lmt= NULL, *local_min;
  1124.   polygon_node  *out_poly= NULL, *p, *q, *poly, *npoly, *cf= NULL;
  1125.   vertex_node   *vtx, *nv;
  1126.   h_state        horiz[2];
  1127.   int            in[2], exists[2], parity[2]= {LEFT, LEFT};
  1128.   int            c, v, contributing, search, scanbeam= 0, sbt_entries= 0;
  1129.   int            vclass, bl, br, tl, tr;
  1130.   double        *sbt= NULL, xb, px, yb, yt, dy, ix, iy;
  1131.  
  1132.   /* Test for trivial NULL result cases */
  1133.   if (((subj->num_contours == 0) && (clip->num_contours == 0))
  1134.    || ((subj->num_contours == 0) && ((op == GPC_INT) || (op == GPC_DIFF)))
  1135.    || ((clip->num_contours == 0) &&  (op == GPC_INT)))
  1136.   {
  1137.     result->num_contours= 0;
  1138.     result->hole= NULL;
  1139.     result->contour= NULL;
  1140.     return;
  1141.   }
  1142.  
  1143.   /* Identify potentialy contributing contours */
  1144.   if (((op == GPC_INT) || (op == GPC_DIFF))
  1145.    && (subj->num_contours > 0) && (clip->num_contours > 0))
  1146.     minimax_test(subj, clip, op);
  1147.  
  1148.   /* Build LMT */
  1149.   if (subj->num_contours > 0)
  1150.     s_heap= build_lmt(&lmt, &sbtree, &sbt_entries, subj, SUBJ, op);
  1151.   if (clip->num_contours > 0)
  1152.     c_heap= build_lmt(&lmt, &sbtree, &sbt_entries, clip, CLIP, op);
  1153.  
  1154.   /* Return a NULL result if no contours contribute */
  1155.   if (lmt == NULL)
  1156.   {
  1157.     result->num_contours= 0;
  1158.     result->hole= NULL;
  1159.     result->contour= NULL;
  1160.     reset_lmt(&lmt);
  1161.     FREE(s_heap);
  1162.     FREE(c_heap);
  1163.     return;
  1164.   }
  1165.  
  1166.   /* Build scanbeam table from scanbeam tree */
  1167.   MALLOC(sbt, sbt_entries * sizeof(double), "sbt creation", double);
  1168.   build_sbt(&scanbeam, sbt, sbtree);
  1169.   scanbeam= 0;
  1170.   free_sbtree(&sbtree);
  1171.  
  1172.   /* Allow pointer re-use without causing memory leak */
  1173.   if (subj == result)
  1174.     gpc_free_polygon(subj);
  1175.   if (clip == result)
  1176.     gpc_free_polygon(clip);
  1177.  
  1178.   /* Invert clip polygon for difference operation */
  1179.   if (op == GPC_DIFF)
  1180.     parity[CLIP]= RIGHT;
  1181.  
  1182.   local_min= lmt;
  1183.  
  1184.   /* Process each scanbeam */
  1185.   while (scanbeam < sbt_entries)
  1186.   {
  1187.     /* Set yb and yt to the bottom and top of the scanbeam */
  1188.     yb= sbt[scanbeam++];
  1189.     if (scanbeam < sbt_entries)
  1190.     {
  1191.       yt= sbt[scanbeam];
  1192.       dy= yt - yb;
  1193.     }
  1194.  
  1195.     /* === SCANBEAM BOUNDARY PROCESSING ================================ */
  1196.  
  1197.     /* If LMT node corresponding to yb exists */
  1198.     if (local_min)
  1199.     {
  1200.       if (local_min->y == yb)
  1201.       {
  1202.         /* Add edges starting at this local minimum to the AET */
  1203.         for (edge= local_min->first_bound; edge; edge= edge->next_bound)
  1204.           add_edge_to_aet(&aet, edge, NULL);
  1205.  
  1206.         local_min= local_min->next;
  1207.       }
  1208.     }
  1209.  
  1210.     /* Set dummy previous x value */
  1211.     px= -DBL_MAX;
  1212.  
  1213.     /* Create bundles within AET */
  1214.     e0= aet;
  1215.     e1= aet;
  1216.  
  1217.     /* Set up bundle fields of first edge */
  1218.     aet->bundle[ABOVE][ aet->type]= (aet->top.y != yb);
  1219.     aet->bundle[ABOVE][!aet->type]= FALSE;
  1220.     aet->bstate[ABOVE]= UNBUNDLED;
  1221.  
  1222.     for (next_edge= aet->next; next_edge; next_edge= next_edge->next)
  1223.     {
  1224.       /* Set up bundle fields of next edge */
  1225.       next_edge->bundle[ABOVE][ next_edge->type]= (next_edge->top.y != yb);
  1226.       next_edge->bundle[ABOVE][!next_edge->type]= FALSE;
  1227.       next_edge->bstate[ABOVE]= UNBUNDLED;
  1228.  
  1229.       /* Bundle edges above the scanbeam boundary if they coincide */
  1230.       if (next_edge->bundle[ABOVE][next_edge->type])
  1231.       {
  1232.         if (EQ(e0->xb, next_edge->xb) && EQ(e0->dx, next_edge->dx)
  1233.      && (e0->top.y != yb))
  1234.         {
  1235.           next_edge->bundle[ABOVE][ next_edge->type]^=
  1236.             e0->bundle[ABOVE][ next_edge->type];
  1237.           next_edge->bundle[ABOVE][!next_edge->type]=
  1238.             e0->bundle[ABOVE][!next_edge->type];
  1239.           next_edge->bstate[ABOVE]= BUNDLE_HEAD;
  1240.           e0->bundle[ABOVE][CLIP]= FALSE;
  1241.           e0->bundle[ABOVE][SUBJ]= FALSE;
  1242.           e0->bstate[ABOVE]= BUNDLE_TAIL;
  1243.         }
  1244.         e0= next_edge;
  1245.       }
  1246.     }
  1247.    
  1248.     horiz[CLIP]= NH;
  1249.     horiz[SUBJ]= NH;
  1250.  
  1251.     /* Process each edge at this scanbeam boundary */
  1252.     for (edge= aet; edge; edge= edge->next)
  1253.     {
  1254.       exists[CLIP]= edge->bundle[ABOVE][CLIP] +
  1255.                    (edge->bundle[BELOW][CLIP] << 1);
  1256.       exists[SUBJ]= edge->bundle[ABOVE][SUBJ] +
  1257.                    (edge->bundle[BELOW][SUBJ] << 1);
  1258.  
  1259.       if (exists[CLIP] || exists[SUBJ])
  1260.       {
  1261.         /* Set bundle side */
  1262.         edge->bside[CLIP]= parity[CLIP];
  1263.         edge->bside[SUBJ]= parity[SUBJ];
  1264.  
  1265.         /* Determine contributing status and quadrant occupancies */
  1266.         switch (op)
  1267.         {
  1268.         case GPC_DIFF:
  1269.         case GPC_INT:
  1270.           contributing= (exists[CLIP] && (parity[SUBJ] || horiz[SUBJ]))
  1271.                      || (exists[SUBJ] && (parity[CLIP] || horiz[CLIP]))
  1272.                      || (exists[CLIP] && exists[SUBJ]
  1273.                      && (parity[CLIP] == parity[SUBJ]));
  1274.           br= (parity[CLIP])
  1275.            && (parity[SUBJ]);
  1276.           bl= (parity[CLIP] ^ edge->bundle[ABOVE][CLIP])
  1277.            && (parity[SUBJ] ^ edge->bundle[ABOVE][SUBJ]);
  1278.           tr= (parity[CLIP] ^ (horiz[CLIP]!=NH))
  1279.            && (parity[SUBJ] ^ (horiz[SUBJ]!=NH));
  1280.           tl= (parity[CLIP] ^ (horiz[CLIP]!=NH) ^ edge->bundle[BELOW][CLIP])
  1281.            && (parity[SUBJ] ^ (horiz[SUBJ]!=NH) ^ edge->bundle[BELOW][SUBJ]);
  1282.           break;
  1283.         case GPC_XOR:
  1284.           contributing= exists[CLIP] || exists[SUBJ];
  1285.           br= (parity[CLIP])
  1286.             ^ (parity[SUBJ]);
  1287.           bl= (parity[CLIP] ^ edge->bundle[ABOVE][CLIP])
  1288.             ^ (parity[SUBJ] ^ edge->bundle[ABOVE][SUBJ]);
  1289.           tr= (parity[CLIP] ^ (horiz[CLIP]!=NH))
  1290.             ^ (parity[SUBJ] ^ (horiz[SUBJ]!=NH));
  1291.           tl= (parity[CLIP] ^ (horiz[CLIP]!=NH) ^ edge->bundle[BELOW][CLIP])
  1292.             ^ (parity[SUBJ] ^ (horiz[SUBJ]!=NH) ^ edge->bundle[BELOW][SUBJ]);
  1293.           break;
  1294.         case GPC_UNION:
  1295.           contributing= (exists[CLIP] && (!parity[SUBJ] || horiz[SUBJ]))
  1296.                      || (exists[SUBJ] && (!parity[CLIP] || horiz[CLIP]))
  1297.                      || (exists[CLIP] && exists[SUBJ]
  1298.                      && (parity[CLIP] == parity[SUBJ]));
  1299.           br= (parity[CLIP])
  1300.            || (parity[SUBJ]);
  1301.           bl= (parity[CLIP] ^ edge->bundle[ABOVE][CLIP])
  1302.            || (parity[SUBJ] ^ edge->bundle[ABOVE][SUBJ]);
  1303.           tr= (parity[CLIP] ^ (horiz[CLIP]!=NH))
  1304.            || (parity[SUBJ] ^ (horiz[SUBJ]!=NH));
  1305.           tl= (parity[CLIP] ^ (horiz[CLIP]!=NH) ^ edge->bundle[BELOW][CLIP])
  1306.            || (parity[SUBJ] ^ (horiz[SUBJ]!=NH) ^ edge->bundle[BELOW][SUBJ]);
  1307.           break;
  1308.         }
  1309.  
  1310.         /* Update parity */
  1311.         parity[CLIP]^= edge->bundle[ABOVE][CLIP];
  1312.         parity[SUBJ]^= edge->bundle[ABOVE][SUBJ];
  1313.  
  1314.         /* Update horizontal state */
  1315.         if (exists[CLIP])        
  1316.           horiz[CLIP]=
  1317.             next_h_state[horiz[CLIP]]
  1318.                         [((exists[CLIP] - 1) << 1) + parity[CLIP]];
  1319.         if (exists[SUBJ])        
  1320.           horiz[SUBJ]=
  1321.             next_h_state[horiz[SUBJ]]
  1322.                         [((exists[SUBJ] - 1) << 1) + parity[SUBJ]];
  1323.  
  1324.         vclass= tr + (tl << 1) + (br << 2) + (bl << 3);
  1325.  
  1326.         if (contributing)
  1327.         {
  1328.           xb= edge->xb;
  1329.  
  1330.           switch (vclass)
  1331.           {
  1332.           case EMN:
  1333.           case IMN:
  1334.             add_local_min(&out_poly, edge, xb, yb);
  1335.             px= xb;
  1336.             cf= edge->outp[ABOVE];
  1337.             break;
  1338.           case ERI:
  1339.             if (xb != px)
  1340.             {
  1341.               add_right(cf, xb, yb);
  1342.               px= xb;
  1343.             }
  1344.             edge->outp[ABOVE]= cf;
  1345.             cf= NULL;
  1346.             break;
  1347.           case ELI:
  1348.             add_left(edge->outp[BELOW], xb, yb);
  1349.             px= xb;
  1350.             cf= edge->outp[BELOW];
  1351.             break;
  1352.           case EMX:
  1353.             if (xb != px)
  1354.             {
  1355.               add_left(cf, xb, yb);
  1356.               px= xb;
  1357.             }
  1358.             merge_right(cf, edge->outp[BELOW], out_poly);
  1359.             cf= NULL;
  1360.             break;
  1361.           case ILI:
  1362.             if (xb != px)
  1363.             {
  1364.               add_left(cf, xb, yb);
  1365.               px= xb;
  1366.             }
  1367.             edge->outp[ABOVE]= cf;
  1368.             cf= NULL;
  1369.             break;
  1370.           case IRI:
  1371.             add_right(edge->outp[BELOW], xb, yb);
  1372.             px= xb;
  1373.             cf= edge->outp[BELOW];
  1374.             edge->outp[BELOW]= NULL;
  1375.             break;
  1376.           case IMX:
  1377.             if (xb != px)
  1378.             {
  1379.               add_right(cf, xb, yb);
  1380.               px= xb;
  1381.             }
  1382.             merge_left(cf, edge->outp[BELOW], out_poly);
  1383.             cf= NULL;
  1384.             edge->outp[BELOW]= NULL;
  1385.             break;
  1386.           case IMM:
  1387.             if (xb != px)
  1388.         {
  1389.               add_right(cf, xb, yb);
  1390.               px= xb;
  1391.         }
  1392.             merge_left(cf, edge->outp[BELOW], out_poly);
  1393.             edge->outp[BELOW]= NULL;
  1394.             add_local_min(&out_poly, edge, xb, yb);
  1395.             cf= edge->outp[ABOVE];
  1396.             break;
  1397.           case EMM:
  1398.             if (xb != px)
  1399.         {
  1400.               add_left(cf, xb, yb);
  1401.               px= xb;
  1402.         }
  1403.             merge_right(cf, edge->outp[BELOW], out_poly);
  1404.             edge->outp[BELOW]= NULL;
  1405.             add_local_min(&out_poly, edge, xb, yb);
  1406.             cf= edge->outp[ABOVE];
  1407.             break;
  1408.           case LED:
  1409.             if (edge->bot.y == yb)
  1410.               add_left(edge->outp[BELOW], xb, yb);
  1411.             edge->outp[ABOVE]= edge->outp[BELOW];
  1412.             px= xb;
  1413.             break;
  1414.           case RED:
  1415.             if (edge->bot.y == yb)
  1416.               add_right(edge->outp[BELOW], xb, yb);
  1417.             edge->outp[ABOVE]= edge->outp[BELOW];
  1418.             px= xb;
  1419.             break;
  1420.           default:
  1421.             break;
  1422.           } /* End of switch */
  1423.         } /* End of contributing conditional */
  1424.       } /* End of edge exists conditional */
  1425.     } /* End of AET loop */
  1426.  
  1427.     /* Delete terminating edges from the AET, otherwise compute xt */
  1428.     for (edge= aet; edge; edge= edge->next)
  1429.     {
  1430.       if (edge->top.y == yb)
  1431.       {
  1432.         prev_edge= edge->prev;
  1433.         next_edge= edge->next;
  1434.         if (prev_edge)
  1435.           prev_edge->next= next_edge;
  1436.         else
  1437.           aet= next_edge;
  1438.         if (next_edge)
  1439.           next_edge->prev= prev_edge;
  1440.  
  1441.         /* Copy bundle head state to the adjacent tail edge if required */
  1442.         if ((edge->bstate[BELOW] == BUNDLE_HEAD) && prev_edge)
  1443.     {
  1444.           if (prev_edge->bstate[BELOW] == BUNDLE_TAIL)
  1445.           {
  1446.             prev_edge->outp[BELOW]= edge->outp[BELOW];
  1447.             prev_edge->bstate[BELOW]= UNBUNDLED;
  1448.             if (prev_edge->prev)
  1449.               if (prev_edge->prev->bstate[BELOW] == BUNDLE_TAIL)
  1450.                 prev_edge->bstate[BELOW]= BUNDLE_HEAD;
  1451.       }
  1452.     }
  1453.       }
  1454.       else
  1455.       {
  1456.         if (edge->top.y == yt)
  1457.           edge->xt= edge->top.x;
  1458.         else
  1459.           edge->xt= edge->bot.x + edge->dx * (yt - edge->bot.y);
  1460.       }
  1461.     }
  1462.  
  1463.     if (scanbeam < sbt_entries)
  1464.     {
  1465.       /* === SCANBEAM INTERIOR PROCESSING ============================== */
  1466.  
  1467.       build_intersection_table(&it, aet, dy);
  1468.  
  1469.       /* Process each node in the intersection table */
  1470.       for (intersect= it; intersect; intersect= intersect->next)
  1471.       {
  1472.         e0= intersect->ie[0];
  1473.         e1= intersect->ie[1];
  1474.  
  1475.         /* Only generate output for contributing intersections */
  1476.         if ((e0->bundle[ABOVE][CLIP] || e0->bundle[ABOVE][SUBJ])
  1477.          && (e1->bundle[ABOVE][CLIP] || e1->bundle[ABOVE][SUBJ]))
  1478.     {
  1479.           p= e0->outp[ABOVE];
  1480.           q= e1->outp[ABOVE];
  1481.           ix= intersect->point.x;
  1482.           iy= intersect->point.y + yb;
  1483.  
  1484.           in[CLIP]= ( e0->bundle[ABOVE][CLIP] && !e0->bside[CLIP])
  1485.                  || ( e1->bundle[ABOVE][CLIP] &&  e1->bside[CLIP])
  1486.                  || (!e0->bundle[ABOVE][CLIP] && !e1->bundle[ABOVE][CLIP]
  1487.                      && e0->bside[CLIP] && e1->bside[CLIP]);
  1488.           in[SUBJ]= ( e0->bundle[ABOVE][SUBJ] && !e0->bside[SUBJ])
  1489.                  || ( e1->bundle[ABOVE][SUBJ] &&  e1->bside[SUBJ])
  1490.                  || (!e0->bundle[ABOVE][SUBJ] && !e1->bundle[ABOVE][SUBJ]
  1491.                      && e0->bside[SUBJ] && e1->bside[SUBJ]);
  1492.        
  1493.           /* Determine quadrant occupancies */
  1494.           switch (op)
  1495.           {
  1496.           case GPC_DIFF:
  1497.           case GPC_INT:
  1498.             tr= (in[CLIP])
  1499.              && (in[SUBJ]);
  1500.             tl= (in[CLIP] ^ e1->bundle[ABOVE][CLIP])
  1501.              && (in[SUBJ] ^ e1->bundle[ABOVE][SUBJ]);
  1502.             br= (in[CLIP] ^ e0->bundle[ABOVE][CLIP])
  1503.              && (in[SUBJ] ^ e0->bundle[ABOVE][SUBJ]);
  1504.             bl= (in[CLIP] ^ e1->bundle[ABOVE][CLIP] ^ e0->bundle[ABOVE][CLIP])
  1505.              && (in[SUBJ] ^ e1->bundle[ABOVE][SUBJ] ^ e0->bundle[ABOVE][SUBJ]);
  1506.             break;
  1507.           case GPC_XOR:
  1508.             tr= (in[CLIP])
  1509.               ^ (in[SUBJ]);
  1510.             tl= (in[CLIP] ^ e1->bundle[ABOVE][CLIP])
  1511.               ^ (in[SUBJ] ^ e1->bundle[ABOVE][SUBJ]);
  1512.             br= (in[CLIP] ^ e0->bundle[ABOVE][CLIP])
  1513.               ^ (in[SUBJ] ^ e0->bundle[ABOVE][SUBJ]);
  1514.             bl= (in[CLIP] ^ e1->bundle[ABOVE][CLIP] ^ e0->bundle[ABOVE][CLIP])
  1515.               ^ (in[SUBJ] ^ e1->bundle[ABOVE][SUBJ] ^ e0->bundle[ABOVE][SUBJ]);
  1516.             break;
  1517.           case GPC_UNION:
  1518.             tr= (in[CLIP])
  1519.              || (in[SUBJ]);
  1520.             tl= (in[CLIP] ^ e1->bundle[ABOVE][CLIP])
  1521.              || (in[SUBJ] ^ e1->bundle[ABOVE][SUBJ]);
  1522.             br= (in[CLIP] ^ e0->bundle[ABOVE][CLIP])
  1523.              || (in[SUBJ] ^ e0->bundle[ABOVE][SUBJ]);
  1524.             bl= (in[CLIP] ^ e1->bundle[ABOVE][CLIP] ^ e0->bundle[ABOVE][CLIP])
  1525.              || (in[SUBJ] ^ e1->bundle[ABOVE][SUBJ] ^ e0->bundle[ABOVE][SUBJ]);
  1526.             break;
  1527.           }
  1528.      
  1529.           vclass= tr + (tl << 1) + (br << 2) + (bl << 3);
  1530.  
  1531.           switch (vclass)
  1532.           {
  1533.           case EMN:
  1534.             add_local_min(&out_poly, e0, ix, iy);
  1535.             e1->outp[ABOVE]= e0->outp[ABOVE];
  1536.             break;
  1537.           case ERI:
  1538.             if (p)
  1539.             {
  1540.               add_right(p, ix, iy);
  1541.               e1->outp[ABOVE]= p;
  1542.               e0->outp[ABOVE]= NULL;
  1543.             }
  1544.             break;
  1545.           case ELI:
  1546.             if (q)
  1547.             {
  1548.               add_left(q, ix, iy);
  1549.               e0->outp[ABOVE]= q;
  1550.               e1->outp[ABOVE]= NULL;
  1551.             }
  1552.             break;
  1553.           case EMX:
  1554.             if (p && q)
  1555.             {
  1556.               add_left(p, ix, iy);
  1557.               merge_right(p, q, out_poly);
  1558.               e0->outp[ABOVE]= NULL;
  1559.               e1->outp[ABOVE]= NULL;
  1560.             }
  1561.             break;
  1562.           case IMN:
  1563.             add_local_min(&out_poly, e0, ix, iy);
  1564.             e1->outp[ABOVE]= e0->outp[ABOVE];
  1565.             break;
  1566.           case ILI:
  1567.             if (p)
  1568.             {
  1569.               add_left(p, ix, iy);
  1570.               e1->outp[ABOVE]= p;
  1571.               e0->outp[ABOVE]= NULL;
  1572.             }
  1573.             break;
  1574.           case IRI:
  1575.             if (q)
  1576.             {
  1577.               add_right(q, ix, iy);
  1578.               e0->outp[ABOVE]= q;
  1579.               e1->outp[ABOVE]= NULL;
  1580.             }
  1581.             break;
  1582.           case IMX:
  1583.             if (p && q)
  1584.             {
  1585.               add_right(p, ix, iy);
  1586.               merge_left(p, q, out_poly);
  1587.               e0->outp[ABOVE]= NULL;
  1588.               e1->outp[ABOVE]= NULL;
  1589.             }
  1590.             break;
  1591.           case IMM:
  1592.             if (p && q)
  1593.             {
  1594.               add_right(p, ix, iy);
  1595.               merge_left(p, q, out_poly);
  1596.               add_local_min(&out_poly, e0, ix, iy);
  1597.               e1->outp[ABOVE]= e0->outp[ABOVE];
  1598.             }
  1599.             break;
  1600.           case EMM:
  1601.             if (p && q)
  1602.             {
  1603.               add_left(p, ix, iy);
  1604.               merge_right(p, q, out_poly);
  1605.               add_local_min(&out_poly, e0, ix, iy);
  1606.               e1->outp[ABOVE]= e0->outp[ABOVE];
  1607.             }
  1608.             break;
  1609.           default:
  1610.             break;
  1611.           } /* End of switch */
  1612.     } /* End of contributing intersection conditional */
  1613.  
  1614.         /* Swap bundle sides in response to edge crossing */
  1615.         if (e0->bundle[ABOVE][CLIP])
  1616.       e1->bside[CLIP]= !e1->bside[CLIP];
  1617.         if (e1->bundle[ABOVE][CLIP])
  1618.       e0->bside[CLIP]= !e0->bside[CLIP];
  1619.         if (e0->bundle[ABOVE][SUBJ])
  1620.       e1->bside[SUBJ]= !e1->bside[SUBJ];
  1621.         if (e1->bundle[ABOVE][SUBJ])
  1622.       e0->bside[SUBJ]= !e0->bside[SUBJ];
  1623.  
  1624.         /* Swap e0 and e1 bundles in the AET */
  1625.         prev_edge= e0->prev;
  1626.         next_edge= e1->next;
  1627.         if (next_edge)
  1628.           next_edge->prev= e0;
  1629.  
  1630.         if (e0->bstate[ABOVE] == BUNDLE_HEAD)
  1631.         {
  1632.           search= TRUE;
  1633.           while (search)
  1634.           {
  1635.             prev_edge= prev_edge->prev;
  1636.             if (prev_edge)
  1637.             {
  1638.               if (prev_edge->bstate[ABOVE] != BUNDLE_TAIL)
  1639.                 search= FALSE;
  1640.             }
  1641.             else
  1642.               search= FALSE;
  1643.           }
  1644.         }
  1645.         if (!prev_edge)
  1646.         {
  1647.           aet->prev= e1;
  1648.           e1->next= aet;
  1649.           aet= e0->next;
  1650.         }
  1651.         else
  1652.         {
  1653.           prev_edge->next->prev= e1;
  1654.           e1->next= prev_edge->next;
  1655.           prev_edge->next= e0->next;
  1656.         }
  1657.         e0->next->prev= prev_edge;
  1658.         e1->next->prev= e1;
  1659.         e0->next= next_edge;
  1660.       } /* End of IT loop*/
  1661.  
  1662.       /* Prepare for next scanbeam */
  1663.       for (edge= aet; edge; edge= next_edge)
  1664.       {
  1665.         next_edge= edge->next;
  1666.         succ_edge= edge->succ;
  1667.  
  1668.         if ((edge->top.y == yt) && succ_edge)
  1669.         {
  1670.           /* Replace AET edge by its successor */
  1671.           succ_edge->outp[BELOW]= edge->outp[ABOVE];
  1672.           succ_edge->bstate[BELOW]= edge->bstate[ABOVE];
  1673.           succ_edge->bundle[BELOW][CLIP]= edge->bundle[ABOVE][CLIP];
  1674.           succ_edge->bundle[BELOW][SUBJ]= edge->bundle[ABOVE][SUBJ];
  1675.           prev_edge= edge->prev;
  1676.           if (prev_edge)
  1677.             prev_edge->next= succ_edge;
  1678.           else
  1679.             aet= succ_edge;
  1680.           if (next_edge)
  1681.             next_edge->prev= succ_edge;
  1682.           succ_edge->prev= prev_edge;
  1683.           succ_edge->next= next_edge;
  1684.         }
  1685.         else
  1686.         {
  1687.           /* Update this edge */
  1688.           edge->outp[BELOW]= edge->outp[ABOVE];
  1689.           edge->bstate[BELOW]= edge->bstate[ABOVE];
  1690.           edge->bundle[BELOW][CLIP]= edge->bundle[ABOVE][CLIP];
  1691.           edge->bundle[BELOW][SUBJ]= edge->bundle[ABOVE][SUBJ];
  1692.           edge->xb= edge->xt;
  1693.           }
  1694.         edge->outp[ABOVE]= NULL;
  1695.       }
  1696.     }
  1697.   } /* === END OF SCANBEAM PROCESSING ================================== */
  1698.  
  1699.   /* Generate result polygon from out_poly */
  1700.   result->contour= NULL;
  1701.   result->hole= NULL;
  1702.   result->num_contours= count_contours(out_poly);
  1703.   if (result->num_contours > 0)
  1704.   {
  1705.     MALLOC(result->hole, result->num_contours
  1706.            * sizeof(int), "hole flag table creation", int);
  1707.     MALLOC(result->contour, result->num_contours
  1708.            * sizeof(gpc_vertex_list), "contour creation", gpc_vertex_list);
  1709.  
  1710.     c= 0;
  1711.     for (poly= out_poly; poly; poly= npoly)
  1712.     {
  1713.       npoly= poly->next;
  1714.       if (poly->active)
  1715.       {
  1716.         result->hole[c]= poly->proxy->hole;
  1717.         result->contour[c].num_vertices= poly->active;
  1718.         MALLOC(result->contour[c].vertex,
  1719.           result->contour[c].num_vertices * sizeof(gpc_vertex),
  1720.           "vertex creation", gpc_vertex);
  1721.      
  1722.         v= result->contour[c].num_vertices - 1;
  1723.         for (vtx= poly->proxy->v[LEFT]; vtx; vtx= nv)
  1724.         {
  1725.           nv= vtx->next;
  1726.           result->contour[c].vertex[v].x= vtx->x;
  1727.           result->contour[c].vertex[v].y= vtx->y;
  1728.           FREE(vtx);
  1729.           v--;
  1730.         }
  1731.         c++;
  1732.       }
  1733.       FREE(poly);
  1734.     }
  1735.   }
  1736.   else
  1737.   {
  1738.     for (poly= out_poly; poly; poly= npoly)
  1739.     {
  1740.       npoly= poly->next;
  1741.       FREE(poly);
  1742.     }
  1743.   }
  1744.  
  1745.   /* Tidy up */
  1746.   reset_it(&it);
  1747.   reset_lmt(&lmt);
  1748.   FREE(c_heap);
  1749.   FREE(s_heap);
  1750.   FREE(sbt);
  1751. }
  1752.  
  1753.  
  1754. void gpc_free_tristrip(gpc_tristrip *t)
  1755. {
  1756.   int s;
  1757.  
  1758.   for (s= 0; s < t->num_strips; s++)
  1759.     FREE(t->strip[s].vertex);
  1760.   FREE(t->strip);
  1761.   t->num_strips= 0;
  1762. }
  1763.  
  1764.  
  1765. void gpc_polygon_to_tristrip(gpc_polygon *s, gpc_tristrip *t)
  1766. {
  1767.   gpc_polygon c;
  1768.  
  1769.   c.num_contours= 0;
  1770.   c.hole= NULL;
  1771.   c.contour= NULL;
  1772.   gpc_tristrip_clip(GPC_DIFF, s, &c, t);
  1773. }
  1774.  
  1775.  
  1776. void gpc_tristrip_clip(gpc_op op, gpc_polygon *subj, gpc_polygon *clip,
  1777.                        gpc_tristrip *result)
  1778. {
  1779.   sb_tree       *sbtree= NULL;
  1780.   it_node       *it= NULL, *intersect;
  1781.   edge_node     *edge, *prev_edge, *next_edge, *succ_edge, *e0, *e1;
  1782.   edge_node     *aet= NULL, *c_heap= NULL, *s_heap= NULL, *cf;
  1783.   lmt_node      *lmt= NULL, *local_min;
  1784.   polygon_node  *tlist= NULL, *tn, *tnn, *p, *q;
  1785.   vertex_node   *lt, *ltn, *rt, *rtn;
  1786.   h_state        horiz[2];
  1787.   vertex_type    cft;
  1788.   int            in[2], exists[2], parity[2]= {LEFT, LEFT};
  1789.   int            s, v, contributing, search, scanbeam= 0, sbt_entries= 0;
  1790.   int            vclass, bl, br, tl, tr;
  1791.   double        *sbt= NULL, xb, px, nx, yb, yt, dy, ix, iy;
  1792.  
  1793.   /* Test for trivial NULL result cases */
  1794.   if (((subj->num_contours == 0) && (clip->num_contours == 0))
  1795.    || ((subj->num_contours == 0) && ((op == GPC_INT) || (op == GPC_DIFF)))
  1796.    || ((clip->num_contours == 0) &&  (op == GPC_INT)))
  1797.   {
  1798.     result->num_strips= 0;
  1799.     result->strip= NULL;
  1800.     return;
  1801.   }
  1802.  
  1803.   /* Identify potentialy contributing contours */
  1804.   if (((op == GPC_INT) || (op == GPC_DIFF))
  1805.    && (subj->num_contours > 0) && (clip->num_contours > 0))
  1806.     minimax_test(subj, clip, op);
  1807.  
  1808.   /* Build LMT */
  1809.   if (subj->num_contours > 0)
  1810.     s_heap= build_lmt(&lmt, &sbtree, &sbt_entries, subj, SUBJ, op);
  1811.   if (clip->num_contours > 0)
  1812.     c_heap= build_lmt(&lmt, &sbtree, &sbt_entries, clip, CLIP, op);
  1813.  
  1814.   /* Return a NULL result if no contours contribute */
  1815.   if (lmt == NULL)
  1816.   {
  1817.     result->num_strips= 0;
  1818.     result->strip= NULL;
  1819.     reset_lmt(&lmt);
  1820.     FREE(s_heap);
  1821.     FREE(c_heap);
  1822.     return;
  1823.   }
  1824.  
  1825.   /* Build scanbeam table from scanbeam tree */
  1826.   MALLOC(sbt, sbt_entries * sizeof(double), "sbt creation", double);
  1827.   build_sbt(&scanbeam, sbt, sbtree);
  1828.   scanbeam= 0;
  1829.   free_sbtree(&sbtree);
  1830.  
  1831.   /* Invert clip polygon for difference operation */
  1832.   if (op == GPC_DIFF)
  1833.     parity[CLIP]= RIGHT;
  1834.  
  1835.   local_min= lmt;
  1836.  
  1837.   /* Process each scanbeam */
  1838.   while (scanbeam < sbt_entries)
  1839.   {
  1840.     /* Set yb and yt to the bottom and top of the scanbeam */
  1841.     yb= sbt[scanbeam++];
  1842.     if (scanbeam < sbt_entries)
  1843.     {
  1844.       yt= sbt[scanbeam];
  1845.       dy= yt - yb;
  1846.     }
  1847.  
  1848.     /* === SCANBEAM BOUNDARY PROCESSING ================================ */
  1849.  
  1850.     /* If LMT node corresponding to yb exists */
  1851.     if (local_min)
  1852.     {
  1853.       if (local_min->y == yb)
  1854.       {
  1855.         /* Add edges starting at this local minimum to the AET */
  1856.         for (edge= local_min->first_bound; edge; edge= edge->next_bound)
  1857.           add_edge_to_aet(&aet, edge, NULL);
  1858.  
  1859.         local_min= local_min->next;
  1860.       }
  1861.     }
  1862.  
  1863.     /* Set dummy previous x value */
  1864.     px= -DBL_MAX;
  1865.  
  1866.     /* Create bundles within AET */
  1867.     e0= aet;
  1868.     e1= aet;
  1869.  
  1870.     /* Set up bundle fields of first edge */
  1871.     aet->bundle[ABOVE][ aet->type]= (aet->top.y != yb);
  1872.     aet->bundle[ABOVE][!aet->type]= FALSE;
  1873.     aet->bstate[ABOVE]= UNBUNDLED;
  1874.  
  1875.     for (next_edge= aet->next; next_edge; next_edge= next_edge->next)
  1876.     {
  1877.       /* Set up bundle fields of next edge */
  1878.       next_edge->bundle[ABOVE][ next_edge->type]= (next_edge->top.y != yb);
  1879.       next_edge->bundle[ABOVE][!next_edge->type]= FALSE;
  1880.       next_edge->bstate[ABOVE]= UNBUNDLED;
  1881.  
  1882.       /* Bundle edges above the scanbeam boundary if they coincide */
  1883.       if (next_edge->bundle[ABOVE][next_edge->type])
  1884.       {
  1885.         if (EQ(e0->xb, next_edge->xb) && EQ(e0->dx, next_edge->dx)
  1886.      && (e0->top.y != yb))
  1887.         {
  1888.           next_edge->bundle[ABOVE][ next_edge->type]^=
  1889.             e0->bundle[ABOVE][ next_edge->type];
  1890.           next_edge->bundle[ABOVE][!next_edge->type]=
  1891.             e0->bundle[ABOVE][!next_edge->type];
  1892.           next_edge->bstate[ABOVE]= BUNDLE_HEAD;
  1893.           e0->bundle[ABOVE][CLIP]= FALSE;
  1894.           e0->bundle[ABOVE][SUBJ]= FALSE;
  1895.           e0->bstate[ABOVE]= BUNDLE_TAIL;
  1896.         }
  1897.         e0= next_edge;
  1898.       }
  1899.     }
  1900.  
  1901.     horiz[CLIP]= NH;
  1902.     horiz[SUBJ]= NH;
  1903.  
  1904.     /* Process each edge at this scanbeam boundary */
  1905.     for (edge= aet; edge; edge= edge->next)
  1906.     {
  1907.       exists[CLIP]= edge->bundle[ABOVE][CLIP] +
  1908.                    (edge->bundle[BELOW][CLIP] << 1);
  1909.       exists[SUBJ]= edge->bundle[ABOVE][SUBJ] +
  1910.                    (edge->bundle[BELOW][SUBJ] << 1);
  1911.  
  1912.       if (exists[CLIP] || exists[SUBJ])
  1913.       {
  1914.         /* Set bundle side */
  1915.         edge->bside[CLIP]= parity[CLIP];
  1916.         edge->bside[SUBJ]= parity[SUBJ];
  1917.  
  1918.         /* Determine contributing status and quadrant occupancies */
  1919.         switch (op)
  1920.         {
  1921.         case GPC_DIFF:
  1922.         case GPC_INT:
  1923.           contributing= (exists[CLIP] && (parity[SUBJ] || horiz[SUBJ]))
  1924.                      || (exists[SUBJ] && (parity[CLIP] || horiz[CLIP]))
  1925.                      || (exists[CLIP] && exists[SUBJ]
  1926.                      && (parity[CLIP] == parity[SUBJ]));
  1927.           br= (parity[CLIP])
  1928.            && (parity[SUBJ]);
  1929.           bl= (parity[CLIP] ^ edge->bundle[ABOVE][CLIP])
  1930.            && (parity[SUBJ] ^ edge->bundle[ABOVE][SUBJ]);
  1931.           tr= (parity[CLIP] ^ (horiz[CLIP]!=NH))
  1932.            && (parity[SUBJ] ^ (horiz[SUBJ]!=NH));
  1933.           tl= (parity[CLIP] ^ (horiz[CLIP]!=NH) ^ edge->bundle[BELOW][CLIP])
  1934.            && (parity[SUBJ] ^ (horiz[SUBJ]!=NH) ^ edge->bundle[BELOW][SUBJ]);
  1935.           break;
  1936.         case GPC_XOR:
  1937.           contributing= exists[CLIP] || exists[SUBJ];
  1938.           br= (parity[CLIP])
  1939.             ^ (parity[SUBJ]);
  1940.           bl= (parity[CLIP] ^ edge->bundle[ABOVE][CLIP])
  1941.             ^ (parity[SUBJ] ^ edge->bundle[ABOVE][SUBJ]);
  1942.           tr= (parity[CLIP] ^ (horiz[CLIP]!=NH))
  1943.             ^ (parity[SUBJ] ^ (horiz[SUBJ]!=NH));
  1944.           tl= (parity[CLIP] ^ (horiz[CLIP]!=NH) ^ edge->bundle[BELOW][CLIP])
  1945.             ^ (parity[SUBJ] ^ (horiz[SUBJ]!=NH) ^ edge->bundle[BELOW][SUBJ]);
  1946.           break;
  1947.         case GPC_UNION:
  1948.           contributing= (exists[CLIP] && (!parity[SUBJ] || horiz[SUBJ]))
  1949.                      || (exists[SUBJ] && (!parity[CLIP] || horiz[CLIP]))
  1950.                      || (exists[CLIP] && exists[SUBJ]
  1951.                      && (parity[CLIP] == parity[SUBJ]));
  1952.           br= (parity[CLIP])
  1953.            || (parity[SUBJ]);
  1954.           bl= (parity[CLIP] ^ edge->bundle[ABOVE][CLIP])
  1955.            || (parity[SUBJ] ^ edge->bundle[ABOVE][SUBJ]);
  1956.           tr= (parity[CLIP] ^ (horiz[CLIP]!=NH))
  1957.            || (parity[SUBJ] ^ (horiz[SUBJ]!=NH));
  1958.           tl= (parity[CLIP] ^ (horiz[CLIP]!=NH) ^ edge->bundle[BELOW][CLIP])
  1959.            || (parity[SUBJ] ^ (horiz[SUBJ]!=NH) ^ edge->bundle[BELOW][SUBJ]);
  1960.           break;
  1961.         }
  1962.  
  1963.         /* Update parity */
  1964.         parity[CLIP]^= edge->bundle[ABOVE][CLIP];
  1965.         parity[SUBJ]^= edge->bundle[ABOVE][SUBJ];
  1966.  
  1967.         /* Update horizontal state */
  1968.         if (exists[CLIP])        
  1969.           horiz[CLIP]=
  1970.             next_h_state[horiz[CLIP]]
  1971.                         [((exists[CLIP] - 1) << 1) + parity[CLIP]];
  1972.         if (exists[SUBJ])        
  1973.           horiz[SUBJ]=
  1974.             next_h_state[horiz[SUBJ]]
  1975.                         [((exists[SUBJ] - 1) << 1) + parity[SUBJ]];
  1976.        
  1977.         vclass= tr + (tl << 1) + (br << 2) + (bl << 3);
  1978.  
  1979.         if (contributing)
  1980.         {
  1981.           xb= edge->xb;
  1982.  
  1983.           switch (vclass)
  1984.           {
  1985.           case EMN:
  1986.             new_tristrip(&tlist, edge, xb, yb);
  1987.             cf= edge;
  1988.             break;
  1989.           case ERI:
  1990.             edge->outp[ABOVE]= cf->outp[ABOVE];
  1991.             if (xb != cf->xb)
  1992.               VERTEX(edge, ABOVE, RIGHT, xb, yb);
  1993.             cf= NULL;
  1994.             break;
  1995.           case ELI:
  1996.             VERTEX(edge, BELOW, LEFT, xb, yb);
  1997.             edge->outp[ABOVE]= NULL;
  1998.             cf= edge;
  1999.             break;
  2000.           case EMX:
  2001.             if (xb != cf->xb)
  2002.               VERTEX(edge, BELOW, RIGHT, xb, yb);
  2003.             edge->outp[ABOVE]= NULL;
  2004.             cf= NULL;
  2005.             break;
  2006.           case IMN:
  2007.             if (cft == LED)
  2008.         {
  2009.               if (cf->bot.y != yb)
  2010.                 VERTEX(cf, BELOW, LEFT, cf->xb, yb);
  2011.               new_tristrip(&tlist, cf, cf->xb, yb);
  2012.         }
  2013.             edge->outp[ABOVE]= cf->outp[ABOVE];
  2014.             VERTEX(edge, ABOVE, RIGHT, xb, yb);
  2015.             break;
  2016.           case ILI:
  2017.             new_tristrip(&tlist, edge, xb, yb);
  2018.             cf= edge;
  2019.             cft= ILI;
  2020.             break;
  2021.           case IRI:
  2022.             if (cft == LED)
  2023.         {
  2024.               if (cf->bot.y != yb)
  2025.                 VERTEX(cf, BELOW, LEFT, cf->xb, yb);
  2026.               new_tristrip(&tlist, cf, cf->xb, yb);
  2027.         }
  2028.             VERTEX(edge, BELOW, RIGHT, xb, yb);
  2029.             edge->outp[ABOVE]= NULL;
  2030.             break;
  2031.           case IMX:
  2032.             VERTEX(edge, BELOW, LEFT, xb, yb);
  2033.             edge->outp[ABOVE]= NULL;
  2034.             cft= IMX;
  2035.             break;
  2036.       case IMM:
  2037.             VERTEX(edge, BELOW, LEFT, xb, yb);
  2038.             edge->outp[ABOVE]= cf->outp[ABOVE];
  2039.             if (xb != cf->xb)
  2040.               VERTEX(cf, ABOVE, RIGHT, xb, yb);
  2041.             cf= edge;
  2042.             break;
  2043.           case EMM:
  2044.             VERTEX(edge, BELOW, RIGHT, xb, yb);
  2045.             edge->outp[ABOVE]= NULL;
  2046.             new_tristrip(&tlist, edge, xb, yb);
  2047.             cf= edge;
  2048.             break;
  2049.           case LED:
  2050.             if (edge->bot.y == yb)
  2051.               VERTEX(edge, BELOW, LEFT, xb, yb);
  2052.             edge->outp[ABOVE]= edge->outp[BELOW];
  2053.             cf= edge;
  2054.             cft= LED;
  2055.             break;
  2056.           case RED:
  2057.             edge->outp[ABOVE]= cf->outp[ABOVE];
  2058.             if (cft == LED)
  2059.         {
  2060.               if (cf->bot.y == yb)
  2061.           {
  2062.                 VERTEX(edge, BELOW, RIGHT, xb, yb);
  2063.           }
  2064.               else
  2065.           {
  2066.                 if (edge->bot.y == yb)
  2067.         {
  2068.                   VERTEX(cf, BELOW, LEFT, cf->xb, yb);
  2069.                   VERTEX(edge, BELOW, RIGHT, xb, yb);
  2070.         }
  2071.           }
  2072.         }
  2073.             else
  2074.         {
  2075.               VERTEX(edge, BELOW, RIGHT, xb, yb);
  2076.               VERTEX(edge, ABOVE, RIGHT, xb, yb);
  2077.         }
  2078.             cf= NULL;
  2079.             break;
  2080.           default:
  2081.             break;
  2082.           } /* End of switch */
  2083.         } /* End of contributing conditional */
  2084.       } /* End of edge exists conditional */
  2085.     } /* End of AET loop */
  2086.  
  2087.     /* Delete terminating edges from the AET, otherwise compute xt */
  2088.     for (edge= aet; edge; edge= edge->next)
  2089.     {
  2090.       if (edge->top.y == yb)
  2091.       {
  2092.         prev_edge= edge->prev;
  2093.         next_edge= edge->next;
  2094.         if (prev_edge)
  2095.           prev_edge->next= next_edge;
  2096.         else
  2097.           aet= next_edge;
  2098.         if (next_edge)
  2099.           next_edge->prev= prev_edge;
  2100.  
  2101.         /* Copy bundle head state to the adjacent tail edge if required */
  2102.         if ((edge->bstate[BELOW] == BUNDLE_HEAD) && prev_edge)
  2103.     {
  2104.           if (prev_edge->bstate[BELOW] == BUNDLE_TAIL)
  2105.           {
  2106.             prev_edge->outp[BELOW]= edge->outp[BELOW];
  2107.             prev_edge->bstate[BELOW]= UNBUNDLED;
  2108.             if (prev_edge->prev)
  2109.               if (prev_edge->prev->bstate[BELOW] == BUNDLE_TAIL)
  2110.                 prev_edge->bstate[BELOW]= BUNDLE_HEAD;
  2111.       }
  2112.     }
  2113.       }
  2114.       else
  2115.       {
  2116.         if (edge->top.y == yt)
  2117.           edge->xt= edge->top.x;
  2118.         else
  2119.           edge->xt= edge->bot.x + edge->dx * (yt - edge->bot.y);
  2120.       }
  2121.     }
  2122.  
  2123.     if (scanbeam < sbt_entries)
  2124.     {
  2125.       /* === SCANBEAM INTERIOR PROCESSING ============================== */
  2126.  
  2127.       build_intersection_table(&it, aet, dy);
  2128.  
  2129.       /* Process each node in the intersection table */
  2130.       for (intersect= it; intersect; intersect= intersect->next)
  2131.       {
  2132.         e0= intersect->ie[0];
  2133.         e1= intersect->ie[1];
  2134.  
  2135.         /* Only generate output for contributing intersections */
  2136.         if ((e0->bundle[ABOVE][CLIP] || e0->bundle[ABOVE][SUBJ])
  2137.          && (e1->bundle[ABOVE][CLIP] || e1->bundle[ABOVE][SUBJ]))
  2138.     {
  2139.           p= e0->outp[ABOVE];
  2140.           q= e1->outp[ABOVE];
  2141.           ix= intersect->point.x;
  2142.           iy= intersect->point.y + yb;
  2143.  
  2144.           in[CLIP]= ( e0->bundle[ABOVE][CLIP] && !e0->bside[CLIP])
  2145.                  || ( e1->bundle[ABOVE][CLIP] &&  e1->bside[CLIP])
  2146.                  || (!e0->bundle[ABOVE][CLIP] && !e1->bundle[ABOVE][CLIP]
  2147.                      && e0->bside[CLIP] && e1->bside[CLIP]);
  2148.           in[SUBJ]= ( e0->bundle[ABOVE][SUBJ] && !e0->bside[SUBJ])
  2149.                  || ( e1->bundle[ABOVE][SUBJ] &&  e1->bside[SUBJ])
  2150.                  || (!e0->bundle[ABOVE][SUBJ] && !e1->bundle[ABOVE][SUBJ]
  2151.                      && e0->bside[SUBJ] && e1->bside[SUBJ]);
  2152.  
  2153.           /* Determine quadrant occupancies */
  2154.           switch (op)
  2155.           {
  2156.           case GPC_DIFF:
  2157.           case GPC_INT:
  2158.             tr= (in[CLIP])
  2159.              && (in[SUBJ]);
  2160.             tl= (in[CLIP] ^ e1->bundle[ABOVE][CLIP])
  2161.              && (in[SUBJ] ^ e1->bundle[ABOVE][SUBJ]);
  2162.             br= (in[CLIP] ^ e0->bundle[ABOVE][CLIP])
  2163.              && (in[SUBJ] ^ e0->bundle[ABOVE][SUBJ]);
  2164.             bl= (in[CLIP] ^ e1->bundle[ABOVE][CLIP] ^ e0->bundle[ABOVE][CLIP])
  2165.              && (in[SUBJ] ^ e1->bundle[ABOVE][SUBJ] ^ e0->bundle[ABOVE][SUBJ]);
  2166.             break;
  2167.           case GPC_XOR:
  2168.             tr= (in[CLIP])
  2169.               ^ (in[SUBJ]);
  2170.             tl= (in[CLIP] ^ e1->bundle[ABOVE][CLIP])
  2171.               ^ (in[SUBJ] ^ e1->bundle[ABOVE][SUBJ]);
  2172.             br= (in[CLIP] ^ e0->bundle[ABOVE][CLIP])
  2173.               ^ (in[SUBJ] ^ e0->bundle[ABOVE][SUBJ]);
  2174.             bl= (in[CLIP] ^ e1->bundle[ABOVE][CLIP] ^ e0->bundle[ABOVE][CLIP])
  2175.               ^ (in[SUBJ] ^ e1->bundle[ABOVE][SUBJ] ^ e0->bundle[ABOVE][SUBJ]);
  2176.             break;
  2177.           case GPC_UNION:
  2178.             tr= (in[CLIP])
  2179.              || (in[SUBJ]);
  2180.             tl= (in[CLIP] ^ e1->bundle[ABOVE][CLIP])
  2181.              || (in[SUBJ] ^ e1->bundle[ABOVE][SUBJ]);
  2182.             br= (in[CLIP] ^ e0->bundle[ABOVE][CLIP])
  2183.              || (in[SUBJ] ^ e0->bundle[ABOVE][SUBJ]);
  2184.             bl= (in[CLIP] ^ e1->bundle[ABOVE][CLIP] ^ e0->bundle[ABOVE][CLIP])
  2185.              || (in[SUBJ] ^ e1->bundle[ABOVE][SUBJ] ^ e0->bundle[ABOVE][SUBJ]);
  2186.             break;
  2187.           }
  2188.  
  2189.           vclass= tr + (tl << 1) + (br << 2) + (bl << 3);
  2190.  
  2191.           switch (vclass)
  2192.           {
  2193.           case EMN:
  2194.             new_tristrip(&tlist, e1, ix, iy);
  2195.             e0->outp[ABOVE]= e1->outp[ABOVE];
  2196.             break;
  2197.           case ERI:
  2198.             if (p)
  2199.             {
  2200.               P_EDGE(prev_edge, e0, ABOVE, px, iy);
  2201.               VERTEX(prev_edge, ABOVE, LEFT, px, iy);
  2202.               VERTEX(e0, ABOVE, RIGHT, ix, iy);
  2203.               e1->outp[ABOVE]= e0->outp[ABOVE];
  2204.               e0->outp[ABOVE]= NULL;
  2205.             }
  2206.             break;
  2207.           case ELI:
  2208.             if (q)
  2209.             {
  2210.               N_EDGE(next_edge, e1, ABOVE, nx, iy);
  2211.               VERTEX(e1, ABOVE, LEFT, ix, iy);
  2212.               VERTEX(next_edge, ABOVE, RIGHT, nx, iy);
  2213.               e0->outp[ABOVE]= e1->outp[ABOVE];
  2214.               e1->outp[ABOVE]= NULL;
  2215.             }
  2216.             break;
  2217.           case EMX:
  2218.             if (p && q)
  2219.             {
  2220.               VERTEX(e0, ABOVE, LEFT, ix, iy);
  2221.               e0->outp[ABOVE]= NULL;
  2222.               e1->outp[ABOVE]= NULL;
  2223.             }
  2224.             break;
  2225.           case IMN:
  2226.             P_EDGE(prev_edge, e0, ABOVE, px, iy);
  2227.             VERTEX(prev_edge, ABOVE, LEFT, px, iy);
  2228.             N_EDGE(next_edge, e1, ABOVE, nx, iy);
  2229.             VERTEX(next_edge, ABOVE, RIGHT, nx, iy);
  2230.             new_tristrip(&tlist, prev_edge, px, iy);
  2231.             e1->outp[ABOVE]= prev_edge->outp[ABOVE];
  2232.             VERTEX(e1, ABOVE, RIGHT, ix, iy);
  2233.             new_tristrip(&tlist, e0, ix, iy);
  2234.             next_edge->outp[ABOVE]= e0->outp[ABOVE];
  2235.             VERTEX(next_edge, ABOVE, RIGHT, nx, iy);
  2236.             break;
  2237.           case ILI:
  2238.             if (p)
  2239.             {
  2240.               VERTEX(e0, ABOVE, LEFT, ix, iy);
  2241.               N_EDGE(next_edge, e1, ABOVE, nx, iy);
  2242.               VERTEX(next_edge, ABOVE, RIGHT, nx, iy);
  2243.               e1->outp[ABOVE]= e0->outp[ABOVE];
  2244.               e0->outp[ABOVE]= NULL;
  2245.             }
  2246.             break;
  2247.           case IRI:
  2248.             if (q)
  2249.             {
  2250.               VERTEX(e1, ABOVE, RIGHT, ix, iy);
  2251.               P_EDGE(prev_edge, e0, ABOVE, px, iy);
  2252.               VERTEX(prev_edge, ABOVE, LEFT, px, iy);
  2253.               e0->outp[ABOVE]= e1->outp[ABOVE];
  2254.               e1->outp[ABOVE]= NULL;
  2255.             }
  2256.             break;
  2257.           case IMX:
  2258.             if (p && q)
  2259.             {
  2260.               VERTEX(e0, ABOVE, RIGHT, ix, iy);
  2261.               VERTEX(e1, ABOVE, LEFT, ix, iy);
  2262.               e0->outp[ABOVE]= NULL;
  2263.               e1->outp[ABOVE]= NULL;
  2264.               P_EDGE(prev_edge, e0, ABOVE, px, iy);
  2265.               VERTEX(prev_edge, ABOVE, LEFT, px, iy);
  2266.               new_tristrip(&tlist, prev_edge, px, iy);
  2267.               N_EDGE(next_edge, e1, ABOVE, nx, iy);
  2268.               VERTEX(next_edge, ABOVE, RIGHT, nx, iy);
  2269.               next_edge->outp[ABOVE]= prev_edge->outp[ABOVE];
  2270.               VERTEX(next_edge, ABOVE, RIGHT, nx, iy);
  2271.             }
  2272.             break;
  2273.           case IMM:
  2274.             if (p && q)
  2275.             {
  2276.               VERTEX(e0, ABOVE, RIGHT, ix, iy);
  2277.               VERTEX(e1, ABOVE, LEFT, ix, iy);
  2278.               P_EDGE(prev_edge, e0, ABOVE, px, iy);
  2279.               VERTEX(prev_edge, ABOVE, LEFT, px, iy);
  2280.               new_tristrip(&tlist, prev_edge, px, iy);
  2281.               N_EDGE(next_edge, e1, ABOVE, nx, iy);
  2282.               VERTEX(next_edge, ABOVE, RIGHT, nx, iy);
  2283.               e1->outp[ABOVE]= prev_edge->outp[ABOVE];
  2284.               VERTEX(e1, ABOVE, RIGHT, ix, iy);
  2285.               new_tristrip(&tlist, e0, ix, iy);
  2286.               next_edge->outp[ABOVE]= e0->outp[ABOVE];
  2287.               VERTEX(next_edge, ABOVE, RIGHT, nx, iy);
  2288.             }
  2289.             break;
  2290.           case EMM:
  2291.             if (p && q)
  2292.             {
  2293.               VERTEX(e0, ABOVE, LEFT, ix, iy);
  2294.               new_tristrip(&tlist, e1, ix, iy);
  2295.               e0->outp[ABOVE]= e1->outp[ABOVE];
  2296.             }
  2297.             break;
  2298.           default:
  2299.             break;
  2300.           } /* End of switch */
  2301.     } /* End of contributing intersection conditional */
  2302.  
  2303.         /* Swap bundle sides in response to edge crossing */
  2304.         if (e0->bundle[ABOVE][CLIP])
  2305.       e1->bside[CLIP]= !e1->bside[CLIP];
  2306.         if (e1->bundle[ABOVE][CLIP])
  2307.       e0->bside[CLIP]= !e0->bside[CLIP];
  2308.         if (e0->bundle[ABOVE][SUBJ])
  2309.       e1->bside[SUBJ]= !e1->bside[SUBJ];
  2310.         if (e1->bundle[ABOVE][SUBJ])
  2311.       e0->bside[SUBJ]= !e0->bside[SUBJ];
  2312.  
  2313.         /* Swap e0 and e1 bundles in the AET */
  2314.         prev_edge= e0->prev;
  2315.         next_edge= e1->next;
  2316.         if (e1->next)
  2317.           e1->next->prev= e0;
  2318.  
  2319.         if (e0->bstate[ABOVE] == BUNDLE_HEAD)
  2320.         {
  2321.           search= TRUE;
  2322.           while (search)
  2323.           {
  2324.             prev_edge= prev_edge->prev;
  2325.             if (prev_edge)
  2326.             {
  2327.               if (prev_edge->bundle[ABOVE][CLIP]
  2328.                || prev_edge->bundle[ABOVE][SUBJ]
  2329.                || (prev_edge->bstate[ABOVE] == BUNDLE_HEAD))
  2330.                 search= FALSE;
  2331.             }
  2332.             else
  2333.               search= FALSE;
  2334.           }
  2335.         }
  2336.         if (!prev_edge)
  2337.         {
  2338.            e1->next= aet;
  2339.            aet= e0->next;
  2340.         }
  2341.         else
  2342.         {
  2343.           e1->next= prev_edge->next;
  2344.           prev_edge->next= e0->next;
  2345.         }
  2346.         e0->next->prev= prev_edge;
  2347.         e1->next->prev= e1;
  2348.         e0->next= next_edge;
  2349.       } /* End of IT loop*/
  2350.  
  2351.       /* Prepare for next scanbeam */
  2352.       for (edge= aet; edge; edge= next_edge)
  2353.       {
  2354.         next_edge= edge->next;
  2355.         succ_edge= edge->succ;
  2356.  
  2357.         if ((edge->top.y == yt) && succ_edge)
  2358.         {
  2359.           /* Replace AET edge by its successor */
  2360.           succ_edge->outp[BELOW]= edge->outp[ABOVE];
  2361.           succ_edge->bstate[BELOW]= edge->bstate[ABOVE];
  2362.           succ_edge->bundle[BELOW][CLIP]= edge->bundle[ABOVE][CLIP];
  2363.           succ_edge->bundle[BELOW][SUBJ]= edge->bundle[ABOVE][SUBJ];
  2364.           prev_edge= edge->prev;
  2365.           if (prev_edge)
  2366.             prev_edge->next= succ_edge;
  2367.           else
  2368.             aet= succ_edge;
  2369.           if (next_edge)
  2370.             next_edge->prev= succ_edge;
  2371.           succ_edge->prev= prev_edge;
  2372.           succ_edge->next= next_edge;
  2373.         }
  2374.         else
  2375.         {
  2376.           /* Update this edge */
  2377.           edge->outp[BELOW]= edge->outp[ABOVE];
  2378.           edge->bstate[BELOW]= edge->bstate[ABOVE];
  2379.           edge->bundle[BELOW][CLIP]= edge->bundle[ABOVE][CLIP];
  2380.           edge->bundle[BELOW][SUBJ]= edge->bundle[ABOVE][SUBJ];
  2381.           edge->xb= edge->xt;
  2382.         }
  2383.         edge->outp[ABOVE]= NULL;
  2384.       }
  2385.     }
  2386.   } /* === END OF SCANBEAM PROCESSING ================================== */
  2387.  
  2388.   /* Generate result tristrip from tlist */
  2389.   result->strip= NULL;
  2390.   result->num_strips= count_tristrips(tlist);
  2391.   if (result->num_strips > 0)
  2392.   {
  2393.     MALLOC(result->strip, result->num_strips * sizeof(gpc_vertex_list),
  2394.            "tristrip list creation", gpc_vertex_list);
  2395.  
  2396.     s= 0;
  2397.     for (tn= tlist; tn; tn= tnn)
  2398.     {
  2399.       tnn= tn->next;
  2400.  
  2401.       if (tn->active > 2)
  2402.       {
  2403.         /* Valid tristrip: copy the vertices and free the heap */
  2404.         result->strip[s].num_vertices= tn->active;
  2405.         MALLOC(result->strip[s].vertex, tn->active * sizeof(gpc_vertex),
  2406.                "tristrip creation", gpc_vertex);
  2407.         v= 0;
  2408.         if (INVERT_TRISTRIPS)
  2409.         {
  2410.           lt= tn->v[RIGHT];
  2411.           rt= tn->v[LEFT];
  2412.         }
  2413.         else
  2414.         {
  2415.           lt= tn->v[LEFT];
  2416.           rt= tn->v[RIGHT];
  2417.         }
  2418.         while (lt || rt)
  2419.         {
  2420.           if (lt)
  2421.           {
  2422.             ltn= lt->next;
  2423.             result->strip[s].vertex[v].x= lt->x;
  2424.             result->strip[s].vertex[v].y= lt->y;
  2425.             v++;
  2426.             FREE(lt);
  2427.             lt= ltn;
  2428.           }
  2429.           if (rt)
  2430.           {
  2431.             rtn= rt->next;
  2432.             result->strip[s].vertex[v].x= rt->x;
  2433.             result->strip[s].vertex[v].y= rt->y;
  2434.             v++;
  2435.             FREE(rt);
  2436.             rt= rtn;
  2437.           }
  2438.         }
  2439.         s++;
  2440.       }
  2441.       else
  2442.       {
  2443.         /* Invalid tristrip: just free the heap */
  2444.         for (lt= tn->v[LEFT]; lt; lt= ltn)
  2445.         {
  2446.           ltn= lt->next;
  2447.           FREE(lt);
  2448.         }
  2449.         for (rt= tn->v[RIGHT]; rt; rt=rtn)
  2450.         {
  2451.           rtn= rt->next;
  2452.           FREE(rt);
  2453.         }
  2454.       }
  2455.       FREE(tn);
  2456.     }
  2457.   }
  2458.  
  2459.   /* Tidy up */
  2460.   reset_it(&it);
  2461.   reset_lmt(&lmt);
  2462.   FREE(c_heap);
  2463.   FREE(s_heap);
  2464.   FREE(sbt);
  2465. }
  2466.  
  2467. /*
  2468. ===========================================================================
  2469.                            TCL compatibility functions
  2470. ===========================================================================
  2471. */
  2472.  
  2473. gpc_vertex_list gpc_vertex_list_make(int n) {
  2474.     gpc_vertex_list result;
  2475.     result.num_vertices=n;
  2476.     result.vertex = malloc(sizeof(gpc_vertex)*n);
  2477.     return result;
  2478. }
  2479.  
  2480. gpc_polygon * gpc_polygon_empty_make() {
  2481.     gpc_polygon *p = (gpc_polygon *)malloc(sizeof(gpc_polygon));
  2482.     if (p) {
  2483.         p->num_contours = 0;
  2484.         p->contour = NULL;
  2485.         p->hole = NULL;
  2486.     }
  2487.     return p;
  2488. }
  2489.  
  2490. int gpc_polygon_num_get(gpc_polygon *polygon) {
  2491.     return polygon->num_contours;
  2492. }
  2493.  
  2494. gpc_vertex_list gpc_polygon_vertex_list_get(gpc_polygon *polygon, int n) {
  2495.     gpc_vertex_list *result;
  2496.     result = polygon->contour;
  2497.     return result[n];
  2498. }
  2499.  
  2500. void gpc_vertex_set(gpc_vertex_list *list, int n, double x, double y) {
  2501.     if (n < 0 || n >= list->num_vertices) {
  2502.         // throw error. This is painful if not using C++
  2503.         // so I simply ignore it here
  2504.     } else {
  2505.         list->vertex[n].x = x;
  2506.         list->vertex[n].y = y;
  2507.     }
  2508. }
  2509.  
  2510. void gpc_vertex_get(gpc_vertex_list *list, int n, double *x, double *y) {
  2511.     if (n < 0 || n >= list->num_vertices) {
  2512.         // throw error. This is painful if not using C++
  2513.         // so I simply ignore it here
  2514.         *x=NAN;
  2515.         *y=NAN;
  2516.     } else {
  2517.         *x=list->vertex[n].x;
  2518.         *y=list->vertex[n].y;
  2519.     }
  2520. }
  2521.  
  2522. int gpc_vertex_num_get(gpc_vertex_list *list) {
  2523.     return list->num_vertices;
  2524. }
  2525.  
  2526. int gpc_write_polygon_tcl(const char *filename, gpc_polygon *polygon) {
  2527.     FILE *f;
  2528.     f = fopen(filename, "w");
  2529.     if (!f) {
  2530.         return 0;
  2531.     } else {   
  2532.         gpc_write_polygon(f, 1, polygon);
  2533.         fclose(f);
  2534.         return 1;
  2535.     }
  2536. }
  2537.  
  2538. /*
  2539. ===========================================================================
  2540.          functions taken from https://github.com/jraedler/Polygon3
  2541. ===========================================================================
  2542. */
  2543.  
  2544. // Rotates the polygon by angle a around center point in ccw direction.
  2545. // If no center is given the center point of the bounding box is used.
  2546. void gpc_polygon_rotate(gpc_polygon *p, double alpha, double xc, double yc) {
  2547.   int i, j;
  2548.   double x, y, l, a;
  2549.   gpc_vertex_list *vl;
  2550.   for (i=0; i < p->num_contours; i++) {
  2551.     vl = p->contour+i;
  2552.     for (j=0; j < vl->num_vertices; j++) {
  2553.       x = vl->vertex[j].x - xc;
  2554.       y = vl->vertex[j].y - yc;
  2555.       l = sqrt(x*x + y*y);
  2556.       a = alpha + ((l != 0.0) ? acos(x/l) *
  2557.                    ((y>0.0) ? 1.0 : -1.0) : 0.0);
  2558.       vl->vertex[j].x = xc + l * cos(a);
  2559.       vl->vertex[j].y = yc + l * sin(a);
  2560.     }
  2561.   }
  2562. }
  2563.  
  2564. // Scales the polygon by multiplying with xs and ys around the center point.
  2565. // If no center is given the center point of the bounding box is used, which
  2566. // will not be changed by this operation.
  2567. void gpc_polygon_scale(gpc_polygon *p, double xs, double ys, double xc, double yc) {
  2568.   int i, j;
  2569.   gpc_vertex_list *vl;
  2570.   for (i=0; i < p->num_contours; i++) {
  2571.     vl = p->contour+i;
  2572.     for (j=0; j < vl->num_vertices; j++) {
  2573.       vl->vertex[j].x = xc + xs * (vl->vertex[j].x - xc);
  2574.       vl->vertex[j].y = yc + ys * (vl->vertex[j].y - yc);
  2575.     }
  2576.   }
  2577. }
  2578.  
  2579. // Shifts the polygon by adding x and y.
  2580. void gpc_polygon_shift(gpc_polygon *p, double x, double y) {
  2581.   int i, j;
  2582.   gpc_vertex_list *vl;
  2583.   for (i=0; i < p->num_contours; i++) {
  2584.     vl = p->contour+i;
  2585.     for (j=0; j < vl->num_vertices; j++) {
  2586.       vl->vertex[j].x += x;
  2587.       vl->vertex[j].y += y;
  2588.     }
  2589.   }
  2590. }
  2591.  
  2592.  
  2593. /*
  2594. ===========================================================================
  2595.                            End of file: gpc.c
  2596. ===========================================================================
  2597. */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement