triangulator.cxx
00001 // Filename: triangulator.cxx
00002 // Created by:  drose (18Jan07)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 #include "triangulator.h"
00016 #include "randomizer.h"
00017 
00018 ////////////////////////////////////////////////////////////////////
00019 //     Function: Triangulator::Constructor
00020 //       Access: Published
00021 //  Description: 
00022 ////////////////////////////////////////////////////////////////////
00023 Triangulator::
00024 Triangulator() {
00025 }
00026 
00027 ////////////////////////////////////////////////////////////////////
00028 //     Function: Triangulator::clear
00029 //       Access: Published
00030 //  Description: Removes all vertices and polygon specifications from
00031 //               the Triangulator, and prepares it to start over.
00032 ////////////////////////////////////////////////////////////////////
00033 void Triangulator::
00034 clear() {
00035   _vertices.clear();
00036   clear_polygon();
00037 }
00038 
00039 ////////////////////////////////////////////////////////////////////
00040 //     Function: Triangulator::add_vertex
00041 //       Access: Published
00042 //  Description: Adds a new vertex to the vertex pool.  Returns the
00043 //               vertex index number.
00044 ////////////////////////////////////////////////////////////////////
00045 int Triangulator::
00046 add_vertex(const LPoint2d &point) {
00047   int index = (int)_vertices.size();
00048   _vertices.push_back(point);
00049   return index;
00050 }
00051 
00052 ////////////////////////////////////////////////////////////////////
00053 //     Function: Triangulator::clear_polygon
00054 //       Access: Published
00055 //  Description: Removes the current polygon definition (and its set
00056 //               of holes), but does not clear the vertex pool.
00057 ////////////////////////////////////////////////////////////////////
00058 void Triangulator::
00059 clear_polygon() {
00060   _polygon.clear();
00061   _holes.clear();
00062 }
00063 
00064 ////////////////////////////////////////////////////////////////////
00065 //     Function: Triangulator::add_polygon_vertex
00066 //       Access: Published
00067 //  Description: Adds the next consecutive vertex of the polygon.
00068 //               This vertex should index into the vertex pool
00069 //               established by repeated calls to add_vertex().
00070 //
00071 //               The vertices may be listed in either clockwise or
00072 //               counterclockwise order.  Vertices should not be
00073 //               repeated.  In particular, do not repeat the first
00074 //               vertex at the end.
00075 ////////////////////////////////////////////////////////////////////
00076 void Triangulator::
00077 add_polygon_vertex(int index) {
00078   _polygon.push_back(index);
00079 }
00080 
00081 ////////////////////////////////////////////////////////////////////
00082 //     Function: Triangulator::begin_hole
00083 //       Access: Published
00084 //  Description: Finishes the previous hole, if any, and prepares to
00085 //               add a new hole.
00086 ////////////////////////////////////////////////////////////////////
00087 void Triangulator::
00088 begin_hole() {
00089   _holes.push_back(vector_int());
00090 }
00091 
00092 ////////////////////////////////////////////////////////////////////
00093 //     Function: Triangulator::add_hole_vertex
00094 //       Access: Published
00095 //  Description: Adds the next consecutive vertex of the current hole.
00096 //               This vertex should index into the vertex pool
00097 //               established by repeated calls to add_vertex().
00098 //
00099 //               The vertices may be listed in either clockwise or
00100 //               counterclockwise order.  Vertices should not be
00101 //               repeated.
00102 ////////////////////////////////////////////////////////////////////
00103 void Triangulator::
00104 add_hole_vertex(int index) {
00105   nassertv(!_holes.empty());
00106   _holes.back().push_back(index);
00107 }
00108 
00109 ////////////////////////////////////////////////////////////////////
00110 //     Function: Triangulator::triangulate
00111 //       Access: Published
00112 //  Description: Does the work of triangulating the specified polygon.
00113 //               After this call, you may retrieve the new triangles
00114 //               one at a time by iterating through
00115 //               get_triangle_v0/1/2().
00116 ////////////////////////////////////////////////////////////////////
00117 void Triangulator::
00118 triangulate() {
00119   _result.clear();
00120 
00121   // Make sure our index numbers are reasonable.
00122   cleanup_polygon_indices(_polygon);
00123   Holes::iterator hi;
00124   for (hi = _holes.begin(); hi != _holes.end(); ++hi) {
00125     cleanup_polygon_indices(*hi);
00126   }
00127 
00128   if (_polygon.size() < 3) {
00129     // Degenerate case.
00130     return;
00131   }
00132 
00133   // Set up the list of segments.
00134   seg.clear();
00135   seg.push_back(segment_t());  // we don't use the first entry.
00136   make_segment(_polygon, true);
00137 
00138   for (hi = _holes.begin(); hi != _holes.end(); ++hi) {
00139     if ((*hi).size() >= 3) {
00140       make_segment(*hi, false);
00141     }
00142   }
00143 
00144   // Shuffle the segment index.
00145   int num_segments = (int)seg.size() - 1;
00146   permute.reserve(num_segments);
00147   int i;
00148   for (i = 0; i < num_segments; ++i) {
00149     permute.push_back(i + 1);
00150   }
00151 
00152   // Actually, I'm not sure why we should shuffle the index.  That
00153   // makes the result non-deterministic, and isn't one order--for
00154   // instance, the initial order--as good as any other?
00155   /*
00156   Randomizer randomizer;
00157   for (i = 0; i < num_segments; ++i) {
00158     int j = randomizer.random_int(num_segments);
00159     nassertv(j >= 0 && j < num_segments);
00160     int t = permute[i];
00161     permute[i] = permute[j];
00162     permute[j] = t;
00163   }
00164   */
00165   choose_idx = 0;
00166 
00167   /*
00168   //cerr << "got " << num_segments << " segments\n";
00169   for (i = 1; i < (int)seg.size(); ++i) {
00170     segment_t &s = seg[i];
00171     printf("  %d. (%g %g), (%g %g)\n", i, s.v0.x, s.v0.y, s.v1.x, s.v1.y);
00172     printf("    root0 = %d, root1 = %d\n", s.root0, s.root1);
00173     printf("    next = %d, prev = %d\n", s.next, s.prev);
00174   }
00175   */
00176 
00177   while (construct_trapezoids(num_segments) != 0) {
00178     // If there's an error, re-shuffle the index and try again.
00179     Randomizer randomizer;
00180     for (i = 0; i < num_segments; ++i) {
00181       int j = randomizer.random_int(num_segments);
00182       nassertv(j >= 0 && j < num_segments);
00183       int t = permute[i];
00184       permute[i] = permute[j];
00185       permute[j] = t;
00186     }
00187     choose_idx = 0;
00188 
00189     /*
00190     //cerr << "got " << num_segments << " segments\n";
00191     for (i = 1; i < (int)seg.size(); ++i) {
00192       segment_t &s = seg[i];
00193       printf("  %d. (%g %g), (%g %g)\n", i, s.v0.x, s.v0.y, s.v1.x, s.v1.y);
00194       printf("    root0 = %d, root1 = %d\n", s.root0, s.root1);
00195       printf("    next = %d, prev = %d\n", s.next, s.prev);
00196     }
00197     */
00198   }
00199 
00200   /*
00201   //cerr << "got " << tr.size() - 1 << " trapezoids\n";
00202   for (i = 1; i < (int)tr.size(); ++i) {
00203     trap_t &t = tr[i];
00204     //cerr << "  " << i << ". state = " << t.state << "\n";
00205     //cerr << "    lseg = " << t.lseg << " rseg = " << t.rseg << "\n";
00206     //cerr << "    hi = " << t.hi.x << " " << t.hi.y << " lo = " << t.lo.x << " " << t.lo.y << "\n";
00207   }
00208   */
00209 
00210   int nmonpoly = monotonate_trapezoids(num_segments);
00211 
00212   //cerr << "got " << nmonpoly << " monotone polygons\n";
00213 
00214   triangulate_monotone_polygons(num_segments, nmonpoly);
00215 
00216   /*
00217   Result::iterator ri;
00218   for (ri = _result.begin(); ri != _result.end(); ++ri) {
00219     //cerr << "tri: " << (*ri)._v0 << " " << (*ri)._v1 << " " << (*ri)._v2 << "\n";
00220   }
00221   */
00222 }
00223 
00224 ////////////////////////////////////////////////////////////////////
00225 //     Function: Triangulator::get_num_triangles
00226 //       Access: Published
00227 //  Description: Returns the number of triangles generated by the
00228 //               previous call to triangulate().
00229 ////////////////////////////////////////////////////////////////////
00230 int Triangulator::
00231 get_num_triangles() const {
00232   return _result.size();
00233 }
00234 
00235 ////////////////////////////////////////////////////////////////////
00236 //     Function: Triangulator::get_triangle_v0
00237 //       Access: Published
00238 //  Description: Returns vertex 0 of the nth triangle generated by the
00239 //               previous call to triangulate().
00240 //
00241 //               This is a zero-based index into the vertices added by
00242 //               repeated calls to add_vertex().
00243 ////////////////////////////////////////////////////////////////////
00244 int Triangulator::
00245 get_triangle_v0(int n) const {
00246   nassertr(n >= 0 && n < (int)_result.size(), -1);
00247   return _result[n]._v0;
00248 }
00249 
00250 ////////////////////////////////////////////////////////////////////
00251 //     Function: Triangulator::get_triangle_v1
00252 //       Access: Published
00253 //  Description: Returns vertex 1 of the nth triangle generated by the
00254 //               previous call to triangulate().
00255 //
00256 //               This is a zero-based index into the vertices added by
00257 //               repeated calls to add_vertex().
00258 ////////////////////////////////////////////////////////////////////
00259 int Triangulator::
00260 get_triangle_v1(int n) const {
00261   nassertr(n >= 0 && n < (int)_result.size(), -1);
00262   return _result[n]._v1;
00263 }
00264 
00265 ////////////////////////////////////////////////////////////////////
00266 //     Function: Triangulator::get_triangle_v2
00267 //       Access: Published
00268 //  Description: Returns vertex 2 of the nth triangle generated by the
00269 //               previous call to triangulate().
00270 //
00271 //               This is a zero-based index into the vertices added by
00272 //               repeated calls to add_vertex().
00273 ////////////////////////////////////////////////////////////////////
00274 int Triangulator::
00275 get_triangle_v2(int n) const {
00276   nassertr(n >= 0 && n < (int)_result.size(), -1);
00277   return _result[n]._v2;
00278 }
00279 
00280 ////////////////////////////////////////////////////////////////////
00281 //     Function: Triangulator::cleanup_polygon_indices
00282 //       Access: Protected
00283 //  Description: Removes any invalid index numbers from the list.
00284 ////////////////////////////////////////////////////////////////////
00285 void Triangulator::
00286 cleanup_polygon_indices(vector_int &polygon) {
00287   // First, check for index bounds.
00288   size_t pi = 0;
00289   while (pi < polygon.size()) {
00290     if (polygon[pi] >= 0 && polygon[pi] < _vertices.size()) {
00291       // This vertex is OK.
00292       ++pi;
00293     } else {
00294       // This index is out-of-bounds; remove it.
00295       polygon.erase(_polygon.begin() + pi);
00296     }
00297   }
00298 
00299   // Now, remove any consecutive repeated vertices.
00300   pi = 1;
00301   while (pi < polygon.size()) {
00302     if (_vertices[polygon[pi]] != _vertices[polygon[pi - 1]]) {
00303       // This vertex is OK.
00304       ++pi;
00305     } else {
00306       // This vertex repeats the previous one; remove it.
00307       polygon.erase(_polygon.begin() + pi);
00308     }
00309   }
00310 
00311   if (polygon.size() > 1 && _vertices[polygon.back()] == _vertices[_polygon.front()]) {
00312     // The last vertex repeats the first one; remove it.
00313     polygon.pop_back();
00314   }
00315 }
00316 
00317 
00318 // The remainder of the code in this file is adapted more or less from
00319 // the C code published with the referenced paper.
00320 
00321 #define T_X     1
00322 #define T_Y     2
00323 #define T_SINK  3
00324 
00325 
00326 #define FIRSTPT 1               /* checking whether pt. is inserted */ 
00327 #define LASTPT  2
00328 
00329 
00330 #define REALLY_BIG 1<<30
00331 #define C_EPS 1.0e-7            /* tolerance value: Used for making */
00332                                 /* all decisions about collinearity or */
00333                                 /* left/right of segment. Decrease */
00334                                 /* this value if the input points are */
00335                                 /* spaced very close together */
00336 
00337 
00338 #define S_LEFT 1                /* for merge-direction */
00339 #define S_RIGHT 2
00340 
00341 
00342 #define ST_VALID 1              /* for trapezium state */
00343 #define ST_INVALID 2
00344 
00345 
00346 #define SP_SIMPLE_LRUP 1        /* for splitting trapezoids */
00347 #define SP_SIMPLE_LRDN 2
00348 #define SP_2UP_2DN     3
00349 #define SP_2UP_LEFT    4
00350 #define SP_2UP_RIGHT   5
00351 #define SP_2DN_LEFT    6
00352 #define SP_2DN_RIGHT   7
00353 #define SP_NOSPLIT    -1
00354 
00355 #define TR_FROM_UP 1            /* for traverse-direction */
00356 #define TR_FROM_DN 2
00357 
00358 #define TRI_LHS 1
00359 #define TRI_RHS 2
00360 
00361 
00362 #define CROSS(v0, v1, v2) (((v1).x - (v0).x)*((v2).y - (v0).y) - \
00363                            ((v1).y - (v0).y)*((v2).x - (v0).x))
00364 
00365 #define DOT(v0, v1) ((v0).x * (v1).x + (v0).y * (v1).y)
00366 
00367 #define FP_EQUAL(s, t) (fabs(s - t) <= C_EPS)
00368 
00369 
00370 #define CROSS_SINE(v0, v1) ((v0).x * (v1).y - (v1).x * (v0).y)
00371 #define LENGTH(v0) (sqrt((v0).x * (v0).x + (v0).y * (v0).y))
00372 
00373 
00374 ////////////////////////////////////////////////////////////////////
00375 //     Function: Triangulator::check_left_winding
00376 //       Access: Private
00377 //  Description: Returns true if the list of vertices is
00378 //               counter-clockwise, false if it is clockwise.
00379 ////////////////////////////////////////////////////////////////////
00380 bool Triangulator::
00381 check_left_winding(const vector_int &range) const {
00382   // We do this by computing the polygon's signed area.  If it comes
00383   // out negative, the polygon is right-winding.
00384 
00385   double area = 0.0;
00386   size_t j = range.size() - 1;
00387   for (size_t i = 0; i < range.size(); ++i) {
00388     const LPoint2d &p0 = _vertices[range[j]];
00389     const LPoint2d &p1 = _vertices[range[i]];
00390     area += p0[0] * p1[1] - p0[1] * p1[0];
00391     j = i;
00392   }
00393 
00394   return area >= 0.0;
00395 }
00396 
00397 ////////////////////////////////////////////////////////////////////
00398 //     Function: Triangulator::make_segment
00399 //       Access: Private
00400 //  Description: Converts a linear list of integer vertices to a list
00401 //               of segment_t.  If want_left_winding is true, the list
00402 //               is reversed if necessary to make it left-winding;
00403 //               otherwise, it is reversed to make it right-winding.
00404 ////////////////////////////////////////////////////////////////////
00405 void Triangulator::
00406 make_segment(const vector_int &range, bool want_left_winding) {
00407   int num_points = (int)range.size();
00408   nassertv(num_points >= 2);
00409 
00410   int first = (int)seg.size();
00411   int last = first + num_points - 1;
00412 
00413   if (want_left_winding == check_left_winding(range)) {
00414     // Keep it in its natural order.
00415     int first = (int)seg.size();
00416     int last = first + num_points - 1;
00417     
00418     seg.push_back(segment_t(this, range[0], range[1],
00419                             last, first + 1));
00420     
00421     for (int i = 1; i < num_points - 1; ++i) {
00422       seg.push_back(segment_t(this, range[i], range[i + 1],
00423                               first + i - 1, first + i + 1));
00424     }
00425     
00426     seg.push_back(segment_t(this, range[num_points - 1], range[0],
00427                             last - 1, first));
00428 
00429   } else {
00430     // Reverse it.
00431     seg.push_back(segment_t(this, range[0], range[num_points - 1],
00432                             last, first + 1));
00433     
00434     for (int i = 1; i < num_points - 1; ++i) {
00435       seg.push_back(segment_t(this, range[num_points - i], range[num_points - i - 1],
00436                               first + i - 1, first + i + 1));
00437     }
00438     
00439     seg.push_back(segment_t(this, range[1], range[0],
00440                             last - 1, first));
00441 
00442   }
00443 }
00444   
00445 /* Return the next segment in the generated random ordering of all the */
00446 /* segments in S */
00447 int Triangulator::
00448 choose_segment() {
00449   nassertr(choose_idx < (int)permute.size(), 0);
00450   //  segment_t &s = seg[permute[choose_idx]];
00451   //  cerr << "choose_segment " << permute[choose_idx] << ": " << s.v0.x << ", " << s.v0.y << " to " << s.v1.x << ", " << s.v1.y << "\n";
00452   return permute[choose_idx++];
00453 }
00454 
00455 double Triangulator::
00456 math_log2(double v) {
00457   static const double log2 = log(2.0);
00458   return log(v) / log2;
00459 }
00460 
00461 /* Get log*n for given n */
00462 int Triangulator::
00463 math_logstar_n(int n) {
00464   int i;
00465   double v;
00466   
00467   for (i = 0, v = (double) n; v >= 1; i++)
00468     v = math_log2(v);
00469   
00470   return (i - 1);
00471 }
00472   
00473 
00474 int Triangulator::
00475 math_N(int n, int h) {
00476   int i;
00477   double v;
00478 
00479   for (i = 0, v = (int) n; i < h; i++)
00480     v = math_log2(v);
00481   
00482   return (int) ceil((double) 1.0*n/v);
00483 }
00484 
00485 
00486 /* Return a new node to be added into the query tree */
00487 int Triangulator::newnode() {
00488   int index = (int)qs.size();
00489   qs.push_back(node_t());
00490   //  cerr << "creating new node " << index << "\n";
00491   return index;
00492 }
00493 
00494 /* Return a free trapezoid */
00495 int Triangulator::newtrap() {
00496   int tr_idx = (int)tr.size();
00497   tr.push_back(trap_t());
00498   tr[tr_idx].lseg = -1;
00499   tr[tr_idx].rseg = -1;
00500   tr[tr_idx].state = ST_VALID;
00501   //  cerr << "creating new trapezoid " << tr_idx << "\n";
00502   return tr_idx;
00503 }
00504 
00505 
00506 /* Return the maximum of the two points into the yval structure */
00507 int Triangulator::_max(point_t *yval, point_t *v0, point_t *v1) {
00508   if (v0->y > v1->y + C_EPS)
00509     *yval = *v0;
00510   else if (FP_EQUAL(v0->y, v1->y))
00511     {
00512       if (v0->x > v1->x + C_EPS)
00513         *yval = *v0;
00514       else
00515         *yval = *v1;
00516     }
00517   else
00518     *yval = *v1;
00519   
00520   return 0;
00521 }
00522 
00523 
00524 /* Return the minimum of the two points into the yval structure */
00525 int Triangulator::_min(point_t *yval, point_t *v0, point_t *v1) {
00526   if (v0->y < v1->y - C_EPS)
00527     *yval = *v0;
00528   else if (FP_EQUAL(v0->y, v1->y))
00529     {
00530       if (v0->x < v1->x)
00531         *yval = *v0;
00532       else
00533         *yval = *v1;
00534     }
00535   else
00536     *yval = *v1;
00537   
00538   return 0;
00539 }
00540 
00541 
00542 int Triangulator::
00543 _greater_than(point_t *v0, point_t *v1) {
00544   if (v0->y > v1->y + C_EPS)
00545     return true;
00546   else if (v0->y < v1->y - C_EPS)
00547     return false;
00548   else
00549     return (v0->x > v1->x);
00550 }
00551 
00552 
00553 int Triangulator::
00554 _equal_to(point_t *v0, point_t *v1) {
00555   return (FP_EQUAL(v0->y, v1->y) && FP_EQUAL(v0->x, v1->x));
00556 }
00557 
00558 int Triangulator::
00559 _greater_than_equal_to(point_t *v0, point_t *v1) {
00560   if (v0->y > v1->y + C_EPS)
00561     return true;
00562   else if (v0->y < v1->y - C_EPS)
00563     return false;
00564   else
00565     return (v0->x >= v1->x);
00566 }
00567 
00568 int Triangulator::
00569 _less_than(point_t *v0, point_t *v1) {
00570   if (v0->y < v1->y - C_EPS)
00571     return true;
00572   else if (v0->y > v1->y + C_EPS)
00573     return false;
00574   else
00575     return (v0->x < v1->x);
00576 }
00577 
00578 
00579 /* Initilialise the query structure (Q) and the trapezoid table (T) 
00580  * when the first segment is added to start the trapezoidation. The
00581  * query-tree starts out with 4 trapezoids, one S-node and 2 Y-nodes
00582  *    
00583  *                4
00584  *   -----------------------------------
00585  *                \
00586  *      1          \        2
00587  *                  \
00588  *   -----------------------------------
00589  *                3
00590  */
00591 
00592 int Triangulator::
00593 init_query_structure(int segnum) {
00594   int i1, i2, i3, i4, i5, i6, i7, root;
00595   int t1, t2, t3, t4;
00596   segment_t *s = &seg[segnum];
00597 
00598   tr.clear();
00599   qs.clear();
00600 
00601   // We don't use the first elements.
00602   tr.push_back(trap_t());
00603   qs.push_back(node_t());
00604 
00605   i1 = newnode();
00606   qs[i1].nodetype = T_Y;
00607   _max(&qs[i1].yval, &s->v0, &s->v1); /* root */
00608   root = i1;
00609 
00610   i2 = newnode();
00611   qs[i1].right = i2;
00612   qs[i2].nodetype = T_SINK;
00613   qs[i2].parent = i1;
00614 
00615   i3 = newnode();
00616   qs[i1].left = i3;
00617 
00618   qs[i3].nodetype = T_Y;
00619   _min(&qs[i3].yval, &s->v0, &s->v1); /* root */
00620   qs[i3].parent = i1;
00621   
00622   i4 = newnode();
00623   qs[i3].left = i4;
00624   qs[i4].nodetype = T_SINK;
00625   qs[i4].parent = i3;
00626   
00627   i5 = newnode();
00628   qs[i3].right = i5;
00629   qs[i5].nodetype = T_X;
00630   qs[i5].segnum = segnum;
00631   qs[i5].parent = i3;
00632   
00633   i6 = newnode();
00634   qs[i5].left = i6;
00635   qs[i6].nodetype = T_SINK;
00636   qs[i6].parent = i5;
00637 
00638   i7 = newnode();
00639   qs[i5].right = i7;
00640   qs[i7].nodetype = T_SINK;
00641   qs[i7].parent = i5;
00642 
00643   t1 = newtrap();               /* middle left */
00644   t2 = newtrap();               /* middle right */
00645   t3 = newtrap();               /* bottom-most */
00646   t4 = newtrap();               /* topmost */
00647 
00648   tr[t4].lo = qs[i1].yval;
00649   tr[t2].hi = qs[i1].yval;
00650   tr[t1].hi = qs[i1].yval;
00651   tr[t3].hi = qs[i3].yval;
00652   tr[t2].lo = qs[i3].yval;
00653   tr[t1].lo = qs[i3].yval;
00654   tr[t4].hi.y = (double) (REALLY_BIG);
00655   tr[t4].hi.x = (double) (REALLY_BIG);
00656   tr[t3].lo.y = (double) -1* (REALLY_BIG);
00657   tr[t3].lo.x = (double) -1* (REALLY_BIG);
00658   tr[t2].lseg = segnum;
00659   tr[t1].rseg = segnum;
00660   tr[t2].u0 = t4;
00661   tr[t1].u0 = t4;
00662   tr[t2].d0 = t3;
00663   tr[t1].d0 = t3;
00664   tr[t3].u0 = t1;
00665   tr[t4].d0 = t1;
00666   tr[t3].u1 = t2;
00667   tr[t4].d1 = t2;
00668   
00669   tr[t1].sink = i6;
00670   tr[t2].sink = i7;
00671   tr[t3].sink = i4;
00672   tr[t4].sink = i2;
00673 
00674   tr[t2].state = ST_VALID;
00675   tr[t1].state = ST_VALID;
00676   tr[t4].state = ST_VALID;
00677   tr[t3].state = ST_VALID;
00678 
00679   qs[i2].trnum = t4;
00680   qs[i4].trnum = t3;
00681   qs[i6].trnum = t1;
00682   qs[i7].trnum = t2;
00683 
00684   s->is_inserted = true;
00685   return root;
00686 }
00687 
00688 
00689 /* Retun true if the vertex v is to the left of line segment no.
00690  * segnum. Takes care of the degenerate cases when both the vertices
00691  * have the same y--cood, etc.
00692  */
00693 
00694 int Triangulator::
00695 is_left_of(int segnum, point_t *v) {
00696   segment_t *s = &seg[segnum];
00697   double area;
00698   
00699   if (_greater_than(&s->v1, &s->v0)) /* seg. going upwards */
00700     {
00701       if (FP_EQUAL(s->v1.y, v->y))
00702         {
00703           if (v->x < s->v1.x)
00704             area = 1.0;
00705           else
00706             area = -1.0;
00707         }
00708       else if (FP_EQUAL(s->v0.y, v->y))
00709         {
00710           if (v->x < s->v0.x)
00711             area = 1.0;
00712           else
00713             area = -1.0;
00714         }
00715       else
00716         area = CROSS(s->v0, s->v1, (*v));
00717     }
00718   else                          /* v0 > v1 */
00719     {
00720       if (FP_EQUAL(s->v1.y, v->y))
00721         {
00722           if (v->x < s->v1.x)
00723             area = 1.0;
00724           else
00725             area = -1.0;
00726         }
00727       else if (FP_EQUAL(s->v0.y, v->y))
00728         {
00729           if (v->x < s->v0.x)
00730             area = 1.0;
00731           else
00732             area = -1.0;
00733         }
00734       else
00735         area = CROSS(s->v1, s->v0, (*v));
00736     }
00737   
00738   if (area > 0.0)
00739     return true;
00740   else 
00741     return false;
00742 }
00743 
00744 
00745 
00746 /* Returns true if the corresponding endpoint of the given segment is */
00747 /* already inserted into the segment tree. Use the simple test of */
00748 /* whether the segment which shares this endpoint is already inserted */
00749 
00750 int Triangulator::
00751 inserted(int segnum, int whichpt) {
00752   if (whichpt == FIRSTPT)
00753     return seg[seg[segnum].prev].is_inserted;
00754   else
00755     return seg[seg[segnum].next].is_inserted;
00756 }
00757 
00758 /* This is query routine which determines which trapezoid does the 
00759  * point v lie in. The return value is the trapezoid number. 
00760  */
00761 
00762 int Triangulator::
00763 locate_endpoint(point_t *v, point_t *vo, int r) {
00764   //  cerr << "locate_endpoint(" << v->x << " " << v->y << ", " << vo->x << " " << vo->y << ", " << r << ")\n";
00765   node_t *rptr = &qs[r];
00766   
00767   switch (rptr->nodetype)
00768     {
00769     case T_SINK:
00770       return rptr->trnum;
00771       
00772     case T_Y:
00773       if (_greater_than(v, &rptr->yval)) /* above */
00774         return locate_endpoint(v, vo, rptr->right);
00775       else if (_equal_to(v, &rptr->yval)) /* the point is already */
00776         {                                 /* inserted. */
00777           if (_greater_than(vo, &rptr->yval)) /* above */
00778             return locate_endpoint(v, vo, rptr->right);
00779           else 
00780             return locate_endpoint(v, vo, rptr->left); /* below */
00781         }
00782       else
00783         return locate_endpoint(v, vo, rptr->left); /* below */
00784 
00785     case T_X:
00786       if (_equal_to(v, &seg[rptr->segnum].v0) || 
00787                _equal_to(v, &seg[rptr->segnum].v1))
00788         {
00789           if (FP_EQUAL(v->y, vo->y)) /* horizontal segment */
00790             {
00791               if (vo->x < v->x)
00792                 return locate_endpoint(v, vo, rptr->left); /* left */
00793               else
00794                 return locate_endpoint(v, vo, rptr->right); /* right */
00795             }
00796 
00797           else if (is_left_of(rptr->segnum, vo))
00798             return locate_endpoint(v, vo, rptr->left); /* left */
00799           else
00800             return locate_endpoint(v, vo, rptr->right); /* right */
00801         }
00802       else if (is_left_of(rptr->segnum, v))
00803         return locate_endpoint(v, vo, rptr->left); /* left */
00804       else
00805         return locate_endpoint(v, vo, rptr->right); /* right */
00806 
00807     default:
00808       fprintf(stderr, "Haggu !!!!!\n");
00809       nassertr(false, -1);
00810       return -1;
00811     }
00812 }
00813 
00814 
00815 /* Thread in the segment into the existing trapezoidation. The 
00816  * limiting trapezoids are given by tfirst and tlast (which are the
00817  * trapezoids containing the two endpoints of the segment. Merges all
00818  * possible trapezoids which flank this segment and have been recently
00819  * divided because of its insertion
00820  */
00821 
00822 int Triangulator::
00823 merge_trapezoids(int segnum, int tfirst, int tlast, int side) {
00824   int t, tnext, cond;
00825   int ptnext;
00826 
00827   //  cerr << "merge_trapezoids(" << segnum << ", " << tfirst << ", " << tlast << ", " << side << ")\n";
00828 
00829   /* First merge polys on the LHS */
00830   t = tfirst;
00831   while ((t > 0) && _greater_than_equal_to(&tr[t].lo, &tr[tlast].lo))
00832     {
00833       if (side == S_LEFT)
00834         cond = ((((tnext = tr[t].d0) > 0) && (tr[tnext].rseg == segnum)) ||
00835                 (((tnext = tr[t].d1) > 0) && (tr[tnext].rseg == segnum)));
00836       else
00837         cond = ((((tnext = tr[t].d0) > 0) && (tr[tnext].lseg == segnum)) ||
00838                 (((tnext = tr[t].d1) > 0) && (tr[tnext].lseg == segnum)));
00839       
00840       if (cond)
00841         {
00842           if ((tr[t].lseg == tr[tnext].lseg) &&
00843               (tr[t].rseg == tr[tnext].rseg)) /* good neighbours */
00844             {                                 /* merge them */
00845               /* Use the upper node as the new node i.e. t */
00846 
00847               ptnext = qs[tr[tnext].sink].parent;
00848 
00849               if (qs[ptnext].left == tr[tnext].sink)
00850                 qs[ptnext].left = tr[t].sink;
00851               else
00852                 qs[ptnext].right = tr[t].sink;  /* redirect parent */
00853 
00854 
00855               /* Change the upper neighbours of the lower trapezoids */
00856 
00857               if ((tr[t].d0 = tr[tnext].d0) > 0)
00858                 if (tr[tr[t].d0].u0 == tnext)
00859                   tr[tr[t].d0].u0 = t;
00860                 else if (tr[tr[t].d0].u1 == tnext)
00861                   tr[tr[t].d0].u1 = t;
00862 
00863               if ((tr[t].d1 = tr[tnext].d1) > 0)
00864                 if (tr[tr[t].d1].u0 == tnext)
00865                   tr[tr[t].d1].u0 = t;
00866                 else if (tr[tr[t].d1].u1 == tnext)
00867                   tr[tr[t].d1].u1 = t;
00868 
00869               tr[t].lo = tr[tnext].lo;
00870               tr[tnext].state = ST_INVALID; /* invalidate the lower */
00871                                             /* trapezium */
00872             }
00873           else              /* not good neighbours */
00874             t = tnext;
00875         }
00876       else                  /* do not satisfy the outer if */
00877         t = tnext;
00878       
00879     } /* end-while */
00880        
00881   return 0;
00882 }
00883 
00884 
00885 /* Add in the new segment into the trapezoidation and update Q and T
00886  * structures. First locate the two endpoints of the segment in the
00887  * Q-structure. Then start from the topmost trapezoid and go down to
00888  * the  lower trapezoid dividing all the trapezoids in between .
00889  */
00890 
00891 int Triangulator::
00892 add_segment(int segnum) {
00893   //cerr << "add_segment(" << segnum << ")\n";
00894 
00895   segment_t s;
00896   //  segment_t *so = &seg[segnum];
00897   int tu, tl, sk, tfirst, tlast; //, tnext;
00898   int tfirstr = 0, tlastr = 0, tfirstl = 0, tlastl = 0;
00899   int i1, i2, t, tn; // t1, t2,
00900   point_t tpt;
00901   int tritop = 0, tribot = 0, is_swapped = 0;
00902   int tmptriseg;
00903 
00904   s = seg[segnum];
00905   if (_greater_than(&s.v1, &s.v0)) /* Get higher vertex in v0 */
00906     {
00907       int tmp;
00908       tpt = s.v0;
00909       s.v0 = s.v1;
00910       s.v1 = tpt;
00911       tmp = s.root0;
00912       s.root0 = s.root1;
00913       s.root1 = tmp;
00914       is_swapped = true;
00915     }
00916 
00917   if ((is_swapped) ? !inserted(segnum, LASTPT) :
00918        !inserted(segnum, FIRSTPT))     /* insert v0 in the tree */
00919     {
00920       int tmp_d;
00921 
00922       tu = locate_endpoint(&s.v0, &s.v1, s.root0);
00923       tl = newtrap();           /* tl is the new lower trapezoid */
00924       tr[tl].state = ST_VALID;
00925       tr[tl] = tr[tu];
00926       tr[tl].hi.y = s.v0.y;
00927       tr[tu].lo.y = s.v0.y;
00928       tr[tl].hi.x = s.v0.x;
00929       tr[tu].lo.x = s.v0.x;
00930       tr[tu].d0 = tl;      
00931       tr[tu].d1 = 0;
00932       tr[tl].u0 = tu;
00933       tr[tl].u1 = 0;
00934 
00935       if (((tmp_d = tr[tl].d0) > 0) && (tr[tmp_d].u0 == tu))
00936         tr[tmp_d].u0 = tl;
00937       if (((tmp_d = tr[tl].d0) > 0) && (tr[tmp_d].u1 == tu))
00938         tr[tmp_d].u1 = tl;
00939 
00940       if (((tmp_d = tr[tl].d1) > 0) && (tr[tmp_d].u0 == tu))
00941         tr[tmp_d].u0 = tl;
00942       if (((tmp_d = tr[tl].d1) > 0) && (tr[tmp_d].u1 == tu))
00943         tr[tmp_d].u1 = tl;
00944 
00945       /* Now update the query structure and obtain the sinks for the */
00946       /* two trapezoids */ 
00947       
00948       i1 = newnode();           /* Upper trapezoid sink */
00949       i2 = newnode();           /* Lower trapezoid sink */
00950       sk = tr[tu].sink;
00951       
00952       qs[sk].nodetype = T_Y;
00953       qs[sk].yval = s.v0;
00954       qs[sk].segnum = segnum;   /* not really reqd ... maybe later */
00955       qs[sk].left = i2;
00956       qs[sk].right = i1;
00957 
00958       qs[i1].nodetype = T_SINK;
00959       qs[i1].trnum = tu;
00960       qs[i1].parent = sk;
00961 
00962       qs[i2].nodetype = T_SINK;
00963       qs[i2].trnum = tl;
00964       qs[i2].parent = sk;
00965 
00966       tr[tu].sink = i1;
00967       tr[tl].sink = i2;
00968       tfirst = tl;
00969     }
00970   else                          /* v0 already present */
00971     {       /* Get the topmost intersecting trapezoid */
00972       tfirst = locate_endpoint(&s.v0, &s.v1, s.root0);
00973       tritop = 1;
00974     }
00975 
00976 
00977   if ((is_swapped) ? !inserted(segnum, FIRSTPT) :
00978        !inserted(segnum, LASTPT))     /* insert v1 in the tree */
00979     {
00980       int tmp_d;
00981 
00982       tu = locate_endpoint(&s.v1, &s.v0, s.root1);
00983 
00984       tl = newtrap();           /* tl is the new lower trapezoid */
00985       tr[tl].state = ST_VALID;
00986       tr[tl] = tr[tu];
00987       tr[tl].hi.y = s.v1.y;
00988       tr[tu].lo.y = s.v1.y;
00989       tr[tl].hi.x = s.v1.x;
00990       tr[tu].lo.x = s.v1.x;
00991       tr[tu].d0 = tl;      
00992       tr[tu].d1 = 0;
00993       tr[tl].u0 = tu;
00994       tr[tl].u1 = 0;
00995 
00996       if (((tmp_d = tr[tl].d0) > 0) && (tr[tmp_d].u0 == tu))
00997         tr[tmp_d].u0 = tl;
00998       if (((tmp_d = tr[tl].d0) > 0) && (tr[tmp_d].u1 == tu))
00999         tr[tmp_d].u1 = tl;
01000 
01001       if (((tmp_d = tr[tl].d1) > 0) && (tr[tmp_d].u0 == tu))
01002         tr[tmp_d].u0 = tl;
01003       if (((tmp_d = tr[tl].d1) > 0) && (tr[tmp_d].u1 == tu))
01004         tr[tmp_d].u1 = tl;
01005       
01006       /* Now update the query structure and obtain the sinks for the */
01007       /* two trapezoids */ 
01008       
01009       i1 = newnode();           /* Upper trapezoid sink */
01010       i2 = newnode();           /* Lower trapezoid sink */
01011       sk = tr[tu].sink;
01012       
01013       qs[sk].nodetype = T_Y;
01014       qs[sk].yval = s.v1;
01015       qs[sk].segnum = segnum;   /* not really reqd ... maybe later */
01016       qs[sk].left = i2;
01017       qs[sk].right = i1;
01018 
01019       qs[i1].nodetype = T_SINK;
01020       qs[i1].trnum = tu;
01021       qs[i1].parent = sk;
01022 
01023       qs[i2].nodetype = T_SINK;
01024       qs[i2].trnum = tl;
01025       qs[i2].parent = sk;
01026 
01027       tr[tu].sink = i1;
01028       tr[tl].sink = i2;
01029       tlast = tu;
01030     }
01031   else                          /* v1 already present */
01032     {       /* Get the lowermost intersecting trapezoid */
01033       tlast = locate_endpoint(&s.v1, &s.v0, s.root1);
01034       tribot = 1;
01035     }
01036   
01037   /* Thread the segment into the query tree creating a new X-node */
01038   /* First, split all the trapezoids which are intersected by s into */
01039   /* two */
01040 
01041   t = tfirst;                   /* topmost trapezoid */
01042   
01043   while ((t > 0) && 
01044          _greater_than_equal_to(&tr[t].lo, &tr[tlast].lo))
01045                                 /* traverse from top to bot */
01046     {
01047       int t_sav, tn_sav;
01048       sk = tr[t].sink;
01049       i1 = newnode();           /* left trapezoid sink */
01050       i2 = newnode();           /* right trapezoid sink */
01051       
01052       qs[sk].nodetype = T_X;
01053       qs[sk].segnum = segnum;
01054       qs[sk].left = i1;
01055       qs[sk].right = i2;
01056 
01057       qs[i1].nodetype = T_SINK; /* left trapezoid (use existing one) */
01058       qs[i1].trnum = t;
01059       qs[i1].parent = sk;
01060 
01061       qs[i2].nodetype = T_SINK; /* right trapezoid (allocate new) */
01062       tn = newtrap();
01063       qs[i2].trnum = tn;
01064       tr[tn].state = ST_VALID;
01065       qs[i2].parent = sk;
01066 
01067       if (t == tfirst)
01068         tfirstr = tn;
01069       if (_equal_to(&tr[t].lo, &tr[tlast].lo))
01070         tlastr = tn;
01071 
01072       tr[tn] = tr[t];
01073       tr[t].sink = i1;
01074       tr[tn].sink = i2;
01075       t_sav = t;
01076       tn_sav = tn;
01077 
01078       /* error */
01079 
01080       if ((tr[t].d0 <= 0) && (tr[t].d1 <= 0)) /* case cannot arise */
01081         {
01082           /* Actually, this case does sometimes arise.  Huh. */
01083           fprintf(stderr, "add_segment: error\n");
01084           return 1;
01085         }
01086       
01087       /* only one trapezoid below. partition t into two and make the */
01088       /* two resulting trapezoids t and tn as the upper neighbours of */
01089       /* the sole lower trapezoid */
01090       
01091       else if ((tr[t].d0 > 0) && (tr[t].d1 <= 0))
01092         {                       /* Only one trapezoid below */
01093           if ((tr[t].u0 > 0) && (tr[t].u1 > 0))
01094             {                   /* continuation of a chain from abv. */
01095               if (tr[t].usave > 0) /* three upper neighbours */
01096                 {
01097                   if (tr[t].uside == S_LEFT)
01098                     {
01099                       tr[tn].u0 = tr[t].u1;
01100                       tr[t].u1 = -1;
01101                       tr[tn].u1 = tr[t].usave;
01102 
01103                       tr[tr[t].u0].d0 = t;
01104                       tr[tr[tn].u0].d0 = tn;
01105                       tr[tr[tn].u1].d0 = tn;
01106                     }
01107                   else          /* intersects in the right */
01108                     {
01109                       tr[tn].u1 = -1;
01110                       tr[tn].u0 = tr[t].u1;
01111                       tr[t].u1 = tr[t].u0;
01112                       tr[t].u0 = tr[t].usave;
01113 
01114                       tr[tr[t].u0].d0 = t;
01115                       tr[tr[t].u1].d0 = t;
01116                       tr[tr[tn].u0].d0 = tn;
01117                     }
01118                   tr[tn].usave = 0;
01119                   tr[t].usave = 0;
01120                 }
01121               else              /* No usave.... simple case */
01122                 {
01123                   tr[tn].u0 = tr[t].u1;
01124                   tr[tn].u1 = -1;
01125                   tr[t].u1 = -1;
01126                   tr[tr[tn].u0].d0 = tn;
01127                 }
01128             }
01129           else 
01130             {                   /* fresh seg. or upward cusp */
01131               int tmp_u = tr[t].u0;
01132               int td0, td1;
01133               if (((td0 = tr[tmp_u].d0) > 0) && 
01134                   ((td1 = tr[tmp_u].d1) > 0))
01135                 {               /* upward cusp */
01136                   if ((tr[td0].rseg > 0) &&
01137                       !is_left_of(tr[td0].rseg, &s.v1))
01138                     {
01139                       tr[tn].u1 = -1;
01140                       tr[t].u1 = -1;
01141                       tr[t].u0 = -1;
01142                       tr[tr[tn].u0].d1 = tn;
01143                     }
01144                   else          /* cusp going leftwards */
01145                     { 
01146                       tr[t].u1 = -1;
01147                       tr[tn].u1 = -1;
01148                       tr[tn].u0 = -1;
01149                       tr[tr[t].u0].d0 = t;
01150                     }
01151                 }
01152               else              /* fresh segment */
01153                 {
01154                   tr[tr[t].u0].d0 = t;
01155                   tr[tr[t].u0].d1 = tn;
01156                 }
01157             }
01158 
01159           if (FP_EQUAL(tr[t].lo.y, tr[tlast].lo.y) && 
01160               FP_EQUAL(tr[t].lo.x, tr[tlast].lo.x) && tribot)
01161             {           /* bottom forms a triangle */
01162 
01163               if (is_swapped)
01164                 tmptriseg = seg[segnum].prev;
01165               else
01166                 tmptriseg = seg[segnum].next;
01167 
01168               if ((tmptriseg > 0) && is_left_of(tmptriseg, &s.v0))
01169                 {
01170                                 /* L-R downward cusp */
01171                   tr[tr[t].d0].u0 = t;
01172                   tr[tn].d1 = -1;
01173                   tr[tn].d0 = -1;
01174                 }
01175               else
01176                 {
01177                                 /* R-L downward cusp */
01178                   tr[tr[tn].d0].u1 = tn;
01179                   tr[t].d1 = -1;
01180                   tr[t].d0 = -1;
01181                 }
01182             }
01183           else
01184             {
01185               if ((tr[tr[t].d0].u0 > 0) && (tr[tr[t].d0].u1 > 0))
01186                 {
01187                   if (tr[tr[t].d0].u0 == t) /* passes thru LHS */
01188                     {
01189                       tr[tr[t].d0].usave = tr[tr[t].d0].u1;
01190                       tr[tr[t].d0].uside = S_LEFT;
01191                     }
01192                   else
01193                     {
01194                       tr[tr[t].d0].usave = tr[tr[t].d0].u0;
01195                       tr[tr[t].d0].uside = S_RIGHT;
01196                     }
01197                 }
01198               tr[tr[t].d0].u0 = t;
01199               tr[tr[t].d0].u1 = tn;
01200             }
01201 
01202           t = tr[t].d0;
01203         }
01204 
01205 
01206       else if ((tr[t].d0 <= 0) && (tr[t].d1 > 0))
01207         {                       /* Only one trapezoid below */
01208           if ((tr[t].u0 > 0) && (tr[t].u1 > 0))
01209             {                   /* continuation of a chain from abv. */
01210               if (tr[t].usave > 0) /* three upper neighbours */
01211                 {
01212                   if (tr[t].uside == S_LEFT)
01213                     {
01214                       tr[tn].u0 = tr[t].u1;
01215                       tr[t].u1 = -1;
01216                       tr[tn].u1 = tr[t].usave;
01217 
01218                       tr[tr[t].u0].d0 = t;
01219                       tr[tr[tn].u0].d0 = tn;
01220                       tr[tr[tn].u1].d0 = tn;
01221                     }
01222                   else          /* intersects in the right */
01223                     {
01224                       tr[tn].u1 = -1;
01225                       tr[tn].u0 = tr[t].u1;
01226                       tr[t].u1 = tr[t].u0;
01227                       tr[t].u0 = tr[t].usave;
01228 
01229                       tr[tr[t].u0].d0 = t;
01230                       tr[tr[t].u1].d0 = t;
01231                       tr[tr[tn].u0].d0 = tn;
01232                     }
01233 
01234                   tr[tn].usave = 0;
01235                   tr[t].usave = 0;
01236                 }
01237               else              /* No usave.... simple case */
01238                 {
01239                   tr[tn].u0 = tr[t].u1;
01240                   tr[tn].u1 = -1;
01241                   tr[t].u1 = -1;
01242                   tr[tr[tn].u0].d0 = tn;
01243                 }
01244             }
01245           else 
01246             {                   /* fresh seg. or upward cusp */
01247               int tmp_u = tr[t].u0;
01248               int td0, td1;
01249               if (((td0 = tr[tmp_u].d0) > 0) && 
01250                   ((td1 = tr[tmp_u].d1) > 0))
01251                 {               /* upward cusp */
01252                   if ((tr[td0].rseg > 0) &&
01253                       !is_left_of(tr[td0].rseg, &s.v1))
01254                     {
01255                       tr[tn].u1 = -1;
01256                       tr[t].u1 = -1;
01257                       tr[t].u0 = -1;
01258                       tr[tr[tn].u0].d1 = tn;
01259                     }
01260                   else 
01261                     {
01262                       tr[t].u1 = -1;
01263                       tr[tn].u1 = -1;
01264                       tr[tn].u0 = -1;
01265                       tr[tr[t].u0].d0 = t;
01266                     }
01267                 }
01268               else              /* fresh segment */
01269                 {
01270                   tr[tr[t].u0].d0 = t;
01271                   tr[tr[t].u0].d1 = tn;
01272                 }
01273             }
01274 
01275           if (FP_EQUAL(tr[t].lo.y, tr[tlast].lo.y) && 
01276               FP_EQUAL(tr[t].lo.x, tr[tlast].lo.x) && tribot)
01277             {           /* bottom forms a triangle */
01278               if (is_swapped)
01279                 tmptriseg = seg[segnum].prev;
01280               else
01281                 tmptriseg = seg[segnum].next;
01282 
01283               if ((tmptriseg > 0) && is_left_of(tmptriseg, &s.v0))
01284                 {
01285                   /* L-R downward cusp */
01286                   tr[tr[t].d1].u0 = t;
01287                   tr[tn].d1 = -1;
01288                   tr[tn].d0 = -1;
01289                 }
01290               else
01291                 {
01292                   /* R-L downward cusp */
01293                   tr[tr[tn].d1].u1 = tn;
01294                   tr[t].d1 = -1;
01295                   tr[t].d0 = -1;
01296                 }
01297             }
01298           else
01299             {
01300               if ((tr[tr[t].d1].u0 > 0) && (tr[tr[t].d1].u1 > 0))
01301                 {
01302                   if (tr[tr[t].d1].u0 == t) /* passes thru LHS */
01303                     {
01304                       tr[tr[t].d1].usave = tr[tr[t].d1].u1;
01305                       tr[tr[t].d1].uside = S_LEFT;
01306                     }
01307                   else
01308                     {
01309                       tr[tr[t].d1].usave = tr[tr[t].d1].u0;
01310                       tr[tr[t].d1].uside = S_RIGHT;
01311                     }
01312                 }
01313               tr[tr[t].d1].u0 = t;
01314               tr[tr[t].d1].u1 = tn;
01315             }
01316 
01317           t = tr[t].d1;
01318         }
01319 
01320       /* two trapezoids below. Find out which one is intersected by */
01321       /* this segment and proceed down that one */
01322       
01323       else
01324         {
01325           //      int tmpseg = tr[tr[t].d0].rseg;
01326           double y0, yt;
01327           point_t tmppt;
01328           int tnext, i_d0, i_d1;
01329 
01330           i_d1 = false;
01331           i_d0 = false;
01332           if (FP_EQUAL(tr[t].lo.y, s.v0.y))
01333             {
01334               if (tr[t].lo.x > s.v0.x)
01335                 i_d0 = true;
01336               else
01337                 i_d1 = true;
01338             }
01339           else
01340             {
01341               y0 = tr[t].lo.y;
01342               tmppt.y = y0;
01343               yt = (y0 - s.v0.y)/(s.v1.y - s.v0.y);
01344               tmppt.x = s.v0.x + yt * (s.v1.x - s.v0.x);
01345 
01346               if (_less_than(&tmppt, &tr[t].lo))
01347                 i_d0 = true;
01348               else
01349                 i_d1 = true;
01350             }
01351 
01352           /* check continuity from the top so that the lower-neighbour */
01353           /* values are properly filled for the upper trapezoid */
01354 
01355           if ((tr[t].u0 > 0) && (tr[t].u1 > 0))
01356             {                   /* continuation of a chain from abv. */
01357               if (tr[t].usave > 0) /* three upper neighbours */
01358                 {
01359                   if (tr[t].uside == S_LEFT)
01360                     {
01361                       tr[tn].u0 = tr[t].u1;
01362                       tr[t].u1 = -1;
01363                       tr[tn].u1 = tr[t].usave;
01364 
01365                       tr[tr[t].u0].d0 = t;
01366                       tr[tr[tn].u0].d0 = tn;
01367                       tr[tr[tn].u1].d0 = tn;
01368                     }
01369                   else          /* intersects in the right */
01370                     {
01371                       tr[tn].u1 = -1;
01372                       tr[tn].u0 = tr[t].u1;
01373                       tr[t].u1 = tr[t].u0;
01374                       tr[t].u0 = tr[t].usave;
01375 
01376                       tr[tr[t].u0].d0 = t;
01377                       tr[tr[t].u1].d0 = t;
01378                       tr[tr[tn].u0].d0 = tn;
01379                     }
01380 
01381                   tr[tn].usave = 0;
01382                   tr[t].usave = 0;
01383                 }
01384               else              /* No usave.... simple case */
01385                 {
01386                   tr[tn].u0 = tr[t].u1;
01387                   tr[tn].u1 = -1;
01388                   tr[t].u1 = -1;
01389                   tr[tr[tn].u0].d0 = tn;
01390                 }
01391             }
01392           else 
01393             {                   /* fresh seg. or upward cusp */
01394               int tmp_u = tr[t].u0;
01395               int td0, td1;
01396               if (((td0 = tr[tmp_u].d0) > 0) && 
01397                   ((td1 = tr[tmp_u].d1) > 0))
01398                 {               /* upward cusp */
01399                   if ((tr[td0].rseg > 0) &&
01400                       !is_left_of(tr[td0].rseg, &s.v1))
01401                     {
01402                       tr[tn].u1 = -1;
01403                       tr[t].u1 = -1;
01404                       tr[t].u0 = -1;
01405                       tr[tr[tn].u0].d1 = tn;
01406                     }
01407                   else 
01408                     {
01409                       tr[t].u1 = -1;
01410                       tr[tn].u1 = -1;
01411                       tr[tn].u0 = -1;
01412                       tr[tr[t].u0].d0 = t;
01413                     }
01414                 }
01415               else              /* fresh segment */
01416                 {
01417                   tr[tr[t].u0].d0 = t;
01418                   tr[tr[t].u0].d1 = tn;
01419                 }
01420             }
01421 
01422           if (FP_EQUAL(tr[t].lo.y, tr[tlast].lo.y) && 
01423               FP_EQUAL(tr[t].lo.x, tr[tlast].lo.x) && tribot)
01424             {
01425               /* this case arises only at the lowest trapezoid.. i.e.
01426                  tlast, if the lower endpoint of the segment is
01427                  already inserted in the structure */
01428 
01429               tr[tr[t].d0].u0 = t;
01430               tr[tr[t].d0].u1 = -1;
01431               tr[tr[t].d1].u0 = tn;
01432               tr[tr[t].d1].u1 = -1;
01433 
01434               tr[tn].d0 = tr[t].d1;
01435               tr[tn].d1 = -1;
01436               tr[t].d1 = -1;
01437 
01438               tnext = tr[t].d1;
01439             }
01440           else if (i_d0)
01441                                 /* intersecting d0 */
01442             {
01443               tr[tr[t].d0].u0 = t;
01444               tr[tr[t].d0].u1 = tn;
01445               tr[tr[t].d1].u0 = tn;
01446               tr[tr[t].d1].u1 = -1;
01447 
01448               /* new code to determine the bottom neighbours of the */
01449               /* newly partitioned trapezoid */
01450 
01451               tr[t].d1 = -1;
01452 
01453               tnext = tr[t].d0;
01454             }
01455           else                  /* intersecting d1 */
01456             {
01457               tr[tr[t].d0].u0 = t;
01458               tr[tr[t].d0].u1 = -1;
01459               tr[tr[t].d1].u0 = t;
01460               tr[tr[t].d1].u1 = tn;
01461 
01462               /* new code to determine the bottom neighbours of the */
01463               /* newly partitioned trapezoid */
01464 
01465               tr[tn].d0 = tr[t].d1;
01466               tr[tn].d1 = -1;
01467 
01468               tnext = tr[t].d1;
01469             }
01470 
01471           t = tnext;
01472         }
01473       
01474       tr[tn_sav].lseg  = segnum;
01475       tr[t_sav].rseg = segnum;
01476     } /* end-while */
01477   
01478   /* Now combine those trapezoids which share common segments. We can */
01479   /* use the pointers to the parent to connect these together. This */
01480   /* works only because all these new trapezoids have been formed */
01481   /* due to splitting by the segment, and hence have only one parent */
01482 
01483   tfirstl = tfirst; 
01484   tlastl = tlast;
01485   merge_trapezoids(segnum, tfirstl, tlastl, S_LEFT);
01486   merge_trapezoids(segnum, tfirstr, tlastr, S_RIGHT);
01487 
01488   seg[segnum].is_inserted = true;
01489   return 0;
01490 }
01491 
01492 
01493 /* Update the roots stored for each of the endpoints of the segment.
01494  * This is done to speed up the location-query for the endpoint when
01495  * the segment is inserted into the trapezoidation subsequently
01496  */
01497 int Triangulator::
01498 find_new_roots(int segnum) {
01499   //  cerr << "find_new_roots(" << segnum << ")\n";
01500   segment_t *s = &seg[segnum];
01501   
01502   if (s->is_inserted)
01503     return 0;
01504 
01505   s->root0 = locate_endpoint(&s->v0, &s->v1, s->root0);
01506   s->root0 = tr[s->root0].sink;
01507 
01508   s->root1 = locate_endpoint(&s->v1, &s->v0, s->root1);
01509   s->root1 = tr[s->root1].sink;  
01510   return 0;
01511 }
01512 
01513 
01514 /* Main routine to perform trapezoidation */
01515 int Triangulator::
01516 construct_trapezoids(int nseg) {
01517   //cerr << "construct_trapezoids(" << nseg << ")\n";
01518   int i;
01519   int root, h;
01520   
01521   /* Add the first segment and get the query structure and trapezoid */
01522   /* list initialised */
01523 
01524   root = init_query_structure(choose_segment());
01525 
01526   for (i = 1; i <= nseg; i++) {
01527     seg[i].root1 = root;
01528     seg[i].root0 = root;
01529   }
01530   
01531   for (h = 1; h <= math_logstar_n(nseg); h++)
01532     {
01533       for (i = math_N(nseg, h -1) + 1; i <= math_N(nseg, h); i++) {
01534         if (add_segment(choose_segment()) != 0) {
01535           // error in add_segment.
01536           return 1;
01537         }
01538       }
01539       
01540       /* Find a new root for each of the segment endpoints */
01541       for (i = 1; i <= nseg; i++)
01542         find_new_roots(i);
01543     }
01544   
01545   for (i = math_N(nseg, math_logstar_n(nseg)) + 1; i <= nseg; i++)
01546     add_segment(choose_segment());
01547 
01548   return 0;
01549 }
01550 
01551 
01552 
01553 /* Function returns true if the trapezoid lies inside the polygon */
01554 int Triangulator::
01555 inside_polygon(trap_t *t) {
01556   int rseg = t->rseg;
01557 
01558   if (t->state == ST_INVALID)
01559     return 0;
01560 
01561   if ((t->lseg <= 0) || (t->rseg <= 0))
01562     return 0;
01563   
01564   if (((t->u0 <= 0) && (t->u1 <= 0)) || 
01565       ((t->d0 <= 0) && (t->d1 <= 0))) /* triangle */
01566     return (_greater_than(&seg[rseg].v1, &seg[rseg].v0));
01567   
01568   return 0;
01569 }
01570 
01571 
01572 /* return a new mon structure from the table */
01573 int Triangulator::
01574 newmon() {
01575   int index = (int)mon.size();
01576   mon.push_back(0);
01577   //  cerr << "newmon " << index << "\n";
01578   return index;
01579 }
01580 
01581 
01582 /* return a new chain element from the table */
01583 int Triangulator::
01584 new_chain_element() {
01585   int index = (int)mchain.size();
01586   mchain.push_back(monchain_t());
01587   //  cerr << "new_chain_element " << index << "\n";
01588   return index;
01589 }
01590 
01591 
01592 double Triangulator::
01593 get_angle(point_t *vp0, point_t *vpnext, point_t *vp1) {
01594   point_t v0, v1;
01595   
01596   v0.x = vpnext->x - vp0->x;
01597   v0.y = vpnext->y - vp0->y;
01598 
01599   v1.x = vp1->x - vp0->x;
01600   v1.y = vp1->y - vp0->y;
01601 
01602   if (CROSS_SINE(v0, v1) >= 0)  /* sine is positive */
01603     return DOT(v0, v1)/LENGTH(v0)/LENGTH(v1);
01604   else
01605     return (-1.0 * DOT(v0, v1)/LENGTH(v0)/LENGTH(v1) - 2);
01606 }
01607 
01608 
01609 /* (v0, v1) is the new diagonal to be added to the polygon. Find which */
01610 /* chain to use and return the positions of v0 and v1 in p and q */ 
01611 int Triangulator::
01612 get_vertex_positions(int v0, int v1, int *ip, int *iq) {
01613   vertexchain_t *vp0, *vp1;
01614   int i;
01615   double angle, temp;
01616   int tp = 0, tq = 0;
01617 
01618   vp0 = &vert[v0];
01619   vp1 = &vert[v1];
01620   
01621   /* p is identified as follows. Scan from (v0, v1) rightwards till */
01622   /* you hit the first segment starting from v0. That chain is the */
01623   /* chain of our interest */
01624   
01625   angle = -4.0;
01626   for (i = 0; i < 4; i++)
01627     {
01628       if (vp0->vnext[i] <= 0)
01629         continue;
01630       if ((temp = get_angle(&vp0->pt, &(vert[vp0->vnext[i]].pt), 
01631                             &vp1->pt)) > angle)
01632         {
01633           angle = temp;
01634           tp = i;
01635         }
01636     }
01637 
01638   *ip = tp;
01639 
01640   /* Do similar actions for q */
01641 
01642   angle = -4.0;
01643   for (i = 0; i < 4; i++)
01644     {
01645       if (vp1->vnext[i] <= 0)
01646         continue;      
01647       if ((temp = get_angle(&vp1->pt, &(vert[vp1->vnext[i]].pt), 
01648                             &vp0->pt)) > angle)
01649         {
01650           angle = temp;
01651           tq = i;
01652         }
01653     }
01654 
01655   *iq = tq;
01656 
01657   return 0;
01658 }
01659 
01660   
01661 /* v0 and v1 are specified in anti-clockwise order with respect to 
01662  * the current monotone polygon mcur. Split the current polygon into 
01663  * two polygons using the diagonal (v0, v1) 
01664  */
01665 int Triangulator::
01666 make_new_monotone_poly(int mcur, int v0, int v1) {
01667   int p, q, ip, iq;
01668   int mnew = newmon();
01669   int i, j, nf0, nf1;
01670   vertexchain_t *vp0, *vp1;
01671 
01672   if (v0 <= 0 || v1 <= 0) {
01673     return -1;
01674   }
01675   
01676   vp0 = &vert[v0];
01677   vp1 = &vert[v1];
01678 
01679   get_vertex_positions(v0, v1, &ip, &iq);
01680 
01681   p = vp0->vpos[ip];
01682   q = vp1->vpos[iq];
01683 
01684   /* At this stage, we have got the positions of v0 and v1 in the */
01685   /* desired chain. Now modify the linked lists */
01686 
01687   i = new_chain_element();      /* for the new list */
01688   j = new_chain_element();
01689 
01690   mchain[i].vnum = v0;
01691   mchain[j].vnum = v1;
01692 
01693   mchain[i].next = mchain[p].next;
01694   mchain[mchain[p].next].prev = i;
01695   mchain[i].prev = j;
01696   mchain[j].next = i;
01697   mchain[j].prev = mchain[q].prev;
01698   mchain[mchain[q].prev].next = j;
01699 
01700   mchain[p].next = q;
01701   mchain[q].prev = p;
01702 
01703   nf0 = vp0->nextfree;
01704   nf1 = vp1->nextfree;
01705 
01706   vp0->vnext[ip] = v1;
01707 
01708   vp0->vpos[nf0] = i;
01709   vp0->vnext[nf0] = mchain[mchain[i].next].vnum;
01710   vp1->vpos[nf1] = j;
01711   vp1->vnext[nf1] = v0;
01712 
01713   vp0->nextfree++;
01714   vp1->nextfree++;
01715 
01716 #ifdef DEBUG
01717   fprintf(stderr, "make_poly: mcur = %d, (v0, v1) = (%d, %d)\n", 
01718           mcur, v0, v1);
01719   fprintf(stderr, "next posns = (p, q) = (%d, %d)\n", p, q);
01720 #endif
01721 
01722   mon[mcur] = p;
01723   mon[mnew] = i;
01724   return mnew;
01725 }
01726 
01727 /* Main routine to get monotone polygons from the trapezoidation of 
01728  * the polygon.
01729  */
01730 
01731 int Triangulator::
01732 monotonate_trapezoids(int n) {
01733   int i;
01734   int tr_start;
01735 
01736   vert.clear();
01737   visited.clear();
01738   mchain.clear();
01739   mon.clear();
01740 
01741   vert.insert(vert.begin(), n + 1, vertexchain_t());
01742   mchain.insert(mchain.begin(), n + 1, monchain_t());
01743 
01744   visited.insert(visited.begin(), tr.size(), 0);
01745   
01746   /* First locate a trapezoid which lies inside the polygon */
01747   /* and which is triangular */
01748   for (i = 1; i < (int)tr.size(); i++)
01749     if (inside_polygon(&tr[i]))
01750       break;
01751   if (i >= (int)tr.size()) {
01752     // No valid trapezoids.
01753     return 0;
01754   }
01755   //  printf("start = %d\n", i);
01756   tr_start = i;
01757   
01758   /* Initialise the mon data-structure and start spanning all the */
01759   /* trapezoids within the polygon */
01760 
01761 #if 0
01762   for (i = 1; i <= n; i++)
01763     {
01764       mchain[i].prev = i - 1;
01765       mchain[i].next = i + 1;
01766       mchain[i].vnum = i;
01767       vert[i].pt = seg[i].v0;
01768       vert[i].vnext[0] = i + 1; /* next vertex */
01769       vert[i].vpos[0] = i;      /* locn. of next vertex */
01770       vert[i].nextfree = 1;
01771       vert[i].user_i = seg[i].v0_i;
01772     }
01773   mchain[1].prev = n;
01774   mchain[n].next = 1;
01775   vert[n].vnext[0] = 1;
01776   vert[n].vpos[0] = n;
01777   mon.push_back(1); /* position of any vertex in the first */
01778                     /* chain  */
01779 
01780 #else
01781 
01782   for (i = 1; i <= n; i++)
01783     {
01784       mchain[i].prev = seg[i].prev;
01785       mchain[i].next = seg[i].next;
01786       mchain[i].vnum = i;
01787       vert[i].pt = seg[i].v0;
01788       vert[i].vnext[0] = seg[i].next; /* next vertex */
01789       vert[i].vpos[0] = i;      /* locn. of next vertex */
01790       vert[i].nextfree = 1;
01791       vert[i].user_i = seg[i].v0_i;
01792     }
01793 
01794   mon.push_back(1); /* position of any vertex in the first */
01795                     /* chain  */
01796 
01797 #endif
01798   
01799   /* traverse the polygon */
01800   if (tr[tr_start].u0 > 0)
01801     traverse_polygon(0, tr_start, tr[tr_start].u0, TR_FROM_UP);
01802   else if (tr[tr_start].d0 > 0)
01803     traverse_polygon(0, tr_start, tr[tr_start].d0, TR_FROM_DN);
01804   
01805   /* return the number of polygons created */
01806   return newmon();
01807 }
01808 
01809 
01810 /* recursively visit all the trapezoids */
01811 int Triangulator::
01812 traverse_polygon(int mcur, int trnum, int from, int dir) {
01813   //  printf("traverse_polygon(%d, %d, %d, %d)\n", mcur, trnum, from, dir);
01814 
01815   if (mcur < 0 || trnum <= 0)
01816     return 0;
01817 
01818   if (visited[trnum])
01819     return 0;
01820 
01821   trap_t *t = &tr[trnum];
01822   //  int howsplit;
01823   int mnew;
01824   int v0, v1;  //, v0next, v1next;
01825   int retval = 0;  //, tmp;
01826   int do_switch = false;
01827 
01828   //  printf("visited size = %d, visited[trnum] = %d\n", visited.size(), visited[trnum]);
01829 
01830   visited[trnum] = true;
01831   
01832   /* We have much more information available here. */
01833   /* rseg: goes upwards   */
01834   /* lseg: goes downwards */
01835 
01836   /* Initially assume that dir = TR_FROM_DN (from the left) */
01837   /* Switch v0 and v1 if necessary afterwards */
01838 
01839 
01840   /* special cases for triangles with cusps at the opposite ends. */
01841   /* take care of this first */
01842   if ((t->u0 <= 0) && (t->u1 <= 0))
01843     {
01844       if ((t->d0 > 0) && (t->d1 > 0)) /* downward opening triangle */
01845         {
01846           v0 = tr[t->d1].lseg;
01847           v1 = t->lseg;
01848           if (from == t->d1)
01849             {
01850               do_switch = true;
01851               mnew = make_new_monotone_poly(mcur, v1, v0);
01852               traverse_polygon(mcur, t->d1, trnum, TR_FROM_UP);
01853               traverse_polygon(mnew, t->d0, trnum, TR_FROM_UP);
01854             }
01855           else
01856             {
01857               mnew = make_new_monotone_poly(mcur, v0, v1);
01858               traverse_polygon(mcur, t->d0, trnum, TR_FROM_UP);
01859               traverse_polygon(mnew, t->d1, trnum, TR_FROM_UP);
01860             }
01861         }
01862       else
01863         {
01864           retval = SP_NOSPLIT;  /* Just traverse all neighbours */
01865           traverse_polygon(mcur, t->u0, trnum, TR_FROM_DN);
01866           traverse_polygon(mcur, t->u1, trnum, TR_FROM_DN);
01867           traverse_polygon(mcur, t->d0, trnum, TR_FROM_UP);
01868           traverse_polygon(mcur, t->d1, trnum, TR_FROM_UP);
01869         }
01870     }
01871   
01872   else if ((t->d0 <= 0) && (t->d1 <= 0))
01873     {
01874       if ((t->u0 > 0) && (t->u1 > 0)) /* upward opening triangle */
01875         {
01876           v0 = t->rseg;
01877           v1 = tr[t->u0].rseg;
01878           if (from == t->u1)
01879             {
01880               do_switch = true;
01881               mnew = make_new_monotone_poly(mcur, v1, v0);
01882               traverse_polygon(mcur, t->u1, trnum, TR_FROM_DN);
01883               traverse_polygon(mnew, t->u0, trnum, TR_FROM_DN);
01884             }
01885           else
01886             {
01887               mnew = make_new_monotone_poly(mcur, v0, v1);
01888               traverse_polygon(mcur, t->u0, trnum, TR_FROM_DN);
01889               traverse_polygon(mnew, t->u1, trnum, TR_FROM_DN);
01890             }
01891         }
01892       else
01893         {
01894           retval = SP_NOSPLIT;  /* Just traverse all neighbours */
01895           traverse_polygon(mcur, t->u0, trnum, TR_FROM_DN);
01896           traverse_polygon(mcur, t->u1, trnum, TR_FROM_DN);
01897           traverse_polygon(mcur, t->d0, trnum, TR_FROM_UP);
01898           traverse_polygon(mcur, t->d1, trnum, TR_FROM_UP);
01899         }
01900     }
01901   
01902   else if ((t->u0 > 0) && (t->u1 > 0)) 
01903     {
01904       if ((t->d0 > 0) && (t->d1 > 0)) /* downward + upward cusps */
01905         {
01906           v0 = tr[t->d1].lseg;
01907           v1 = tr[t->u0].rseg;
01908           retval = SP_2UP_2DN;
01909           if (((dir == TR_FROM_DN) && (t->d1 == from)) ||
01910               ((dir == TR_FROM_UP) && (t->u1 == from)))
01911             {
01912               do_switch = true;
01913               mnew = make_new_monotone_poly(mcur, v1, v0);
01914               traverse_polygon(mcur, t->u1, trnum, TR_FROM_DN);
01915               traverse_polygon(mcur, t->d1, trnum, TR_FROM_UP);
01916               traverse_polygon(mnew, t->u0, trnum, TR_FROM_DN);
01917               traverse_polygon(mnew, t->d0, trnum, TR_FROM_UP);
01918             }
01919           else
01920             {
01921               mnew = make_new_monotone_poly(mcur, v0, v1);
01922               traverse_polygon(mcur, t->u0, trnum, TR_FROM_DN);
01923               traverse_polygon(mcur, t->d0, trnum, TR_FROM_UP);
01924               traverse_polygon(mnew, t->u1, trnum, TR_FROM_DN);
01925               traverse_polygon(mnew, t->d1, trnum, TR_FROM_UP);
01926             }
01927         }
01928       else                      /* only downward cusp */
01929         {
01930           if (_equal_to(&t->lo, &seg[t->lseg].v1))
01931             {
01932               v0 = tr[t->u0].rseg;
01933               v1 = seg[t->lseg].next;
01934 
01935               retval = SP_2UP_LEFT;
01936               if ((dir == TR_FROM_UP) && (t->u0 == from))
01937                 {
01938                   do_switch = true;
01939                   mnew = make_new_monotone_poly(mcur, v1, v0);
01940                   traverse_polygon(mcur, t->u0, trnum, TR_FROM_DN);
01941                   traverse_polygon(mnew, t->d0, trnum, TR_FROM_UP);
01942                   traverse_polygon(mnew, t->u1, trnum, TR_FROM_DN);
01943                   traverse_polygon(mnew, t->d1, trnum, TR_FROM_UP);
01944                 }
01945               else
01946                 {
01947                   mnew = make_new_monotone_poly(mcur, v0, v1);
01948                   traverse_polygon(mcur, t->u1, trnum, TR_FROM_DN);
01949                   traverse_polygon(mcur, t->d0, trnum, TR_FROM_UP);
01950                   traverse_polygon(mcur, t->d1, trnum, TR_FROM_UP);
01951                   traverse_polygon(mnew, t->u0, trnum, TR_FROM_DN);
01952                 }
01953             }
01954           else
01955             {
01956               v0 = t->rseg;
01957               v1 = tr[t->u0].rseg;
01958               retval = SP_2UP_RIGHT;
01959               if ((dir == TR_FROM_UP) && (t->u1 == from))
01960                 {
01961                   do_switch = true;
01962                   mnew = make_new_monotone_poly(mcur, v1, v0);
01963                   traverse_polygon(mcur, t->u1, trnum, TR_FROM_DN);
01964                   traverse_polygon(mnew, t->d1, trnum, TR_FROM_UP);
01965                   traverse_polygon(mnew, t->d0, trnum, TR_FROM_UP);
01966                   traverse_polygon(mnew, t->u0, trnum, TR_FROM_DN);
01967                 }
01968               else
01969                 {
01970                   mnew = make_new_monotone_poly(mcur, v0, v1);
01971                   traverse_polygon(mcur, t->u0, trnum, TR_FROM_DN);
01972                   traverse_polygon(mcur, t->d0, trnum, TR_FROM_UP);
01973                   traverse_polygon(mcur, t->d1, trnum, TR_FROM_UP);
01974                   traverse_polygon(mnew, t->u1, trnum, TR_FROM_DN);
01975                 }
01976             }
01977         }
01978     }
01979   else if ((t->u0 > 0) || (t->u1 > 0)) /* no downward cusp */
01980     {
01981       if ((t->d0 > 0) && (t->d1 > 0)) /* only upward cusp */
01982         {
01983           if (_equal_to(&t->hi, &seg[t->lseg].v0))
01984             {
01985               v0 = tr[t->d1].lseg;
01986               v1 = t->lseg;
01987               retval = SP_2DN_LEFT;
01988               if (!((dir == TR_FROM_DN) && (t->d0 == from)))
01989                 {
01990                   do_switch = true;
01991                   mnew = make_new_monotone_poly(mcur, v1, v0);
01992                   traverse_polygon(mcur, t->u1, trnum, TR_FROM_DN);
01993                   traverse_polygon(mcur, t->d1, trnum, TR_FROM_UP);
01994                   traverse_polygon(mcur, t->u0, trnum, TR_FROM_DN);
01995                   traverse_polygon(mnew, t->d0, trnum, TR_FROM_UP);
01996                 }
01997               else
01998                 {
01999                   mnew = make_new_monotone_poly(mcur, v0, v1);
02000                   traverse_polygon(mcur, t->d0, trnum, TR_FROM_UP);
02001                   traverse_polygon(mnew, t->u0, trnum, TR_FROM_DN);
02002                   traverse_polygon(mnew, t->u1, trnum, TR_FROM_DN);
02003                   traverse_polygon(mnew, t->d1, trnum, TR_FROM_UP);
02004                 }
02005             }
02006           else
02007             {
02008               v0 = tr[t->d1].lseg;
02009               v1 = seg[t->rseg].next;
02010 
02011               retval = SP_2DN_RIGHT;
02012               if ((dir == TR_FROM_DN) && (t->d1 == from))
02013                 {
02014                   do_switch = true;
02015                   mnew = make_new_monotone_poly(mcur, v1, v0);
02016                   traverse_polygon(mcur, t->d1, trnum, TR_FROM_UP);
02017                   traverse_polygon(mnew, t->u1, trnum, TR_FROM_DN);
02018                   traverse_polygon(mnew, t->u0, trnum, TR_FROM_DN);
02019                   traverse_polygon(mnew, t->d0, trnum, TR_FROM_UP);
02020                 }
02021               else
02022                 {
02023                   mnew = make_new_monotone_poly(mcur, v0, v1);
02024                   traverse_polygon(mcur, t->u0, trnum, TR_FROM_DN);
02025                   traverse_polygon(mcur, t->d0, trnum, TR_FROM_UP);
02026                   traverse_polygon(mcur, t->u1, trnum, TR_FROM_DN);
02027                   traverse_polygon(mnew, t->d1, trnum, TR_FROM_UP);
02028                 }
02029             }
02030         }
02031       else                      /* no cusp */
02032         {
02033           if (_equal_to(&t->hi, &seg[t->lseg].v0) &&
02034               _equal_to(&t->lo, &seg[t->rseg].v0))
02035             {
02036               v0 = t->rseg;
02037               v1 = t->lseg;
02038               retval = SP_SIMPLE_LRDN;
02039               if (dir == TR_FROM_UP)
02040                 {
02041                   do_switch = true;
02042                   mnew = make_new_monotone_poly(mcur, v1, v0);
02043                   traverse_polygon(mcur, t->u0, trnum, TR_FROM_DN);
02044                   traverse_polygon(mcur, t->u1, trnum, TR_FROM_DN);
02045                   traverse_polygon(mnew, t->d1, trnum, TR_FROM_UP);
02046                   traverse_polygon(mnew, t->d0, trnum, TR_FROM_UP);
02047                 }
02048               else
02049                 {
02050                   mnew = make_new_monotone_poly(mcur, v0, v1);
02051                   traverse_polygon(mcur, t->d1, trnum, TR_FROM_UP);
02052                   traverse_polygon(mcur, t->d0, trnum, TR_FROM_UP);
02053                   traverse_polygon(mnew, t->u0, trnum, TR_FROM_DN);
02054                   traverse_polygon(mnew, t->u1, trnum, TR_FROM_DN);
02055                 }
02056             }
02057           else if (_equal_to(&t->hi, &seg[t->rseg].v1) &&
02058                    _equal_to(&t->lo, &seg[t->lseg].v1))
02059             {
02060               v0 = seg[t->rseg].next;
02061               v1 = seg[t->lseg].next;
02062 
02063               retval = SP_SIMPLE_LRUP;
02064               if (dir == TR_FROM_UP)
02065                 {
02066                   do_switch = true;
02067                   mnew = make_new_monotone_poly(mcur, v1, v0);
02068                   traverse_polygon(mcur, t->u0, trnum, TR_FROM_DN);
02069                   traverse_polygon(mcur, t->u1, trnum, TR_FROM_DN);
02070                   traverse_polygon(mnew, t->d1, trnum, TR_FROM_UP);
02071                   traverse_polygon(mnew, t->d0, trnum, TR_FROM_UP);
02072                 }
02073               else
02074                 {
02075                   mnew = make_new_monotone_poly(mcur, v0, v1);
02076                   traverse_polygon(mcur, t->d1, trnum, TR_FROM_UP);
02077                   traverse_polygon(mcur, t->d0, trnum, TR_FROM_UP);
02078                   traverse_polygon(mnew, t->u0, trnum, TR_FROM_DN);
02079                   traverse_polygon(mnew, t->u1, trnum, TR_FROM_DN);
02080                 }
02081             }
02082           else                  /* no split possible */
02083             {
02084               retval = SP_NOSPLIT;
02085               traverse_polygon(mcur, t->u0, trnum, TR_FROM_DN);
02086               traverse_polygon(mcur, t->d0, trnum, TR_FROM_UP);
02087               traverse_polygon(mcur, t->u1, trnum, TR_FROM_DN);
02088               traverse_polygon(mcur, t->d1, trnum, TR_FROM_UP);
02089             }
02090         }
02091     }
02092 
02093   return retval;
02094 }
02095 
02096 
02097 /* For each monotone polygon, find the ymax and ymin (to determine the */
02098 /* two y-monotone chains) and pass on this monotone polygon for greedy */
02099 /* triangulation. */
02100 /* Take care not to triangulate duplicate monotone polygons */
02101 
02102 void Triangulator::
02103 triangulate_monotone_polygons(int nvert, int nmonpoly) {
02104   int i;
02105   point_t ymax, ymin;
02106   int p, vfirst, posmax, posmin, v;
02107   int vcount, processed;
02108 
02109   #ifdef DEBUG
02110   for (i = 0; i < nmonpoly; i++)
02111     {
02112       fprintf(stderr, "\n\nPolygon %d: ", i);
02113       vfirst = mchain[mon[i]].vnum;
02114       p = mchain[mon[i]].next;
02115       fprintf (stderr, "%d ", mchain[mon[i]].vnum);
02116       while (mchain[p].vnum != vfirst)
02117         {
02118           fprintf(stderr, "%d ", mchain[p].vnum);
02119           if (mchain[p].vnum == -1) {
02120             fprintf(stderr, " xx");
02121             break;
02122           }
02123           p = mchain[p].next;
02124         }
02125     }
02126   fprintf(stderr, "\n");
02127   #endif
02128 
02129   for (i = 0; i < nmonpoly; i++)
02130     {
02131       vcount = 1;
02132       processed = false;
02133       vfirst = mchain[mon[i]].vnum;
02134       if (vfirst <= 0) {
02135         return;
02136       }
02137       ymin = vert[vfirst].pt;
02138       ymax = ymin;
02139       posmin = mon[i];
02140       posmax = posmin;
02141       mchain[mon[i]].marked = true;
02142       p = mchain[mon[i]].next;
02143       while ((v = mchain[p].vnum) != vfirst)
02144         {
02145           if (v <= 0) {
02146             return;
02147           }
02148           if (mchain[p].marked)
02149            {
02150              processed = true;
02151              break;             /* break from while */
02152            }
02153           else
02154             mchain[p].marked = true;
02155           
02156           if (_greater_than(&vert[v].pt, &ymax))
02157             {
02158               ymax = vert[v].pt;
02159               posmax = p;
02160             }
02161           if (_less_than(&vert[v].pt, &ymin))
02162             {
02163               ymin = vert[v].pt;
02164               posmin = p;
02165             }
02166           p = mchain[p].next;
02167           vcount++;
02168        }
02169 
02170       if (processed)            /* Go to next polygon */
02171         continue;
02172       
02173       if (vcount == 3)          /* already a triangle */
02174         {
02175           _result.push_back(Triangle(this, mchain[p].vnum,
02176                                      mchain[mchain[p].next].vnum,
02177                                      mchain[mchain[p].prev].vnum));
02178         }
02179       else                      /* triangulate the polygon */
02180         {
02181           v = mchain[mchain[posmax].next].vnum;
02182           if (_equal_to(&vert[v].pt, &ymin))
02183             {                   /* LHS is a single line */
02184               triangulate_single_polygon(nvert, posmax, TRI_LHS);
02185             }
02186           else
02187             triangulate_single_polygon(nvert, posmax, TRI_RHS);
02188         }
02189     }
02190 }
02191 
02192 
02193 /* A greedy corner-cutting algorithm to triangulate a y-monotone 
02194  * polygon in O(n) time.
02195  * Joseph O-Rourke, Computational Geometry in C.
02196  */
02197 void Triangulator::
02198 triangulate_single_polygon(int nvert, int posmax, int side) {
02199   int v;
02200   vector_int rc;        /* reflex chain */
02201   int ri;
02202   int endv, tmp, vpos;
02203 
02204   //cerr << "triangulate_single_polygon(" << nvert << ", " << posmax << ", " << side << ")\n";
02205 
02206   if (side == TRI_RHS)          /* RHS segment is a single segment */
02207     {
02208       rc.push_back(mchain[posmax].vnum);
02209       tmp = mchain[posmax].next;
02210       rc.push_back(mchain[tmp].vnum);
02211       ri = 1;
02212       
02213       vpos = mchain[tmp].next;
02214       v = mchain[vpos].vnum;
02215       
02216       if ((endv = mchain[mchain[posmax].prev].vnum) == 0)
02217         endv = nvert;
02218     }
02219   else                          /* LHS is a single segment */
02220     {
02221       tmp = mchain[posmax].next;
02222       rc.push_back(mchain[tmp].vnum);
02223       tmp = mchain[tmp].next;
02224       rc.push_back(mchain[tmp].vnum);
02225       ri = 1;
02226 
02227       vpos = mchain[tmp].next;
02228       v = mchain[vpos].vnum;
02229 
02230       endv = mchain[posmax].vnum;
02231     }
02232   
02233   while ((v != endv) || (ri > 1))
02234     {
02235       //cerr << " v = " << v << " ri = " << ri << " rc = " << rc.size() << " _result = " << _result.size() << "\n";
02236       if (v <= 0) {
02237         // Something went wrong.
02238         return;
02239       }
02240       if (ri > 0)               /* reflex chain is non-empty */
02241         {
02242           PN_stdfloat crossResult = CROSS(vert[v].pt, vert[rc[ri - 1]].pt,
02243                                     vert[rc[ri]].pt);
02244           if ( crossResult >= 0 )  /* could be convex corner or straight */
02245             {
02246               if ( crossResult > 0)  /* convex corner: cut it off */
02247                 _result.push_back(Triangle(this, rc[ri - 1], rc[ri], v));
02248               /* else : perfectly straight, will be abandoned anyway */
02249               ri--;
02250               rc.pop_back();
02251               nassertv(ri + 1 == (int)rc.size());
02252             }
02253           else /* concave, add v to the chain */
02254             {
02255               ri++;
02256               rc.push_back(v);
02257               nassertv(ri + 1 == (int)rc.size());
02258               vpos = mchain[vpos].next;
02259               v = mchain[vpos].vnum;
02260             }
02261         }
02262       else                      /* reflex-chain empty: add v to the */
02263         {                       /* reflex chain and advance it  */
02264           ri++;
02265           rc.push_back(v);
02266           nassertv(ri + 1 == (int)rc.size());
02267           vpos = mchain[vpos].next;
02268           v = mchain[vpos].vnum;
02269         }
02270     } /* end-while */
02271   
02272   /* reached the bottom vertex. Add in the triangle formed */
02273   _result.push_back(Triangle(this, rc[ri - 1], rc[ri], v));  
02274   ri--;
02275 }
02276 
02277