]> granicus.if.org Git - poly2tri-c/commitdiff
Convert line endings to unix format (\n instead of \r\n)
authorBarak Itkin <lightningismyname@gmail.com>
Fri, 1 Jun 2012 17:21:30 +0000 (20:21 +0300)
committerBarak Itkin <lightningismyname@gmail.com>
Fri, 1 Jun 2012 17:21:30 +0000 (20:21 +0300)
16 files changed:
p2t/common/utils.h
p2t/sweep/cdt.c
p2t/sweep/cdt.h
p2t/sweep/sweep.c
p2t/sweep/sweep_context.h
refine/bounded-line.c
refine/bounded-line.h
refine/circle.c
refine/circle.h
refine/line.c
refine/line.h
refine/rmath.c
refine/rmath.h
refine/vector2.c
refine/vector2.h
render/svg-plot.h

index 014fc1630ba37253668d804c366e1674a271605d..0031b65f763242c30a17ffd8b699a6bb3906cc50 100644 (file)
@@ -1,63 +1,63 @@
-/* \r
- * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors\r
- * http://code.google.com/p/poly2tri/\r
- *\r
- * All rights reserved.\r
- *\r
- * Redistribution and use in source and binary forms, with or without modification,\r
- * are permitted provided that the following conditions are met:\r
- *\r
- * * Redistributions of source code must retain the above copyright notice,\r
- *   this list of conditions and the following disclaimer.\r
- * * Redistributions in binary form must reproduce the above copyright notice,\r
- *   this list of conditions and the following disclaimer in the documentation\r
- *   and/or other materials provided with the distribution.\r
- * * Neither the name of Poly2Tri nor the names of its contributors may be\r
- *   used to endorse or promote products derived from this software without specific\r
- *   prior written permission.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\r
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\r
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\r
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\r
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\r
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\r
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
- */\r
-\r
-#ifndef UTILS_H\r
-#define UTILS_H\r
-\r
-#include <glib.h>\r
-#include "poly2tri-private.h"\r
-#include "cutils.h"\r
-#include "shapes.h"\r
-\r
-#define PI_3div4 (3 * G_PI / 4)\r
-#define EPSILON  (1e-6)\r
-\r
-typedef enum\r
-{\r
-  CW, CCW, COLLINEAR\r
-} P2tOrientation;\r
-\r
-/**\r
- * Forumla to calculate signed area<br>\r
- * Positive if CCW<br>\r
- * Negative if CW<br>\r
- * 0 if collinear<br>\r
- * <pre>\r
- * A[P1,P2,P3]  =  (x1*y2 - y1*x2) + (x2*y3 - y2*x3) + (x3*y1 - y3*x1)\r
- *              =  (x1-x3)*(y2-y3) - (y1-y3)*(x2-x3)\r
- * </pre>\r
- */\r
-P2tOrientation p2t_orient2d (P2tPoint* pa, P2tPoint* pb, P2tPoint* pc);\r
-\r
-gboolean p2t_utils_in_scan_area (P2tPoint* pa, P2tPoint* pb, P2tPoint* pc, P2tPoint* pd);\r
-\r
-#endif\r
-\r
+/* 
+ * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
+ * http://code.google.com/p/poly2tri/
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of Poly2Tri nor the names of its contributors may be
+ *   used to endorse or promote products derived from this software without specific
+ *   prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef UTILS_H
+#define UTILS_H
+
+#include <glib.h>
+#include "poly2tri-private.h"
+#include "cutils.h"
+#include "shapes.h"
+
+#define PI_3div4 (3 * G_PI / 4)
+#define EPSILON  (1e-6)
+
+typedef enum
+{
+  CW, CCW, COLLINEAR
+} P2tOrientation;
+
+/**
+ * Forumla to calculate signed area<br>
+ * Positive if CCW<br>
+ * Negative if CW<br>
+ * 0 if collinear<br>
+ * <pre>
+ * A[P1,P2,P3]  =  (x1*y2 - y1*x2) + (x2*y3 - y2*x3) + (x3*y1 - y3*x1)
+ *              =  (x1-x3)*(y2-y3) - (y1-y3)*(x2-x3)
+ * </pre>
+ */
+P2tOrientation p2t_orient2d (P2tPoint* pa, P2tPoint* pb, P2tPoint* pc);
+
+gboolean p2t_utils_in_scan_area (P2tPoint* pa, P2tPoint* pb, P2tPoint* pc, P2tPoint* pd);
+
+#endif
+
index 49785e6ec1e81b506fcf620312da973753b74d5b..4ed05031503d874d6ac09c6c0bc256d0d0fe6aef 100644 (file)
@@ -1,90 +1,90 @@
-/* \r
- * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors\r
- * http://code.google.com/p/poly2tri/\r
- *\r
- * All rights reserved.\r
- *\r
- * Redistribution and use in source and binary forms, with or without modification,\r
- * are permitted provided that the following conditions are met:\r
- *\r
- * * Redistributions of source code must retain the above copyright notice,\r
- *   this list of conditions and the following disclaimer.\r
- * * Redistributions in binary form must reproduce the above copyright notice,\r
- *   this list of conditions and the following disclaimer in the documentation\r
- *   and/or other materials provided with the distribution.\r
- * * Neither the name of Poly2Tri nor the names of its contributors may be\r
- *   used to endorse or promote products derived from this software without specific\r
- *   prior written permission.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\r
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\r
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\r
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\r
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\r
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\r
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
- */\r
-#include "cdt.h"\r
-\r
-void\r
-p2t_cdt_init (P2tCDT* THIS, P2tPointPtrArray polyline)\r
-{\r
-  THIS->sweep_context_ = p2t_sweepcontext_new (polyline);\r
-  THIS->sweep_ = p2t_sweep_new ();\r
-}\r
-\r
-P2tCDT*\r
-p2t_cdt_new (P2tPointPtrArray polyline)\r
-{\r
-  P2tCDT* THIS = g_slice_new (P2tCDT);\r
-  p2t_cdt_init (THIS, polyline);\r
-  return THIS;\r
-}\r
-\r
-void\r
-p2t_cdt_destroy (P2tCDT* THIS)\r
-{\r
-  p2t_sweepcontext_delete (THIS->sweep_context_);\r
-  p2t_sweep_free (THIS->sweep_);\r
-}\r
-\r
-void\r
-p2t_cdt_free (P2tCDT* THIS)\r
-{\r
-  p2t_cdt_destroy (THIS);\r
-  g_slice_free (P2tCDT, THIS);\r
-}\r
-\r
-void\r
-p2t_cdt_add_hole (P2tCDT *THIS, P2tPointPtrArray polyline)\r
-{\r
-  p2t_sweepcontext_add_hole (THIS->sweep_context_, polyline);\r
-}\r
-\r
-void\r
-p2t_cdt_add_point (P2tCDT *THIS, P2tPoint* point)\r
-{\r
-  p2t_sweepcontext_add_point (THIS->sweep_context_, point);\r
-}\r
-\r
-void\r
-p2t_cdt_triangulate (P2tCDT *THIS)\r
-{\r
-  p2t_sweep_triangulate (THIS->sweep_, THIS->sweep_context_);\r
-}\r
-\r
-P2tTrianglePtrArray\r
-p2t_cdt_get_triangles (P2tCDT *THIS)\r
-{\r
-  return p2t_sweepcontext_get_triangles (THIS->sweep_context_);\r
-}\r
-\r
-P2tTrianglePtrList\r
-p2t_cdt_get_map (P2tCDT *THIS)\r
-{\r
-  return p2t_sweepcontext_get_map (THIS->sweep_context_);\r
-}\r
+/* 
+ * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
+ * http://code.google.com/p/poly2tri/
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of Poly2Tri nor the names of its contributors may be
+ *   used to endorse or promote products derived from this software without specific
+ *   prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include "cdt.h"
+
+void
+p2t_cdt_init (P2tCDT* THIS, P2tPointPtrArray polyline)
+{
+  THIS->sweep_context_ = p2t_sweepcontext_new (polyline);
+  THIS->sweep_ = p2t_sweep_new ();
+}
+
+P2tCDT*
+p2t_cdt_new (P2tPointPtrArray polyline)
+{
+  P2tCDT* THIS = g_slice_new (P2tCDT);
+  p2t_cdt_init (THIS, polyline);
+  return THIS;
+}
+
+void
+p2t_cdt_destroy (P2tCDT* THIS)
+{
+  p2t_sweepcontext_delete (THIS->sweep_context_);
+  p2t_sweep_free (THIS->sweep_);
+}
+
+void
+p2t_cdt_free (P2tCDT* THIS)
+{
+  p2t_cdt_destroy (THIS);
+  g_slice_free (P2tCDT, THIS);
+}
+
+void
+p2t_cdt_add_hole (P2tCDT *THIS, P2tPointPtrArray polyline)
+{
+  p2t_sweepcontext_add_hole (THIS->sweep_context_, polyline);
+}
+
+void
+p2t_cdt_add_point (P2tCDT *THIS, P2tPoint* point)
+{
+  p2t_sweepcontext_add_point (THIS->sweep_context_, point);
+}
+
+void
+p2t_cdt_triangulate (P2tCDT *THIS)
+{
+  p2t_sweep_triangulate (THIS->sweep_, THIS->sweep_context_);
+}
+
+P2tTrianglePtrArray
+p2t_cdt_get_triangles (P2tCDT *THIS)
+{
+  return p2t_sweepcontext_get_triangles (THIS->sweep_context_);
+}
+
+P2tTrianglePtrList
+p2t_cdt_get_map (P2tCDT *THIS)
+{
+  return p2t_sweepcontext_get_map (THIS->sweep_context_);
+}
index fdc57af64d7f377061a862ef65a4d23bbf09c04b..4428467de169c9876618bb69e0d3480921f01c4d 100644 (file)
-/* \r
- * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors\r
- * http://code.google.com/p/poly2tri/\r
- *\r
- * All rights reserved.\r
- *\r
- * Redistribution and use in source and binary forms, with or without modification,\r
- * are permitted provided that the following conditions are met:\r
- *\r
- * * Redistributions of source code must retain the above copyright notice,\r
- *   this list of conditions and the following disclaimer.\r
- * * Redistributions in binary form must reproduce the above copyright notice,\r
- *   this list of conditions and the following disclaimer in the documentation\r
- *   and/or other materials provided with the distribution.\r
- * * Neither the name of Poly2Tri nor the names of its contributors may be\r
- *   used to endorse or promote products derived from this software without specific\r
- *   prior written permission.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\r
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\r
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\r
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\r
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\r
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\r
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
- */\r
-\r
-#ifndef CDT_H\r
-#define CDT_H\r
-\r
-#include "../common/poly2tri-private.h"\r
-#include "advancing_front.h"\r
-#include "sweep_context.h"\r
-#include "sweep.h"\r
-\r
-/**\r
- * \r
- * @author Mason Green <mason.green@gmail.com>\r
- *\r
- */\r
-\r
-struct CDT_\r
-{\r
-  /*private: */\r
-\r
-  /**\r
-   * Internals\r
-   */\r
-\r
-  P2tSweepContext* sweep_context_;\r
-  P2tSweep* sweep_;\r
-\r
-};\r
-/**\r
- * Constructor - add polyline with non repeating points\r
- *\r
- * @param polyline\r
- */\r
-void p2t_cdt_init (P2tCDT* THIS, P2tPointPtrArray polyline);\r
-P2tCDT* p2t_cdt_new (P2tPointPtrArray polyline);\r
-\r
-/**\r
- * Destructor - clean up memory\r
- */\r
-void p2t_cdt_destroy (P2tCDT* THIS);\r
-void p2t_cdt_free (P2tCDT* THIS);\r
-\r
-/**\r
- * Add a hole\r
- *\r
- * @param polyline\r
- */\r
-void p2t_cdt_add_hole (P2tCDT *THIS, P2tPointPtrArray polyline);\r
-\r
-/**\r
- * Add a steiner point\r
- *\r
- * @param point\r
- */\r
-void p2t_cdt_add_point (P2tCDT *THIS, P2tPoint* point);\r
-\r
-/**\r
- * Triangulate - do this AFTER you've added the polyline, holes, and Steiner points\r
- */\r
-void p2t_cdt_triangulate (P2tCDT *THIS);\r
-\r
-/**\r
- * Get CDT triangles\r
- */\r
-P2tTrianglePtrArray p2t_cdt_get_triangles (P2tCDT *THIS);\r
-\r
-/**\r
- * Get triangle map\r
- */\r
-P2tTrianglePtrList p2t_cdt_get_map (P2tCDT *THIS);\r
-\r
-#endif\r
+/* 
+ * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
+ * http://code.google.com/p/poly2tri/
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of Poly2Tri nor the names of its contributors may be
+ *   used to endorse or promote products derived from this software without specific
+ *   prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef CDT_H
+#define CDT_H
+
+#include "../common/poly2tri-private.h"
+#include "advancing_front.h"
+#include "sweep_context.h"
+#include "sweep.h"
+
+/**
+ * 
+ * @author Mason Green <mason.green@gmail.com>
+ *
+ */
+
+struct CDT_
+{
+  /*private: */
+
+  /**
+   * Internals
+   */
+
+  P2tSweepContext* sweep_context_;
+  P2tSweep* sweep_;
+
+};
+/**
+ * Constructor - add polyline with non repeating points
+ *
+ * @param polyline
+ */
+void p2t_cdt_init (P2tCDT* THIS, P2tPointPtrArray polyline);
+P2tCDT* p2t_cdt_new (P2tPointPtrArray polyline);
+
+/**
+ * Destructor - clean up memory
+ */
+void p2t_cdt_destroy (P2tCDT* THIS);
+void p2t_cdt_free (P2tCDT* THIS);
+
+/**
+ * Add a hole
+ *
+ * @param polyline
+ */
+void p2t_cdt_add_hole (P2tCDT *THIS, P2tPointPtrArray polyline);
+
+/**
+ * Add a steiner point
+ *
+ * @param point
+ */
+void p2t_cdt_add_point (P2tCDT *THIS, P2tPoint* point);
+
+/**
+ * Triangulate - do this AFTER you've added the polyline, holes, and Steiner points
+ */
+void p2t_cdt_triangulate (P2tCDT *THIS);
+
+/**
+ * Get CDT triangles
+ */
+P2tTrianglePtrArray p2t_cdt_get_triangles (P2tCDT *THIS);
+
+/**
+ * Get triangle map
+ */
+P2tTrianglePtrList p2t_cdt_get_map (P2tCDT *THIS);
+
+#endif
index 3a63399829891345802213d871a531935c5bc598..71c084eee8e1fdb15cd5379ec84ab6b3cd1dba7f 100644 (file)
-/*\r
- * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors\r
- * http://code.google.com/p/poly2tri/\r
- * \r
- *\r
- * All rights reserved.\r
- *\r
- * Redistribution and use in source and binary forms, with or without modification,\r
- * are permitted provided that the following conditions are met:\r
- *\r
- * * Redistributions of source code must retain the above copyright notice,\r
- *   this list of conditions and the following disclaimer.\r
- * * Redistributions in binary form must reproduce the above copyright notice,\r
- *   this list of conditions and the following disclaimer in the documentation\r
- *   and/or other materials provided with the distribution.\r
- * * Neither the name of Poly2Tri nor the names of its contributors may be\r
- *   used to endorse or promote products derived from this software without specific\r
- *   prior written permission.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\r
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\r
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\r
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\r
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\r
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\r
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
- */\r
-#include <math.h>\r
-\r
-#include "sweep.h"\r
-#include "sweep_context.h"\r
-#include "advancing_front.h"\r
-#include "../common/utils.h"\r
-#include "../common/shapes.h"\r
-\r
-void\r
-p2t_sweep_init (P2tSweep* THIS)\r
-{\r
-  THIS->nodes_ = g_ptr_array_new ();\r
-}\r
-\r
-P2tSweep*\r
-p2t_sweep_new ()\r
-{\r
-  P2tSweep* THIS = g_new (P2tSweep, 1);\r
-  p2t_sweep_init (THIS);\r
-  return THIS;\r
-}\r
-\r
-/**\r
- * Destructor - clean up memory\r
- */\r
-void\r
-p2t_sweep_destroy (P2tSweep* THIS)\r
-{\r
-  int i;\r
-  /* Clean up memory */\r
-  for (i = 0; i < THIS->nodes_->len; i++)\r
-    {\r
-      p2t_node_free (node_index (THIS->nodes_, i));\r
-    }\r
-\r
-  g_ptr_array_free (THIS->nodes_, TRUE);\r
-}\r
-\r
-void\r
-p2t_sweep_free (P2tSweep* THIS)\r
-{\r
-  p2t_sweep_destroy (THIS);\r
-  g_free (THIS);\r
-}\r
-\r
-/* Triangulate simple polygon with holes */\r
-\r
-void\r
-p2t_sweep_triangulate (P2tSweep *THIS, P2tSweepContext *tcx)\r
-{\r
-  p2t_sweepcontext_init_triangulation (tcx);\r
-  p2t_sweepcontext_create_advancingfront (tcx, THIS->nodes_);\r
-  /* Sweep points; build mesh */\r
-  p2t_sweep_sweep_points (THIS, tcx);\r
-  /* Clean up */\r
-  p2t_sweep_finalization_polygon (THIS, tcx);\r
-}\r
-\r
-void\r
-p2t_sweep_sweep_points (P2tSweep *THIS, P2tSweepContext *tcx)\r
-{\r
-  int i, j;\r
-  for (i = 1; i < p2t_sweepcontext_point_count (tcx); i++)\r
-    {\r
-      P2tPoint* point = p2t_sweepcontext_get_point (tcx, i);\r
-      P2tNode* node = p2t_sweep_point_event (THIS, tcx, point);\r
-      for (j = 0; j < point->edge_list->len; j++)\r
-        {\r
-          p2t_sweep_edge_event_ed_n (THIS, tcx, edge_index (point->edge_list, j), node);\r
-        }\r
-    }\r
-}\r
-\r
-void\r
-p2t_sweep_finalization_polygon (P2tSweep *THIS, P2tSweepContext *tcx)\r
-{\r
-  /* Get an Internal triangle to start with */\r
-  P2tTriangle* t = p2t_advancingfront_head (p2t_sweepcontext_front (tcx))->next->triangle;\r
-  P2tPoint* p = p2t_advancingfront_head (p2t_sweepcontext_front (tcx))->next->point;\r
-  while (!p2t_triangle_get_constrained_edge_cw (t, p))\r
-    {\r
-      t = p2t_triangle_neighbor_ccw (t, p);\r
-    }\r
-\r
-  /* Collect interior triangles constrained by edges */\r
-  p2t_sweepcontext_mesh_clean (tcx, t);\r
-}\r
-\r
-P2tNode*\r
-p2t_sweep_point_event (P2tSweep *THIS, P2tSweepContext *tcx, P2tPoint* point)\r
-{\r
-  P2tNode* node = p2t_sweepcontext_locate_node (tcx, point);\r
-  P2tNode* new_node = p2t_sweep_new_front_triangle (THIS, tcx, point, node);\r
-\r
-  /* Only need to check +epsilon since point never have smaller\r
-   * x value than node due to how we fetch nodes from the front */\r
-  if (point->x <= node->point->x + EPSILON)\r
-    {\r
-      p2t_sweep_fill (THIS, tcx, node);\r
-    }\r
-\r
-  /*tcx.AddNode(new_node); */\r
-\r
-  p2t_sweep_fill_advancingfront (THIS, tcx, new_node);\r
-  return new_node;\r
-}\r
-\r
-void\r
-p2t_sweep_edge_event_ed_n (P2tSweep *THIS, P2tSweepContext *tcx, P2tEdge* edge, P2tNode* node)\r
-{\r
-  tcx->edge_event.constrained_edge = edge;\r
-  tcx->edge_event.right = (edge->p->x > edge->q->x);\r
-\r
-  if (p2t_sweep_is_edge_side_of_triangle (THIS, node->triangle, edge->p, edge->q))\r
-    {\r
-      return;\r
-    }\r
-\r
-  /* For now we will do all needed filling\r
-   * TODO: integrate with flip process might give some better performance\r
-   *       but for now this avoid the issue with cases that needs both flips and fills\r
-   */\r
-  p2t_sweep_fill_edge_event (THIS, tcx, edge, node);\r
-  p2t_sweep_edge_event_pt_pt_tr_pt (THIS, tcx, edge->p, edge->q, node->triangle, edge->q);\r
-}\r
-\r
-void\r
-p2t_sweep_edge_event_pt_pt_tr_pt (P2tSweep *THIS, P2tSweepContext *tcx, P2tPoint* ep, P2tPoint* eq, P2tTriangle* triangle, P2tPoint* point)\r
-{\r
-  P2tPoint *p1, *p2;\r
-  P2tOrientation o1, o2;\r
-\r
-  if (p2t_sweep_is_edge_side_of_triangle (THIS, triangle, ep, eq))\r
-    {\r
-      return;\r
-    }\r
-\r
-  p1 = p2t_triangle_point_ccw (triangle, point);\r
-  o1 = p2t_orient2d (eq, p1, ep);\r
-  if (o1 == COLLINEAR)\r
-    {\r
-      if (p2t_triangle_contains_pt_pt (triangle, eq, p1))\r
-        {\r
-          p2t_triangle_mark_constrained_edge_pt_pt (triangle, eq, p1);\r
-          /* We are modifying the constraint maybe it would be better to\r
-           * not change the given constraint and just keep a variable for the new constraint\r
-           */\r
-          tcx->edge_event.constrained_edge->q = p1;\r
-          triangle = p2t_triangle_neighbor_across (triangle, point);\r
-          p2t_sweep_edge_event_pt_pt_tr_pt (THIS, tcx, ep, p1, triangle, p1);\r
-        }\r
-      else\r
-        {\r
-          g_error ("EdgeEvent - collinear points not supported");\r
-        }\r
-      return;\r
-    }\r
-\r
-  p2 = p2t_triangle_point_cw (triangle, point);\r
-  o2 = p2t_orient2d (eq, p2, ep);\r
-  if (o2 == COLLINEAR)\r
-    {\r
-      if (p2t_triangle_contains_pt_pt (triangle, eq, p2))\r
-        {\r
-          p2t_triangle_mark_constrained_edge_pt_pt (triangle, eq, p2);\r
-          /* We are modifying the constraint maybe it would be better to\r
-           * not change the given constraint and just keep a variable for the new constraint\r
-           */\r
-          tcx->edge_event.constrained_edge->q = p2;\r
-          triangle = p2t_triangle_neighbor_across (triangle, point);\r
-          p2t_sweep_edge_event_pt_pt_tr_pt (THIS, tcx, ep, p2, triangle, p2);\r
-        }\r
-      else\r
-        {\r
-          g_error ("EdgeEvent - collinear points not supported");\r
-        }\r
-      return;\r
-    }\r
-\r
-  if (o1 == o2)\r
-    {\r
-      /* Need to decide if we are rotating CW or CCW to get to a triangle\r
-       * that will cross edge */\r
-      if (o1 == CW)\r
-        {\r
-          triangle = p2t_triangle_neighbor_ccw (triangle, point);\r
-        }\r
-      else\r
-        {\r
-          triangle = p2t_triangle_neighbor_cw (triangle, point);\r
-        }\r
-      p2t_sweep_edge_event_pt_pt_tr_pt (THIS, tcx, ep, eq, triangle, point);\r
-    }\r
-  else\r
-    {\r
-      /* This triangle crosses constraint so lets flippin start! */\r
-      p2t_sweep_flip_edge_event (THIS, tcx, ep, eq, triangle, point);\r
-    }\r
-}\r
-\r
-gboolean\r
-p2t_sweep_is_edge_side_of_triangle (P2tSweep *THIS, P2tTriangle *triangle, P2tPoint* ep, P2tPoint* eq)\r
-{\r
-  int index = p2t_triangle_edge_index (triangle, ep, eq);\r
-\r
-  if (index != -1)\r
-    {\r
-      P2tTriangle *t;\r
-      p2t_triangle_mark_constrained_edge_i (triangle, index);\r
-      t = p2t_triangle_get_neighbor (triangle, index);\r
-      if (t)\r
-        {\r
-          p2t_triangle_mark_constrained_edge_pt_pt (t, ep, eq);\r
-        }\r
-      return TRUE;\r
-    }\r
-  return FALSE;\r
-}\r
-\r
-P2tNode*\r
-p2t_sweep_new_front_triangle (P2tSweep *THIS, P2tSweepContext *tcx, P2tPoint* point, P2tNode *node)\r
-{\r
-  P2tTriangle* triangle = p2t_triangle_new (point, node->point, node->next->point);\r
-  P2tNode *new_node;\r
-\r
-  p2t_triangle_mark_neighbor_tr (triangle, node->triangle);\r
-  p2t_sweepcontext_add_to_map (tcx, triangle);\r
-\r
-  new_node = p2t_node_new_pt (point);\r
-  g_ptr_array_add (THIS->nodes_, new_node);\r
-\r
-  new_node->next = node->next;\r
-  new_node->prev = node;\r
-  node->next->prev = new_node;\r
-  node->next = new_node;\r
-\r
-  if (!p2t_sweep_legalize (THIS, tcx, triangle))\r
-    {\r
-      p2t_sweepcontext_map_triangle_to_nodes (tcx, triangle);\r
-    }\r
-\r
-  return new_node;\r
-}\r
-\r
-void\r
-p2t_sweep_fill (P2tSweep *THIS, P2tSweepContext *tcx, P2tNode* node)\r
-{\r
-  P2tTriangle* triangle = p2t_triangle_new (node->prev->point, node->point, node->next->point);\r
-\r
-  /* TODO: should copy the constrained_edge value from neighbor triangles\r
-   *       for now constrained_edge values are copied during the legalize */\r
-  p2t_triangle_mark_neighbor_tr (triangle, node->prev->triangle);\r
-  p2t_triangle_mark_neighbor_tr (triangle, node->triangle);\r
-\r
-  p2t_sweepcontext_add_to_map (tcx, triangle);\r
-\r
-  /* Update the advancing front */\r
-  node->prev->next = node->next;\r
-  node->next->prev = node->prev;\r
-\r
-  /* If it was legalized the triangle has already been mapped */\r
-  if (!p2t_sweep_legalize (THIS, tcx, triangle))\r
-    {\r
-      p2t_sweepcontext_map_triangle_to_nodes (tcx, triangle);\r
-    }\r
-\r
-}\r
-\r
-void\r
-p2t_sweep_fill_advancingfront (P2tSweep *THIS, P2tSweepContext *tcx, P2tNode* n)\r
-{\r
-\r
-  /* Fill right holes */\r
-  P2tNode* node = n->next;\r
-\r
-  while (node->next)\r
-    {\r
-      double angle = p2t_sweep_hole_angle (THIS, node);\r
-      if (angle > G_PI_2 || angle < -G_PI_2) break;\r
-      p2t_sweep_fill (THIS, tcx, node);\r
-      node = node->next;\r
-    }\r
-\r
-  /* Fill left holes */\r
-  node = n->prev;\r
-\r
-  while (node->prev)\r
-    {\r
-      double angle = p2t_sweep_hole_angle (THIS, node);\r
-      if (angle > G_PI_2 || angle < -G_PI_2) break;\r
-      p2t_sweep_fill (THIS, tcx, node);\r
-      node = node->prev;\r
-    }\r
-\r
-  /* Fill right basins */\r
-  if (n->next && n->next->next)\r
-    {\r
-      double angle = p2t_sweep_basin_angle (THIS, n);\r
-      if (angle < PI_3div4)\r
-        {\r
-          p2t_sweep_fill_basin (THIS, tcx, n);\r
-        }\r
-    }\r
-}\r
-\r
-double\r
-p2t_sweep_basin_angle (P2tSweep *THIS, P2tNode* node)\r
-{\r
-  double ax = node->point->x - node->next->next->point->x;\r
-  double ay = node->point->y - node->next->next->point->y;\r
-  return atan2 (ay, ax);\r
-}\r
-\r
-double\r
-p2t_sweep_hole_angle (P2tSweep *THIS, P2tNode* node)\r
-{\r
-  /* Complex plane\r
-   * ab = cosA +i*sinA\r
-   * ab = (ax + ay*i)(bx + by*i) = (ax*bx + ay*by) + i(ax*by-ay*bx)\r
-   * atan2(y,x) computes the principal value of the argument function\r
-   * applied to the complex number x+iy\r
-   * Where x = ax*bx + ay*by\r
-   *       y = ax*by - ay*bx\r
-   */\r
-  double ax = node->next->point->x - node->point->x;\r
-  double ay = node->next->point->y - node->point->y;\r
-  double bx = node->prev->point->x - node->point->x;\r
-  double by = node->prev->point->y - node->point->y;\r
-  return atan2 (ax * by - ay * bx, ax * bx + ay * by);\r
-}\r
-\r
-gboolean\r
-p2t_sweep_legalize (P2tSweep *THIS, P2tSweepContext *tcx, P2tTriangle *t)\r
-{\r
-  int i;\r
-  /* To legalize a triangle we start by finding if any of the three edges\r
-   * violate the Delaunay condition */\r
-  for (i = 0; i < 3; i++)\r
-    {\r
-      P2tTriangle *ot;\r
-\r
-      if (t->delaunay_edge[i])\r
-        continue;\r
-\r
-      ot = p2t_triangle_get_neighbor (t, i);\r
-\r
-      if (ot)\r
-        {\r
-          P2tPoint* p = p2t_triangle_get_point (t, i);\r
-          P2tPoint* op = p2t_triangle_opposite_point (ot, t, p);\r
-          int oi = p2t_triangle_index (ot, op);\r
-          gboolean inside;\r
-\r
-          /* If this is a Constrained Edge or a Delaunay Edge(only during recursive legalization)\r
-           * then we should not try to legalize */\r
-          if (ot->constrained_edge[oi] || ot->delaunay_edge[oi])\r
-            {\r
-              t->constrained_edge[i] = ot->constrained_edge[oi];\r
-              continue;\r
-            }\r
-\r
-          inside = p2t_sweep_incircle (THIS, p, p2t_triangle_point_ccw (t, p), p2t_triangle_point_cw (t, p), op);\r
-\r
-          if (inside)\r
-            {\r
-              gboolean not_legalized;\r
-              /* Lets mark this shared edge as Delaunay */\r
-              t->delaunay_edge[i] = TRUE;\r
-              ot->delaunay_edge[oi] = TRUE;\r
-\r
-              /* Lets rotate shared edge one vertex CW to legalize it */\r
-              p2t_sweep_rotate_triangle_pair (THIS, t, p, ot, op);\r
-\r
-              /* We now got one valid Delaunay Edge shared by two triangles\r
-               * This gives us 4 new edges to check for Delaunay */\r
-\r
-              /* Make sure that triangle to node mapping is done only one time for a specific triangle */\r
-              not_legalized = !p2t_sweep_legalize (THIS, tcx, t);\r
-              if (not_legalized)\r
-                {\r
-                  p2t_sweepcontext_map_triangle_to_nodes (tcx, t);\r
-                }\r
-\r
-              not_legalized = !p2t_sweep_legalize (THIS, tcx, ot);\r
-              if (not_legalized)\r
-                p2t_sweepcontext_map_triangle_to_nodes (tcx, ot);\r
-\r
-              /* Reset the Delaunay edges, since they only are valid Delaunay edges\r
-               * until we add a new triangle or point.\r
-               * XXX: need to think about this. Can these edges be tried after we\r
-               *      return to previous recursive level? */\r
-              t->delaunay_edge[i] = FALSE;\r
-              ot->delaunay_edge[oi] = FALSE;\r
-\r
-              /* If triangle have been legalized no need to check the other edges since\r
-               * the recursive legalization will handles those so we can end here.*/\r
-              return TRUE;\r
-            }\r
-        }\r
-    }\r
-  return FALSE;\r
-}\r
-\r
-gboolean\r
-p2t_sweep_incircle (P2tSweep *THIS, P2tPoint* pa, P2tPoint* pb, P2tPoint* pc, P2tPoint* pd)\r
-{\r
-  double adx = pa->x - pd->x;\r
-  double ady = pa->y - pd->y;\r
-  double bdx = pb->x - pd->x;\r
-  double bdy = pb->y - pd->y;\r
-\r
-  double adxbdy = adx * bdy;\r
-  double bdxady = bdx * ady;\r
-  double oabd = adxbdy - bdxady;\r
-\r
-  double cdx, cdy;\r
-  double cdxady, adxcdy, ocad;\r
-\r
-  double bdxcdy, cdxbdy;\r
-  double alift, blift, clift;\r
-  double det;\r
-\r
-  if (oabd <= 0)\r
-    return FALSE;\r
-\r
-  cdx = pc->x - pd->x;\r
-  cdy = pc->y - pd->y;\r
-\r
-  cdxady = cdx * ady;\r
-  adxcdy = adx * cdy;\r
-  ocad = cdxady - adxcdy;\r
-\r
-  if (ocad <= 0)\r
-    return FALSE;\r
-\r
-  bdxcdy = bdx * cdy;\r
-  cdxbdy = cdx * bdy;\r
-\r
-  alift = adx * adx + ady * ady;\r
-  blift = bdx * bdx + bdy * bdy;\r
-  clift = cdx * cdx + cdy * cdy;\r
-\r
-  det = alift * (bdxcdy - cdxbdy) + blift * ocad + clift * oabd;\r
-\r
-  return det > 0;\r
-}\r
-\r
-void\r
-p2t_sweep_rotate_triangle_pair (P2tSweep *THIS, P2tTriangle *t, P2tPoint* p, P2tTriangle *ot, P2tPoint* op)\r
-{\r
-  P2tTriangle *n1, *n2, *n3, *n4;\r
-  gboolean ce1, ce2, ce3, ce4;\r
-  gboolean de1, de2, de3, de4;\r
-\r
-  n1 = p2t_triangle_neighbor_ccw (t, p);\r
-  n2 = p2t_triangle_neighbor_cw (t, p);\r
-  n3 = p2t_triangle_neighbor_ccw (ot, op);\r
-  n4 = p2t_triangle_neighbor_cw (ot, op);\r
-\r
-  ce1 = p2t_triangle_get_constrained_edge_ccw (t, p);\r
-  ce2 = p2t_triangle_get_constrained_edge_cw (t, p);\r
-  ce3 = p2t_triangle_get_constrained_edge_ccw (ot, op);\r
-  ce4 = p2t_triangle_get_constrained_edge_cw (ot, op);\r
-\r
-  de1 = p2t_triangle_get_delunay_edge_ccw (t, p);\r
-  de2 = p2t_triangle_get_delunay_edge_cw (t, p);\r
-  de3 = p2t_triangle_get_delunay_edge_ccw (ot, op);\r
-  de4 = p2t_triangle_get_delunay_edge_cw (ot, op);\r
-\r
-  p2t_triangle_legalize_pt_pt (t, p, op);\r
-  p2t_triangle_legalize_pt_pt (ot, op, p);\r
-\r
-  /* Remap delaunay_edge */\r
-  p2t_triangle_set_delunay_edge_ccw (ot, p, de1);\r
-  p2t_triangle_set_delunay_edge_cw (t, p, de2);\r
-  p2t_triangle_set_delunay_edge_ccw (t, op, de3);\r
-  p2t_triangle_set_delunay_edge_cw (ot, op, de4);\r
-\r
-  /* Remap constrained_edge */\r
-  p2t_triangle_set_constrained_edge_ccw (ot, p, ce1);\r
-  p2t_triangle_set_constrained_edge_cw (t, p, ce2);\r
-  p2t_triangle_set_constrained_edge_ccw (t, op, ce3);\r
-  p2t_triangle_set_constrained_edge_cw (ot, op, ce4);\r
-\r
-  /* Remap neighbors\r
-   * XXX: might optimize the markNeighbor by keeping track of\r
-   *      what side should be assigned to what neighbor after the\r
-   *      rotation. Now mark neighbor does lots of testing to find\r
-   *      the right side. */\r
-  p2t_triangle_clear_neighbors (t);\r
-  p2t_triangle_clear_neighbors (ot);\r
-  if (n1) p2t_triangle_mark_neighbor_tr (ot, n1);\r
-  if (n2) p2t_triangle_mark_neighbor_tr (t, n2);\r
-  if (n3) p2t_triangle_mark_neighbor_tr (t, n3);\r
-  if (n4) p2t_triangle_mark_neighbor_tr (ot, n4);\r
-  p2t_triangle_mark_neighbor_tr (t, ot);\r
-}\r
-\r
-void\r
-p2t_sweep_fill_basin (P2tSweep *THIS, P2tSweepContext *tcx, P2tNode* node)\r
-{\r
-  if (p2t_orient2d (node->point, node->next->point, node->next->next->point) == CCW)\r
-    {\r
-      tcx->basin.left_node = node->next->next;\r
-    }\r
-  else\r
-    {\r
-      tcx->basin.left_node = node->next;\r
-    }\r
-\r
-  /* Find the bottom and right node */\r
-  tcx->basin.bottom_node = tcx->basin.left_node;\r
-  while (tcx->basin.bottom_node->next\r
-         && tcx->basin.bottom_node->point->y >= tcx->basin.bottom_node->next->point->y)\r
-    {\r
-      tcx->basin.bottom_node = tcx->basin.bottom_node->next;\r
-    }\r
-  if (tcx->basin.bottom_node == tcx->basin.left_node)\r
-    {\r
-      /* No valid basin */\r
-      return;\r
-    }\r
-\r
-  tcx->basin.right_node = tcx->basin.bottom_node;\r
-  while (tcx->basin.right_node->next\r
-         && tcx->basin.right_node->point->y < tcx->basin.right_node->next->point->y)\r
-    {\r
-      tcx->basin.right_node = tcx->basin.right_node->next;\r
-    }\r
-  if (tcx->basin.right_node == tcx->basin.bottom_node)\r
-    {\r
-      /* No valid basins */\r
-      return;\r
-    }\r
-\r
-  tcx->basin.width = tcx->basin.right_node->point->x - tcx->basin.left_node->point->x;\r
-  tcx->basin.left_highest = tcx->basin.left_node->point->y > tcx->basin.right_node->point->y;\r
-\r
-  p2t_sweep_fill_basin_req (THIS, tcx, tcx->basin.bottom_node);\r
-}\r
-\r
-void\r
-p2t_sweep_fill_basin_req (P2tSweep *THIS, P2tSweepContext *tcx, P2tNode* node)\r
-{\r
-  /* if shallow stop filling */\r
-  if (p2t_sweep_is_shallow (THIS, tcx, node))\r
-    {\r
-      return;\r
-    }\r
-\r
-  p2t_sweep_fill (THIS, tcx, node);\r
-\r
-  if (node->prev == tcx->basin.left_node && node->next == tcx->basin.right_node)\r
-    {\r
-      return;\r
-    }\r
-  else if (node->prev == tcx->basin.left_node)\r
-    {\r
-      P2tOrientation o = p2t_orient2d (node->point, node->next->point, node->next->next->point);\r
-      if (o == CW)\r
-        {\r
-          return;\r
-        }\r
-      node = node->next;\r
-    }\r
-  else if (node->next == tcx->basin.right_node)\r
-    {\r
-      P2tOrientation o = p2t_orient2d (node->point, node->prev->point, node->prev->prev->point);\r
-      if (o == CCW)\r
-        {\r
-          return;\r
-        }\r
-      node = node->prev;\r
-    }\r
-  else\r
-    {\r
-      /* Continue with the neighbor node with lowest Y value */\r
-      if (node->prev->point->y < node->next->point->y)\r
-        {\r
-          node = node->prev;\r
-        }\r
-      else\r
-        {\r
-          node = node->next;\r
-        }\r
-    }\r
-\r
-  p2t_sweep_fill_basin_req (THIS, tcx, node);\r
-}\r
-\r
-gboolean\r
-p2t_sweep_is_shallow (P2tSweep *THIS, P2tSweepContext *tcx, P2tNode* node)\r
-{\r
-  double height;\r
-\r
-  if (tcx->basin.left_highest)\r
-    {\r
-      height = tcx->basin.left_node->point->y - node->point->y;\r
-    }\r
-  else\r
-    {\r
-      height = tcx->basin.right_node->point->y - node->point->y;\r
-    }\r
-\r
-  /* if shallow stop filling */\r
-  if (tcx->basin.width > height)\r
-    {\r
-      return TRUE;\r
-    }\r
-  return FALSE;\r
-}\r
-\r
-void\r
-p2t_sweep_fill_edge_event (P2tSweep *THIS, P2tSweepContext *tcx, P2tEdge* edge, P2tNode* node)\r
-{\r
-  if (tcx->edge_event.right)\r
-    {\r
-      p2t_sweep_fill_right_above_edge_event (THIS, tcx, edge, node);\r
-    }\r
-  else\r
-    {\r
-      p2t_sweep_fill_left_above_edge_event (THIS, tcx, edge, node);\r
-    }\r
-}\r
-\r
-void\r
-p2t_sweep_fill_right_above_edge_event (P2tSweep *THIS, P2tSweepContext *tcx, P2tEdge* edge, P2tNode* node)\r
-{\r
-  while (node->next->point->x < edge->p->x)\r
-    {\r
-      /* Check if next node is below the edge */\r
-      if (p2t_orient2d (edge->q, node->next->point, edge->p) == CCW)\r
-        {\r
-          p2t_sweep_fill_right_below_edge_event (THIS, tcx, edge, node);\r
-        }\r
-      else\r
-        {\r
-          node = node->next;\r
-        }\r
-    }\r
-}\r
-\r
-void\r
-p2t_sweep_fill_right_below_edge_event (P2tSweep *THIS, P2tSweepContext *tcx, P2tEdge* edge, P2tNode* node)\r
-{\r
-  if (node->point->x < edge->p->x)\r
-    {\r
-      if (p2t_orient2d (node->point, node->next->point, node->next->next->point) == CCW)\r
-        {\r
-          /* Concave */\r
-          p2t_sweep_fill_right_concave_edge_event (THIS, tcx, edge, node);\r
-        }\r
-      else\r
-        {\r
-          /* Convex */\r
-          p2t_sweep_fill_right_convex_edge_event (THIS, tcx, edge, node);\r
-          /* Retry this one */\r
-          p2t_sweep_fill_right_below_edge_event (THIS, tcx, edge, node);\r
-        }\r
-    }\r
-}\r
-\r
-void\r
-p2t_sweep_fill_right_concave_edge_event (P2tSweep *THIS, P2tSweepContext *tcx, P2tEdge* edge, P2tNode* node)\r
-{\r
-  p2t_sweep_fill (THIS, tcx, node->next);\r
-  if (node->next->point != edge->p)\r
-    {\r
-      /* Next above or below edge? */\r
-      if (p2t_orient2d (edge->q, node->next->point, edge->p) == CCW)\r
-        {\r
-          /* Below */\r
-          if (p2t_orient2d (node->point, node->next->point, node->next->next->point) == CCW)\r
-            {\r
-              /* Next is concave */\r
-              p2t_sweep_fill_right_concave_edge_event (THIS, tcx, edge, node);\r
-            }\r
-          else\r
-            {\r
-              /* Next is convex */\r
-            }\r
-        }\r
-    }\r
-\r
-}\r
-\r
-void\r
-p2t_sweep_fill_right_convex_edge_event (P2tSweep *THIS, P2tSweepContext *tcx, P2tEdge* edge, P2tNode* node)\r
-{\r
-  /* Next concave or convex? */\r
-  if (p2t_orient2d (node->next->point, node->next->next->point, node->next->next->next->point) == CCW)\r
-    {\r
-      /* Concave */\r
-      p2t_sweep_fill_right_concave_edge_event (THIS, tcx, edge, node->next);\r
-    }\r
-  else\r
-    {\r
-      /* Convex\r
-       * Next above or below edge? */\r
-      if (p2t_orient2d (edge->q, node->next->next->point, edge->p) == CCW)\r
-        {\r
-          /* Below */\r
-          p2t_sweep_fill_right_convex_edge_event (THIS, tcx, edge, node->next);\r
-        }\r
-      else\r
-        {\r
-          /* Above */\r
-        }\r
-    }\r
-}\r
-\r
-void\r
-p2t_sweep_fill_left_above_edge_event (P2tSweep *THIS, P2tSweepContext *tcx, P2tEdge* edge, P2tNode* node)\r
-{\r
-  while (node->prev->point->x > edge->p->x)\r
-    {\r
-      /* Check if next node is below the edge */\r
-      if (p2t_orient2d (edge->q, node->prev->point, edge->p) == CW)\r
-        {\r
-          p2t_sweep_fill_left_below_edge_event (THIS, tcx, edge, node);\r
-        }\r
-      else\r
-        {\r
-          node = node->prev;\r
-        }\r
-    }\r
-}\r
-\r
-void\r
-p2t_sweep_fill_left_below_edge_event (P2tSweep *THIS, P2tSweepContext *tcx, P2tEdge* edge, P2tNode* node)\r
-{\r
-  if (node->point->x > edge->p->x)\r
-    {\r
-      if (p2t_orient2d (node->point, node->prev->point, node->prev->prev->point) == CW)\r
-        {\r
-          /* Concave */\r
-          p2t_sweep_fill_left_concave_edge_event (THIS, tcx, edge, node);\r
-        }\r
-      else\r
-        {\r
-          /* Convex */\r
-          p2t_sweep_fill_left_convex_edge_event (THIS, tcx, edge, node);\r
-          /* Retry this one */\r
-          p2t_sweep_fill_left_below_edge_event (THIS, tcx, edge, node);\r
-        }\r
-    }\r
-}\r
-\r
-void\r
-p2t_sweep_fill_left_convex_edge_event (P2tSweep *THIS, P2tSweepContext *tcx, P2tEdge* edge, P2tNode* node)\r
-{\r
-  /* Next concave or convex? */\r
-  if (p2t_orient2d (node->prev->point, node->prev->prev->point, node->prev->prev->prev->point) == CW)\r
-    {\r
-      /* Concave */\r
-      p2t_sweep_fill_left_concave_edge_event (THIS, tcx, edge, node->prev);\r
-    }\r
-  else\r
-    {\r
-      /* Convex\r
-       * Next above or below edge? */\r
-      if (p2t_orient2d (edge->q, node->prev->prev->point, edge->p) == CW)\r
-        {\r
-          /* Below */\r
-          p2t_sweep_fill_left_convex_edge_event (THIS, tcx, edge, node->prev);\r
-        }\r
-      else\r
-        {\r
-          /* Above */\r
-        }\r
-    }\r
-}\r
-\r
-void\r
-p2t_sweep_fill_left_concave_edge_event (P2tSweep *THIS, P2tSweepContext *tcx, P2tEdge* edge, P2tNode* node)\r
-{\r
-  p2t_sweep_fill (THIS, tcx, node->prev);\r
-  if (node->prev->point != edge->p)\r
-    {\r
-      /* Next above or below edge? */\r
-      if (p2t_orient2d (edge->q, node->prev->point, edge->p) == CW)\r
-        {\r
-          /* Below */\r
-          if (p2t_orient2d (node->point, node->prev->point, node->prev->prev->point) == CW)\r
-            {\r
-              /* Next is concave */\r
-              p2t_sweep_fill_left_concave_edge_event (THIS, tcx, edge, node);\r
-            }\r
-          else\r
-            {\r
-              /* Next is convex */\r
-            }\r
-        }\r
-    }\r
-\r
-}\r
-\r
-void\r
-p2t_sweep_flip_edge_event (P2tSweep *THIS, P2tSweepContext *tcx, P2tPoint* ep, P2tPoint* eq, P2tTriangle* t, P2tPoint* p)\r
-{\r
-  P2tTriangle* ot = p2t_triangle_neighbor_across (t, p);\r
-  P2tPoint* op = p2t_triangle_opposite_point (ot, t, p);\r
-\r
-  if (ot == NULL)\r
-    {\r
-      /* If we want to integrate the fillEdgeEvent do it here\r
-       * With current implementation we should never get here\r
-       *throw new RuntimeException( "[BUG:FIXME] FLIP failed due to missing triangle");\r
-       */\r
-      assert (0);\r
-    }\r
-\r
-  if (p2t_utils_in_scan_area (p, p2t_triangle_point_ccw (t, p), p2t_triangle_point_cw (t, p), op))\r
-    {\r
-      /* Lets rotate shared edge one vertex CW */\r
-      p2t_sweep_rotate_triangle_pair (THIS, t, p, ot, op);\r
-      p2t_sweepcontext_map_triangle_to_nodes (tcx, t);\r
-      p2t_sweepcontext_map_triangle_to_nodes (tcx, ot);\r
-\r
-      if (p == eq && op == ep)\r
-        {\r
-          if (p2t_point_equals (eq, tcx->edge_event.constrained_edge->q) && p2t_point_equals (ep, tcx->edge_event.constrained_edge->p))\r
-            {\r
-              p2t_triangle_mark_constrained_edge_pt_pt (t, ep, eq);\r
-              p2t_triangle_mark_constrained_edge_pt_pt (ot, ep, eq);\r
-              p2t_sweep_legalize (THIS, tcx, t);\r
-              p2t_sweep_legalize (THIS, tcx, ot);\r
-            }\r
-          else\r
-            {\r
-              /* XXX: I think one of the triangles should be legalized here? */\r
-            }\r
-        }\r
-      else\r
-        {\r
-          P2tOrientation o = p2t_orient2d (eq, op, ep);\r
-          t = p2t_sweep_next_flip_triangle (THIS, tcx, (int) o, t, ot, p, op);\r
-          p2t_sweep_flip_edge_event (THIS, tcx, ep, eq, t, p);\r
-        }\r
-    }\r
-  else\r
-    {\r
-      P2tPoint* newP = p2t_sweep_next_flip_point (THIS, ep, eq, ot, op);\r
-      p2t_sweep_flip_scan_edge_event (THIS, tcx, ep, eq, t, ot, newP);\r
-      p2t_sweep_edge_event_pt_pt_tr_pt (THIS, tcx, ep, eq, t, p);\r
-    }\r
-}\r
-\r
-P2tTriangle*\r
-p2t_sweep_next_flip_triangle (P2tSweep *THIS, P2tSweepContext *tcx, int o, P2tTriangle *t, P2tTriangle *ot, P2tPoint* p, P2tPoint* op)\r
-{\r
-  int edge_index;\r
-\r
-  if (o == CCW)\r
-    {\r
-      /* ot is not crossing edge after flip */\r
-      int edge_index = p2t_triangle_edge_index (ot, p, op);\r
-      ot->delaunay_edge[edge_index] = TRUE;\r
-      p2t_sweep_legalize (THIS, tcx, ot);\r
-      p2t_triangle_clear_delunay_edges (ot);\r
-      return t;\r
-    }\r
-\r
-  /* t is not crossing edge after flip */\r
-  edge_index = p2t_triangle_edge_index (t, p, op);\r
-\r
-  t->delaunay_edge[edge_index] = TRUE;\r
-  p2t_sweep_legalize (THIS, tcx, t);\r
-  p2t_triangle_clear_delunay_edges (t);\r
-  return ot;\r
-}\r
-\r
-P2tPoint*\r
-p2t_sweep_next_flip_point (P2tSweep *THIS, P2tPoint* ep, P2tPoint* eq, P2tTriangle *ot, P2tPoint* op)\r
-{\r
-  P2tOrientation o2d = p2t_orient2d (eq, op, ep);\r
-  if (o2d == CW)\r
-    {\r
-      /* Right */\r
-      return p2t_triangle_point_ccw (ot, op);\r
-    }\r
-  else if (o2d == CCW)\r
-    {\r
-      /* Left */\r
-      return p2t_triangle_point_cw (ot, op);\r
-    }\r
-  else\r
-    {\r
-      /*throw new RuntimeException("[Unsupported] Opposing point on constrained edge");*/\r
-      assert (0);\r
-    }\r
-}\r
-\r
-void\r
-p2t_sweep_flip_scan_edge_event (P2tSweep *THIS, P2tSweepContext *tcx, P2tPoint* ep, P2tPoint* eq, P2tTriangle *flip_triangle,\r
-                                P2tTriangle *t, P2tPoint* p)\r
-{\r
-  P2tTriangle* ot = p2t_triangle_neighbor_across (t, p);\r
-  P2tPoint* op = p2t_triangle_opposite_point (ot, t, p);\r
-\r
-  if (p2t_triangle_neighbor_across (t, p) == NULL)\r
-    {\r
-      /* If we want to integrate the fillEdgeEvent do it here\r
-       * With current implementation we should never get here\r
-       *throw new RuntimeException( "[BUG:FIXME] FLIP failed due to missing triangle");\r
-       */\r
-      assert (0);\r
-    }\r
-\r
-  if (p2t_utils_in_scan_area (eq, p2t_triangle_point_ccw (flip_triangle, eq), p2t_triangle_point_cw (flip_triangle, eq), op))\r
-    {\r
-      /* flip with new edge op->eq */\r
-      p2t_sweep_flip_edge_event (THIS, tcx, eq, op, ot, op);\r
-      /* TODO: Actually I just figured out that it should be possible to\r
-       *       improve this by getting the next ot and op before the the above\r
-       *       flip and continue the flipScanEdgeEvent here\r
-       * set new ot and op here and loop back to inScanArea test\r
-       * also need to set a new flip_triangle first\r
-       * Turns out at first glance that this is somewhat complicated\r
-       * so it will have to wait. */\r
-    }\r
-  else\r
-    {\r
-      P2tPoint* newP = p2t_sweep_next_flip_point (THIS, ep, eq, ot, op);\r
-      p2t_sweep_flip_scan_edge_event (THIS, tcx, ep, eq, flip_triangle, ot, newP);\r
-    }\r
-}\r
+/*
+ * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
+ * http://code.google.com/p/poly2tri/
+ * 
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of Poly2Tri nor the names of its contributors may be
+ *   used to endorse or promote products derived from this software without specific
+ *   prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <math.h>
+
+#include "sweep.h"
+#include "sweep_context.h"
+#include "advancing_front.h"
+#include "../common/utils.h"
+#include "../common/shapes.h"
+
+void
+p2t_sweep_init (P2tSweep* THIS)
+{
+  THIS->nodes_ = g_ptr_array_new ();
+}
+
+P2tSweep*
+p2t_sweep_new ()
+{
+  P2tSweep* THIS = g_new (P2tSweep, 1);
+  p2t_sweep_init (THIS);
+  return THIS;
+}
+
+/**
+ * Destructor - clean up memory
+ */
+void
+p2t_sweep_destroy (P2tSweep* THIS)
+{
+  int i;
+  /* Clean up memory */
+  for (i = 0; i < THIS->nodes_->len; i++)
+    {
+      p2t_node_free (node_index (THIS->nodes_, i));
+    }
+
+  g_ptr_array_free (THIS->nodes_, TRUE);
+}
+
+void
+p2t_sweep_free (P2tSweep* THIS)
+{
+  p2t_sweep_destroy (THIS);
+  g_free (THIS);
+}
+
+/* Triangulate simple polygon with holes */
+
+void
+p2t_sweep_triangulate (P2tSweep *THIS, P2tSweepContext *tcx)
+{
+  p2t_sweepcontext_init_triangulation (tcx);
+  p2t_sweepcontext_create_advancingfront (tcx, THIS->nodes_);
+  /* Sweep points; build mesh */
+  p2t_sweep_sweep_points (THIS, tcx);
+  /* Clean up */
+  p2t_sweep_finalization_polygon (THIS, tcx);
+}
+
+void
+p2t_sweep_sweep_points (P2tSweep *THIS, P2tSweepContext *tcx)
+{
+  int i, j;
+  for (i = 1; i < p2t_sweepcontext_point_count (tcx); i++)
+    {
+      P2tPoint* point = p2t_sweepcontext_get_point (tcx, i);
+      P2tNode* node = p2t_sweep_point_event (THIS, tcx, point);
+      for (j = 0; j < point->edge_list->len; j++)
+        {
+          p2t_sweep_edge_event_ed_n (THIS, tcx, edge_index (point->edge_list, j), node);
+        }
+    }
+}
+
+void
+p2t_sweep_finalization_polygon (P2tSweep *THIS, P2tSweepContext *tcx)
+{
+  /* Get an Internal triangle to start with */
+  P2tTriangle* t = p2t_advancingfront_head (p2t_sweepcontext_front (tcx))->next->triangle;
+  P2tPoint* p = p2t_advancingfront_head (p2t_sweepcontext_front (tcx))->next->point;
+  while (!p2t_triangle_get_constrained_edge_cw (t, p))
+    {
+      t = p2t_triangle_neighbor_ccw (t, p);
+    }
+
+  /* Collect interior triangles constrained by edges */
+  p2t_sweepcontext_mesh_clean (tcx, t);
+}
+
+P2tNode*
+p2t_sweep_point_event (P2tSweep *THIS, P2tSweepContext *tcx, P2tPoint* point)
+{
+  P2tNode* node = p2t_sweepcontext_locate_node (tcx, point);
+  P2tNode* new_node = p2t_sweep_new_front_triangle (THIS, tcx, point, node);
+
+  /* Only need to check +epsilon since point never have smaller
+   * x value than node due to how we fetch nodes from the front */
+  if (point->x <= node->point->x + EPSILON)
+    {
+      p2t_sweep_fill (THIS, tcx, node);
+    }
+
+  /*tcx.AddNode(new_node); */
+
+  p2t_sweep_fill_advancingfront (THIS, tcx, new_node);
+  return new_node;
+}
+
+void
+p2t_sweep_edge_event_ed_n (P2tSweep *THIS, P2tSweepContext *tcx, P2tEdge* edge, P2tNode* node)
+{
+  tcx->edge_event.constrained_edge = edge;
+  tcx->edge_event.right = (edge->p->x > edge->q->x);
+
+  if (p2t_sweep_is_edge_side_of_triangle (THIS, node->triangle, edge->p, edge->q))
+    {
+      return;
+    }
+
+  /* For now we will do all needed filling
+   * TODO: integrate with flip process might give some better performance
+   *       but for now this avoid the issue with cases that needs both flips and fills
+   */
+  p2t_sweep_fill_edge_event (THIS, tcx, edge, node);
+  p2t_sweep_edge_event_pt_pt_tr_pt (THIS, tcx, edge->p, edge->q, node->triangle, edge->q);
+}
+
+void
+p2t_sweep_edge_event_pt_pt_tr_pt (P2tSweep *THIS, P2tSweepContext *tcx, P2tPoint* ep, P2tPoint* eq, P2tTriangle* triangle, P2tPoint* point)
+{
+  P2tPoint *p1, *p2;
+  P2tOrientation o1, o2;
+
+  if (p2t_sweep_is_edge_side_of_triangle (THIS, triangle, ep, eq))
+    {
+      return;
+    }
+
+  p1 = p2t_triangle_point_ccw (triangle, point);
+  o1 = p2t_orient2d (eq, p1, ep);
+  if (o1 == COLLINEAR)
+    {
+      if (p2t_triangle_contains_pt_pt (triangle, eq, p1))
+        {
+          p2t_triangle_mark_constrained_edge_pt_pt (triangle, eq, p1);
+          /* We are modifying the constraint maybe it would be better to
+           * not change the given constraint and just keep a variable for the new constraint
+           */
+          tcx->edge_event.constrained_edge->q = p1;
+          triangle = p2t_triangle_neighbor_across (triangle, point);
+          p2t_sweep_edge_event_pt_pt_tr_pt (THIS, tcx, ep, p1, triangle, p1);
+        }
+      else
+        {
+          g_error ("EdgeEvent - collinear points not supported");
+        }
+      return;
+    }
+
+  p2 = p2t_triangle_point_cw (triangle, point);
+  o2 = p2t_orient2d (eq, p2, ep);
+  if (o2 == COLLINEAR)
+    {
+      if (p2t_triangle_contains_pt_pt (triangle, eq, p2))
+        {
+          p2t_triangle_mark_constrained_edge_pt_pt (triangle, eq, p2);
+          /* We are modifying the constraint maybe it would be better to
+           * not change the given constraint and just keep a variable for the new constraint
+           */
+          tcx->edge_event.constrained_edge->q = p2;
+          triangle = p2t_triangle_neighbor_across (triangle, point);
+          p2t_sweep_edge_event_pt_pt_tr_pt (THIS, tcx, ep, p2, triangle, p2);
+        }
+      else
+        {
+          g_error ("EdgeEvent - collinear points not supported");
+        }
+      return;
+    }
+
+  if (o1 == o2)
+    {
+      /* Need to decide if we are rotating CW or CCW to get to a triangle
+       * that will cross edge */
+      if (o1 == CW)
+        {
+          triangle = p2t_triangle_neighbor_ccw (triangle, point);
+        }
+      else
+        {
+          triangle = p2t_triangle_neighbor_cw (triangle, point);
+        }
+      p2t_sweep_edge_event_pt_pt_tr_pt (THIS, tcx, ep, eq, triangle, point);
+    }
+  else
+    {
+      /* This triangle crosses constraint so lets flippin start! */
+      p2t_sweep_flip_edge_event (THIS, tcx, ep, eq, triangle, point);
+    }
+}
+
+gboolean
+p2t_sweep_is_edge_side_of_triangle (P2tSweep *THIS, P2tTriangle *triangle, P2tPoint* ep, P2tPoint* eq)
+{
+  int index = p2t_triangle_edge_index (triangle, ep, eq);
+
+  if (index != -1)
+    {
+      P2tTriangle *t;
+      p2t_triangle_mark_constrained_edge_i (triangle, index);
+      t = p2t_triangle_get_neighbor (triangle, index);
+      if (t)
+        {
+          p2t_triangle_mark_constrained_edge_pt_pt (t, ep, eq);
+        }
+      return TRUE;
+    }
+  return FALSE;
+}
+
+P2tNode*
+p2t_sweep_new_front_triangle (P2tSweep *THIS, P2tSweepContext *tcx, P2tPoint* point, P2tNode *node)
+{
+  P2tTriangle* triangle = p2t_triangle_new (point, node->point, node->next->point);
+  P2tNode *new_node;
+
+  p2t_triangle_mark_neighbor_tr (triangle, node->triangle);
+  p2t_sweepcontext_add_to_map (tcx, triangle);
+
+  new_node = p2t_node_new_pt (point);
+  g_ptr_array_add (THIS->nodes_, new_node);
+
+  new_node->next = node->next;
+  new_node->prev = node;
+  node->next->prev = new_node;
+  node->next = new_node;
+
+  if (!p2t_sweep_legalize (THIS, tcx, triangle))
+    {
+      p2t_sweepcontext_map_triangle_to_nodes (tcx, triangle);
+    }
+
+  return new_node;
+}
+
+void
+p2t_sweep_fill (P2tSweep *THIS, P2tSweepContext *tcx, P2tNode* node)
+{
+  P2tTriangle* triangle = p2t_triangle_new (node->prev->point, node->point, node->next->point);
+
+  /* TODO: should copy the constrained_edge value from neighbor triangles
+   *       for now constrained_edge values are copied during the legalize */
+  p2t_triangle_mark_neighbor_tr (triangle, node->prev->triangle);
+  p2t_triangle_mark_neighbor_tr (triangle, node->triangle);
+
+  p2t_sweepcontext_add_to_map (tcx, triangle);
+
+  /* Update the advancing front */
+  node->prev->next = node->next;
+  node->next->prev = node->prev;
+
+  /* If it was legalized the triangle has already been mapped */
+  if (!p2t_sweep_legalize (THIS, tcx, triangle))
+    {
+      p2t_sweepcontext_map_triangle_to_nodes (tcx, triangle);
+    }
+
+}
+
+void
+p2t_sweep_fill_advancingfront (P2tSweep *THIS, P2tSweepContext *tcx, P2tNode* n)
+{
+
+  /* Fill right holes */
+  P2tNode* node = n->next;
+
+  while (node->next)
+    {
+      double angle = p2t_sweep_hole_angle (THIS, node);
+      if (angle > G_PI_2 || angle < -G_PI_2) break;
+      p2t_sweep_fill (THIS, tcx, node);
+      node = node->next;
+    }
+
+  /* Fill left holes */
+  node = n->prev;
+
+  while (node->prev)
+    {
+      double angle = p2t_sweep_hole_angle (THIS, node);
+      if (angle > G_PI_2 || angle < -G_PI_2) break;
+      p2t_sweep_fill (THIS, tcx, node);
+      node = node->prev;
+    }
+
+  /* Fill right basins */
+  if (n->next && n->next->next)
+    {
+      double angle = p2t_sweep_basin_angle (THIS, n);
+      if (angle < PI_3div4)
+        {
+          p2t_sweep_fill_basin (THIS, tcx, n);
+        }
+    }
+}
+
+double
+p2t_sweep_basin_angle (P2tSweep *THIS, P2tNode* node)
+{
+  double ax = node->point->x - node->next->next->point->x;
+  double ay = node->point->y - node->next->next->point->y;
+  return atan2 (ay, ax);
+}
+
+double
+p2t_sweep_hole_angle (P2tSweep *THIS, P2tNode* node)
+{
+  /* Complex plane
+   * ab = cosA +i*sinA
+   * ab = (ax + ay*i)(bx + by*i) = (ax*bx + ay*by) + i(ax*by-ay*bx)
+   * atan2(y,x) computes the principal value of the argument function
+   * applied to the complex number x+iy
+   * Where x = ax*bx + ay*by
+   *       y = ax*by - ay*bx
+   */
+  double ax = node->next->point->x - node->point->x;
+  double ay = node->next->point->y - node->point->y;
+  double bx = node->prev->point->x - node->point->x;
+  double by = node->prev->point->y - node->point->y;
+  return atan2 (ax * by - ay * bx, ax * bx + ay * by);
+}
+
+gboolean
+p2t_sweep_legalize (P2tSweep *THIS, P2tSweepContext *tcx, P2tTriangle *t)
+{
+  int i;
+  /* To legalize a triangle we start by finding if any of the three edges
+   * violate the Delaunay condition */
+  for (i = 0; i < 3; i++)
+    {
+      P2tTriangle *ot;
+
+      if (t->delaunay_edge[i])
+        continue;
+
+      ot = p2t_triangle_get_neighbor (t, i);
+
+      if (ot)
+        {
+          P2tPoint* p = p2t_triangle_get_point (t, i);
+          P2tPoint* op = p2t_triangle_opposite_point (ot, t, p);
+          int oi = p2t_triangle_index (ot, op);
+          gboolean inside;
+
+          /* If this is a Constrained Edge or a Delaunay Edge(only during recursive legalization)
+           * then we should not try to legalize */
+          if (ot->constrained_edge[oi] || ot->delaunay_edge[oi])
+            {
+              t->constrained_edge[i] = ot->constrained_edge[oi];
+              continue;
+            }
+
+          inside = p2t_sweep_incircle (THIS, p, p2t_triangle_point_ccw (t, p), p2t_triangle_point_cw (t, p), op);
+
+          if (inside)
+            {
+              gboolean not_legalized;
+              /* Lets mark this shared edge as Delaunay */
+              t->delaunay_edge[i] = TRUE;
+              ot->delaunay_edge[oi] = TRUE;
+
+              /* Lets rotate shared edge one vertex CW to legalize it */
+              p2t_sweep_rotate_triangle_pair (THIS, t, p, ot, op);
+
+              /* We now got one valid Delaunay Edge shared by two triangles
+               * This gives us 4 new edges to check for Delaunay */
+
+              /* Make sure that triangle to node mapping is done only one time for a specific triangle */
+              not_legalized = !p2t_sweep_legalize (THIS, tcx, t);
+              if (not_legalized)
+                {
+                  p2t_sweepcontext_map_triangle_to_nodes (tcx, t);
+                }
+
+              not_legalized = !p2t_sweep_legalize (THIS, tcx, ot);
+              if (not_legalized)
+                p2t_sweepcontext_map_triangle_to_nodes (tcx, ot);
+
+              /* Reset the Delaunay edges, since they only are valid Delaunay edges
+               * until we add a new triangle or point.
+               * XXX: need to think about this. Can these edges be tried after we
+               *      return to previous recursive level? */
+              t->delaunay_edge[i] = FALSE;
+              ot->delaunay_edge[oi] = FALSE;
+
+              /* If triangle have been legalized no need to check the other edges since
+               * the recursive legalization will handles those so we can end here.*/
+              return TRUE;
+            }
+        }
+    }
+  return FALSE;
+}
+
+gboolean
+p2t_sweep_incircle (P2tSweep *THIS, P2tPoint* pa, P2tPoint* pb, P2tPoint* pc, P2tPoint* pd)
+{
+  double adx = pa->x - pd->x;
+  double ady = pa->y - pd->y;
+  double bdx = pb->x - pd->x;
+  double bdy = pb->y - pd->y;
+
+  double adxbdy = adx * bdy;
+  double bdxady = bdx * ady;
+  double oabd = adxbdy - bdxady;
+
+  double cdx, cdy;
+  double cdxady, adxcdy, ocad;
+
+  double bdxcdy, cdxbdy;
+  double alift, blift, clift;
+  double det;
+
+  if (oabd <= 0)
+    return FALSE;
+
+  cdx = pc->x - pd->x;
+  cdy = pc->y - pd->y;
+
+  cdxady = cdx * ady;
+  adxcdy = adx * cdy;
+  ocad = cdxady - adxcdy;
+
+  if (ocad <= 0)
+    return FALSE;
+
+  bdxcdy = bdx * cdy;
+  cdxbdy = cdx * bdy;
+
+  alift = adx * adx + ady * ady;
+  blift = bdx * bdx + bdy * bdy;
+  clift = cdx * cdx + cdy * cdy;
+
+  det = alift * (bdxcdy - cdxbdy) + blift * ocad + clift * oabd;
+
+  return det > 0;
+}
+
+void
+p2t_sweep_rotate_triangle_pair (P2tSweep *THIS, P2tTriangle *t, P2tPoint* p, P2tTriangle *ot, P2tPoint* op)
+{
+  P2tTriangle *n1, *n2, *n3, *n4;
+  gboolean ce1, ce2, ce3, ce4;
+  gboolean de1, de2, de3, de4;
+
+  n1 = p2t_triangle_neighbor_ccw (t, p);
+  n2 = p2t_triangle_neighbor_cw (t, p);
+  n3 = p2t_triangle_neighbor_ccw (ot, op);
+  n4 = p2t_triangle_neighbor_cw (ot, op);
+
+  ce1 = p2t_triangle_get_constrained_edge_ccw (t, p);
+  ce2 = p2t_triangle_get_constrained_edge_cw (t, p);
+  ce3 = p2t_triangle_get_constrained_edge_ccw (ot, op);
+  ce4 = p2t_triangle_get_constrained_edge_cw (ot, op);
+
+  de1 = p2t_triangle_get_delunay_edge_ccw (t, p);
+  de2 = p2t_triangle_get_delunay_edge_cw (t, p);
+  de3 = p2t_triangle_get_delunay_edge_ccw (ot, op);
+  de4 = p2t_triangle_get_delunay_edge_cw (ot, op);
+
+  p2t_triangle_legalize_pt_pt (t, p, op);
+  p2t_triangle_legalize_pt_pt (ot, op, p);
+
+  /* Remap delaunay_edge */
+  p2t_triangle_set_delunay_edge_ccw (ot, p, de1);
+  p2t_triangle_set_delunay_edge_cw (t, p, de2);
+  p2t_triangle_set_delunay_edge_ccw (t, op, de3);
+  p2t_triangle_set_delunay_edge_cw (ot, op, de4);
+
+  /* Remap constrained_edge */
+  p2t_triangle_set_constrained_edge_ccw (ot, p, ce1);
+  p2t_triangle_set_constrained_edge_cw (t, p, ce2);
+  p2t_triangle_set_constrained_edge_ccw (t, op, ce3);
+  p2t_triangle_set_constrained_edge_cw (ot, op, ce4);
+
+  /* Remap neighbors
+   * XXX: might optimize the markNeighbor by keeping track of
+   *      what side should be assigned to what neighbor after the
+   *      rotation. Now mark neighbor does lots of testing to find
+   *      the right side. */
+  p2t_triangle_clear_neighbors (t);
+  p2t_triangle_clear_neighbors (ot);
+  if (n1) p2t_triangle_mark_neighbor_tr (ot, n1);
+  if (n2) p2t_triangle_mark_neighbor_tr (t, n2);
+  if (n3) p2t_triangle_mark_neighbor_tr (t, n3);
+  if (n4) p2t_triangle_mark_neighbor_tr (ot, n4);
+  p2t_triangle_mark_neighbor_tr (t, ot);
+}
+
+void
+p2t_sweep_fill_basin (P2tSweep *THIS, P2tSweepContext *tcx, P2tNode* node)
+{
+  if (p2t_orient2d (node->point, node->next->point, node->next->next->point) == CCW)
+    {
+      tcx->basin.left_node = node->next->next;
+    }
+  else
+    {
+      tcx->basin.left_node = node->next;
+    }
+
+  /* Find the bottom and right node */
+  tcx->basin.bottom_node = tcx->basin.left_node;
+  while (tcx->basin.bottom_node->next
+         && tcx->basin.bottom_node->point->y >= tcx->basin.bottom_node->next->point->y)
+    {
+      tcx->basin.bottom_node = tcx->basin.bottom_node->next;
+    }
+  if (tcx->basin.bottom_node == tcx->basin.left_node)
+    {
+      /* No valid basin */
+      return;
+    }
+
+  tcx->basin.right_node = tcx->basin.bottom_node;
+  while (tcx->basin.right_node->next
+         && tcx->basin.right_node->point->y < tcx->basin.right_node->next->point->y)
+    {
+      tcx->basin.right_node = tcx->basin.right_node->next;
+    }
+  if (tcx->basin.right_node == tcx->basin.bottom_node)
+    {
+      /* No valid basins */
+      return;
+    }
+
+  tcx->basin.width = tcx->basin.right_node->point->x - tcx->basin.left_node->point->x;
+  tcx->basin.left_highest = tcx->basin.left_node->point->y > tcx->basin.right_node->point->y;
+
+  p2t_sweep_fill_basin_req (THIS, tcx, tcx->basin.bottom_node);
+}
+
+void
+p2t_sweep_fill_basin_req (P2tSweep *THIS, P2tSweepContext *tcx, P2tNode* node)
+{
+  /* if shallow stop filling */
+  if (p2t_sweep_is_shallow (THIS, tcx, node))
+    {
+      return;
+    }
+
+  p2t_sweep_fill (THIS, tcx, node);
+
+  if (node->prev == tcx->basin.left_node && node->next == tcx->basin.right_node)
+    {
+      return;
+    }
+  else if (node->prev == tcx->basin.left_node)
+    {
+      P2tOrientation o = p2t_orient2d (node->point, node->next->point, node->next->next->point);
+      if (o == CW)
+        {
+          return;
+        }
+      node = node->next;
+    }
+  else if (node->next == tcx->basin.right_node)
+    {
+      P2tOrientation o = p2t_orient2d (node->point, node->prev->point, node->prev->prev->point);
+      if (o == CCW)
+        {
+          return;
+        }
+      node = node->prev;
+    }
+  else
+    {
+      /* Continue with the neighbor node with lowest Y value */
+      if (node->prev->point->y < node->next->point->y)
+        {
+          node = node->prev;
+        }
+      else
+        {
+          node = node->next;
+        }
+    }
+
+  p2t_sweep_fill_basin_req (THIS, tcx, node);
+}
+
+gboolean
+p2t_sweep_is_shallow (P2tSweep *THIS, P2tSweepContext *tcx, P2tNode* node)
+{
+  double height;
+
+  if (tcx->basin.left_highest)
+    {
+      height = tcx->basin.left_node->point->y - node->point->y;
+    }
+  else
+    {
+      height = tcx->basin.right_node->point->y - node->point->y;
+    }
+
+  /* if shallow stop filling */
+  if (tcx->basin.width > height)
+    {
+      return TRUE;
+    }
+  return FALSE;
+}
+
+void
+p2t_sweep_fill_edge_event (P2tSweep *THIS, P2tSweepContext *tcx, P2tEdge* edge, P2tNode* node)
+{
+  if (tcx->edge_event.right)
+    {
+      p2t_sweep_fill_right_above_edge_event (THIS, tcx, edge, node);
+    }
+  else
+    {
+      p2t_sweep_fill_left_above_edge_event (THIS, tcx, edge, node);
+    }
+}
+
+void
+p2t_sweep_fill_right_above_edge_event (P2tSweep *THIS, P2tSweepContext *tcx, P2tEdge* edge, P2tNode* node)
+{
+  while (node->next->point->x < edge->p->x)
+    {
+      /* Check if next node is below the edge */
+      if (p2t_orient2d (edge->q, node->next->point, edge->p) == CCW)
+        {
+          p2t_sweep_fill_right_below_edge_event (THIS, tcx, edge, node);
+        }
+      else
+        {
+          node = node->next;
+        }
+    }
+}
+
+void
+p2t_sweep_fill_right_below_edge_event (P2tSweep *THIS, P2tSweepContext *tcx, P2tEdge* edge, P2tNode* node)
+{
+  if (node->point->x < edge->p->x)
+    {
+      if (p2t_orient2d (node->point, node->next->point, node->next->next->point) == CCW)
+        {
+          /* Concave */
+          p2t_sweep_fill_right_concave_edge_event (THIS, tcx, edge, node);
+        }
+      else
+        {
+          /* Convex */
+          p2t_sweep_fill_right_convex_edge_event (THIS, tcx, edge, node);
+          /* Retry this one */
+          p2t_sweep_fill_right_below_edge_event (THIS, tcx, edge, node);
+        }
+    }
+}
+
+void
+p2t_sweep_fill_right_concave_edge_event (P2tSweep *THIS, P2tSweepContext *tcx, P2tEdge* edge, P2tNode* node)
+{
+  p2t_sweep_fill (THIS, tcx, node->next);
+  if (node->next->point != edge->p)
+    {
+      /* Next above or below edge? */
+      if (p2t_orient2d (edge->q, node->next->point, edge->p) == CCW)
+        {
+          /* Below */
+          if (p2t_orient2d (node->point, node->next->point, node->next->next->point) == CCW)
+            {
+              /* Next is concave */
+              p2t_sweep_fill_right_concave_edge_event (THIS, tcx, edge, node);
+            }
+          else
+            {
+              /* Next is convex */
+            }
+        }
+    }
+
+}
+
+void
+p2t_sweep_fill_right_convex_edge_event (P2tSweep *THIS, P2tSweepContext *tcx, P2tEdge* edge, P2tNode* node)
+{
+  /* Next concave or convex? */
+  if (p2t_orient2d (node->next->point, node->next->next->point, node->next->next->next->point) == CCW)
+    {
+      /* Concave */
+      p2t_sweep_fill_right_concave_edge_event (THIS, tcx, edge, node->next);
+    }
+  else
+    {
+      /* Convex
+       * Next above or below edge? */
+      if (p2t_orient2d (edge->q, node->next->next->point, edge->p) == CCW)
+        {
+          /* Below */
+          p2t_sweep_fill_right_convex_edge_event (THIS, tcx, edge, node->next);
+        }
+      else
+        {
+          /* Above */
+        }
+    }
+}
+
+void
+p2t_sweep_fill_left_above_edge_event (P2tSweep *THIS, P2tSweepContext *tcx, P2tEdge* edge, P2tNode* node)
+{
+  while (node->prev->point->x > edge->p->x)
+    {
+      /* Check if next node is below the edge */
+      if (p2t_orient2d (edge->q, node->prev->point, edge->p) == CW)
+        {
+          p2t_sweep_fill_left_below_edge_event (THIS, tcx, edge, node);
+        }
+      else
+        {
+          node = node->prev;
+        }
+    }
+}
+
+void
+p2t_sweep_fill_left_below_edge_event (P2tSweep *THIS, P2tSweepContext *tcx, P2tEdge* edge, P2tNode* node)
+{
+  if (node->point->x > edge->p->x)
+    {
+      if (p2t_orient2d (node->point, node->prev->point, node->prev->prev->point) == CW)
+        {
+          /* Concave */
+          p2t_sweep_fill_left_concave_edge_event (THIS, tcx, edge, node);
+        }
+      else
+        {
+          /* Convex */
+          p2t_sweep_fill_left_convex_edge_event (THIS, tcx, edge, node);
+          /* Retry this one */
+          p2t_sweep_fill_left_below_edge_event (THIS, tcx, edge, node);
+        }
+    }
+}
+
+void
+p2t_sweep_fill_left_convex_edge_event (P2tSweep *THIS, P2tSweepContext *tcx, P2tEdge* edge, P2tNode* node)
+{
+  /* Next concave or convex? */
+  if (p2t_orient2d (node->prev->point, node->prev->prev->point, node->prev->prev->prev->point) == CW)
+    {
+      /* Concave */
+      p2t_sweep_fill_left_concave_edge_event (THIS, tcx, edge, node->prev);
+    }
+  else
+    {
+      /* Convex
+       * Next above or below edge? */
+      if (p2t_orient2d (edge->q, node->prev->prev->point, edge->p) == CW)
+        {
+          /* Below */
+          p2t_sweep_fill_left_convex_edge_event (THIS, tcx, edge, node->prev);
+        }
+      else
+        {
+          /* Above */
+        }
+    }
+}
+
+void
+p2t_sweep_fill_left_concave_edge_event (P2tSweep *THIS, P2tSweepContext *tcx, P2tEdge* edge, P2tNode* node)
+{
+  p2t_sweep_fill (THIS, tcx, node->prev);
+  if (node->prev->point != edge->p)
+    {
+      /* Next above or below edge? */
+      if (p2t_orient2d (edge->q, node->prev->point, edge->p) == CW)
+        {
+          /* Below */
+          if (p2t_orient2d (node->point, node->prev->point, node->prev->prev->point) == CW)
+            {
+              /* Next is concave */
+              p2t_sweep_fill_left_concave_edge_event (THIS, tcx, edge, node);
+            }
+          else
+            {
+              /* Next is convex */
+            }
+        }
+    }
+
+}
+
+void
+p2t_sweep_flip_edge_event (P2tSweep *THIS, P2tSweepContext *tcx, P2tPoint* ep, P2tPoint* eq, P2tTriangle* t, P2tPoint* p)
+{
+  P2tTriangle* ot = p2t_triangle_neighbor_across (t, p);
+  P2tPoint* op = p2t_triangle_opposite_point (ot, t, p);
+
+  if (ot == NULL)
+    {
+      /* If we want to integrate the fillEdgeEvent do it here
+       * With current implementation we should never get here
+       *throw new RuntimeException( "[BUG:FIXME] FLIP failed due to missing triangle");
+       */
+      assert (0);
+    }
+
+  if (p2t_utils_in_scan_area (p, p2t_triangle_point_ccw (t, p), p2t_triangle_point_cw (t, p), op))
+    {
+      /* Lets rotate shared edge one vertex CW */
+      p2t_sweep_rotate_triangle_pair (THIS, t, p, ot, op);
+      p2t_sweepcontext_map_triangle_to_nodes (tcx, t);
+      p2t_sweepcontext_map_triangle_to_nodes (tcx, ot);
+
+      if (p == eq && op == ep)
+        {
+          if (p2t_point_equals (eq, tcx->edge_event.constrained_edge->q) && p2t_point_equals (ep, tcx->edge_event.constrained_edge->p))
+            {
+              p2t_triangle_mark_constrained_edge_pt_pt (t, ep, eq);
+              p2t_triangle_mark_constrained_edge_pt_pt (ot, ep, eq);
+              p2t_sweep_legalize (THIS, tcx, t);
+              p2t_sweep_legalize (THIS, tcx, ot);
+            }
+          else
+            {
+              /* XXX: I think one of the triangles should be legalized here? */
+            }
+        }
+      else
+        {
+          P2tOrientation o = p2t_orient2d (eq, op, ep);
+          t = p2t_sweep_next_flip_triangle (THIS, tcx, (int) o, t, ot, p, op);
+          p2t_sweep_flip_edge_event (THIS, tcx, ep, eq, t, p);
+        }
+    }
+  else
+    {
+      P2tPoint* newP = p2t_sweep_next_flip_point (THIS, ep, eq, ot, op);
+      p2t_sweep_flip_scan_edge_event (THIS, tcx, ep, eq, t, ot, newP);
+      p2t_sweep_edge_event_pt_pt_tr_pt (THIS, tcx, ep, eq, t, p);
+    }
+}
+
+P2tTriangle*
+p2t_sweep_next_flip_triangle (P2tSweep *THIS, P2tSweepContext *tcx, int o, P2tTriangle *t, P2tTriangle *ot, P2tPoint* p, P2tPoint* op)
+{
+  int edge_index;
+
+  if (o == CCW)
+    {
+      /* ot is not crossing edge after flip */
+      int edge_index = p2t_triangle_edge_index (ot, p, op);
+      ot->delaunay_edge[edge_index] = TRUE;
+      p2t_sweep_legalize (THIS, tcx, ot);
+      p2t_triangle_clear_delunay_edges (ot);
+      return t;
+    }
+
+  /* t is not crossing edge after flip */
+  edge_index = p2t_triangle_edge_index (t, p, op);
+
+  t->delaunay_edge[edge_index] = TRUE;
+  p2t_sweep_legalize (THIS, tcx, t);
+  p2t_triangle_clear_delunay_edges (t);
+  return ot;
+}
+
+P2tPoint*
+p2t_sweep_next_flip_point (P2tSweep *THIS, P2tPoint* ep, P2tPoint* eq, P2tTriangle *ot, P2tPoint* op)
+{
+  P2tOrientation o2d = p2t_orient2d (eq, op, ep);
+  if (o2d == CW)
+    {
+      /* Right */
+      return p2t_triangle_point_ccw (ot, op);
+    }
+  else if (o2d == CCW)
+    {
+      /* Left */
+      return p2t_triangle_point_cw (ot, op);
+    }
+  else
+    {
+      /*throw new RuntimeException("[Unsupported] Opposing point on constrained edge");*/
+      assert (0);
+    }
+}
+
+void
+p2t_sweep_flip_scan_edge_event (P2tSweep *THIS, P2tSweepContext *tcx, P2tPoint* ep, P2tPoint* eq, P2tTriangle *flip_triangle,
+                                P2tTriangle *t, P2tPoint* p)
+{
+  P2tTriangle* ot = p2t_triangle_neighbor_across (t, p);
+  P2tPoint* op = p2t_triangle_opposite_point (ot, t, p);
+
+  if (p2t_triangle_neighbor_across (t, p) == NULL)
+    {
+      /* If we want to integrate the fillEdgeEvent do it here
+       * With current implementation we should never get here
+       *throw new RuntimeException( "[BUG:FIXME] FLIP failed due to missing triangle");
+       */
+      assert (0);
+    }
+
+  if (p2t_utils_in_scan_area (eq, p2t_triangle_point_ccw (flip_triangle, eq), p2t_triangle_point_cw (flip_triangle, eq), op))
+    {
+      /* flip with new edge op->eq */
+      p2t_sweep_flip_edge_event (THIS, tcx, eq, op, ot, op);
+      /* TODO: Actually I just figured out that it should be possible to
+       *       improve this by getting the next ot and op before the the above
+       *       flip and continue the flipScanEdgeEvent here
+       * set new ot and op here and loop back to inScanArea test
+       * also need to set a new flip_triangle first
+       * Turns out at first glance that this is somewhat complicated
+       * so it will have to wait. */
+    }
+  else
+    {
+      P2tPoint* newP = p2t_sweep_next_flip_point (THIS, ep, eq, ot, op);
+      p2t_sweep_flip_scan_edge_event (THIS, tcx, ep, eq, flip_triangle, ot, newP);
+    }
+}
index 73cb4ca6172a7eb6559c0f8d91cfe7e9a891e256..0596ecc886161c05c8ae40c2ca16eb0047bbf8c3 100644 (file)
-/*\r
- * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors\r
- * http://code.google.com/p/poly2tri/\r
- *\r
- * All rights reserved.\r
- *\r
- * Redistribution and use in source and binary forms, with or without modification,\r
- * are permitted provided that the following conditions are met:\r
- *\r
- * * Redistributions of source code must retain the above copyright notice,\r
- *   this list of conditions and the following disclaimer.\r
- * * Redistributions in binary form must reproduce the above copyright notice,\r
- *   this list of conditions and the following disclaimer in the documentation\r
- *   and/or other materials provided with the distribution.\r
- * * Neither the name of Poly2Tri nor the names of its contributors may be\r
- *   used to endorse or promote products derived from this software without specific\r
- *   prior written permission.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\r
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\r
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\r
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\r
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\r
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\r
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
- */\r
-\r
-#ifndef SWEEP_CONTEXT_H\r
-#define SWEEP_CONTEXT_H\r
-\r
-#include "../common/poly2tri-private.h"\r
-#include "../common/shapes.h"\r
-#include "advancing_front.h"\r
-\r
-/* Inital triangle factor, seed triangle will extend 30% of\r
- * PointSet width to both left and right. */\r
-#define kAlpha 0.3\r
-\r
-struct P2tSweepContextBasin_\r
-{\r
-  P2tNode* left_node;\r
-  P2tNode* bottom_node;\r
-  P2tNode* right_node;\r
-  double width;\r
-  gboolean left_highest;\r
-};\r
-\r
-void p2t_sweepcontext_basin_init (P2tSweepContextBasin* THIS);\r
-void p2t_sweepcontext_basin_clear (P2tSweepContextBasin* THIS);\r
-\r
-struct P2tSweepContextEdgeEvent_\r
-{\r
-  P2tEdge* constrained_edge;\r
-  gboolean right;\r
-};\r
-\r
-void p2t_sweepcontext_edgeevent_init (P2tSweepContextEdgeEvent* THIS);\r
-\r
-struct SweepContext_\r
-{\r
-  P2tEdgePtrArray edge_list;\r
-\r
-  P2tSweepContextBasin basin;\r
-  P2tSweepContextEdgeEvent edge_event;\r
-\r
-  P2tTrianglePtrArray triangles_;\r
-  P2tTrianglePtrList map_;\r
-  P2tPointPtrArray points_;\r
-\r
-  /** Advancing front */\r
-  P2tAdvancingFront* front_;\r
-  /** head point used with advancing front */\r
-  P2tPoint* head_;\r
-  /** tail point used with advancing front */\r
-  P2tPoint* tail_;\r
-\r
-  P2tNode *af_head_, *af_middle_, *af_tail_;\r
-};\r
-\r
-/** Constructor */\r
-void p2t_sweepcontext_init (P2tSweepContext* THIS, P2tPointPtrArray polyline);\r
-P2tSweepContext* p2t_sweepcontext_new (P2tPointPtrArray polyline);\r
-\r
-/** Destructor */\r
-void p2t_sweepcontext_destroy (P2tSweepContext* THIS);\r
-void p2t_sweepcontext_delete (P2tSweepContext* THIS);\r
-\r
-void p2t_sweepcontext_set_head (P2tSweepContext *THIS, P2tPoint* p1);\r
-\r
-P2tPoint* p2t_sweepcontext_head (P2tSweepContext *THIS);\r
-\r
-void p2t_sweepcontext_set_tail (P2tSweepContext *THIS, P2tPoint* p1);\r
-\r
-P2tPoint* p2t_sweepcontext_tail (P2tSweepContext *THIS);\r
-\r
-int p2t_sweepcontext_point_count (P2tSweepContext *THIS);\r
-\r
-P2tNode* p2t_sweepcontext_locate_node (P2tSweepContext *THIS, P2tPoint* point);\r
-\r
-void p2t_sweepcontext_remove_node (P2tSweepContext *THIS, P2tNode* node);\r
-\r
-void p2t_sweepcontext_create_advancingfront (P2tSweepContext *THIS, P2tNodePtrArray nodes);\r
-\r
-/** Try to map a node to all sides of this triangle that don't have a neighbor */\r
-void p2t_sweepcontext_map_triangle_to_nodes (P2tSweepContext *THIS, P2tTriangle* t);\r
-\r
-void p2t_sweepcontext_add_to_map (P2tSweepContext *THIS, P2tTriangle* triangle);\r
-\r
-P2tPoint* p2t_sweepcontext_get_point (P2tSweepContext *THIS, const int index);\r
-\r
-P2tPoint* SweepContext_GetPoints (P2tSweepContext *THIS);\r
-\r
-void p2t_sweepcontext_remove_from_map (P2tSweepContext *THIS, P2tTriangle* triangle);\r
-\r
-void p2t_sweepcontext_add_hole (P2tSweepContext *THIS, P2tPointPtrArray polyline);\r
-\r
-void p2t_sweepcontext_add_point (P2tSweepContext *THIS, P2tPoint* point);\r
-\r
-P2tAdvancingFront* p2t_sweepcontext_front (P2tSweepContext *THIS);\r
-\r
-void p2t_sweepcontext_mesh_clean (P2tSweepContext *THIS, P2tTriangle* triangle);\r
-\r
-P2tTrianglePtrArray p2t_sweepcontext_get_triangles (P2tSweepContext *THIS);\r
-P2tTrianglePtrList p2t_sweepcontext_get_map (P2tSweepContext *THIS);\r
-\r
-void p2t_sweepcontext_init_triangulation (P2tSweepContext *THIS);\r
-void p2t_sweepcontext_init_edges (P2tSweepContext *THIS, P2tPointPtrArray polyline);\r
-\r
-#endif\r
+/*
+ * Poly2Tri Copyright (c) 2009-2010, Poly2Tri Contributors
+ * http://code.google.com/p/poly2tri/
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ *   this list of conditions and the following disclaimer in the documentation
+ *   and/or other materials provided with the distribution.
+ * * Neither the name of Poly2Tri nor the names of its contributors may be
+ *   used to endorse or promote products derived from this software without specific
+ *   prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SWEEP_CONTEXT_H
+#define SWEEP_CONTEXT_H
+
+#include "../common/poly2tri-private.h"
+#include "../common/shapes.h"
+#include "advancing_front.h"
+
+/* Inital triangle factor, seed triangle will extend 30% of
+ * PointSet width to both left and right. */
+#define kAlpha 0.3
+
+struct P2tSweepContextBasin_
+{
+  P2tNode* left_node;
+  P2tNode* bottom_node;
+  P2tNode* right_node;
+  double width;
+  gboolean left_highest;
+};
+
+void p2t_sweepcontext_basin_init (P2tSweepContextBasin* THIS);
+void p2t_sweepcontext_basin_clear (P2tSweepContextBasin* THIS);
+
+struct P2tSweepContextEdgeEvent_
+{
+  P2tEdge* constrained_edge;
+  gboolean right;
+};
+
+void p2t_sweepcontext_edgeevent_init (P2tSweepContextEdgeEvent* THIS);
+
+struct SweepContext_
+{
+  P2tEdgePtrArray edge_list;
+
+  P2tSweepContextBasin basin;
+  P2tSweepContextEdgeEvent edge_event;
+
+  P2tTrianglePtrArray triangles_;
+  P2tTrianglePtrList map_;
+  P2tPointPtrArray points_;
+
+  /** Advancing front */
+  P2tAdvancingFront* front_;
+  /** head point used with advancing front */
+  P2tPoint* head_;
+  /** tail point used with advancing front */
+  P2tPoint* tail_;
+
+  P2tNode *af_head_, *af_middle_, *af_tail_;
+};
+
+/** Constructor */
+void p2t_sweepcontext_init (P2tSweepContext* THIS, P2tPointPtrArray polyline);
+P2tSweepContext* p2t_sweepcontext_new (P2tPointPtrArray polyline);
+
+/** Destructor */
+void p2t_sweepcontext_destroy (P2tSweepContext* THIS);
+void p2t_sweepcontext_delete (P2tSweepContext* THIS);
+
+void p2t_sweepcontext_set_head (P2tSweepContext *THIS, P2tPoint* p1);
+
+P2tPoint* p2t_sweepcontext_head (P2tSweepContext *THIS);
+
+void p2t_sweepcontext_set_tail (P2tSweepContext *THIS, P2tPoint* p1);
+
+P2tPoint* p2t_sweepcontext_tail (P2tSweepContext *THIS);
+
+int p2t_sweepcontext_point_count (P2tSweepContext *THIS);
+
+P2tNode* p2t_sweepcontext_locate_node (P2tSweepContext *THIS, P2tPoint* point);
+
+void p2t_sweepcontext_remove_node (P2tSweepContext *THIS, P2tNode* node);
+
+void p2t_sweepcontext_create_advancingfront (P2tSweepContext *THIS, P2tNodePtrArray nodes);
+
+/** Try to map a node to all sides of this triangle that don't have a neighbor */
+void p2t_sweepcontext_map_triangle_to_nodes (P2tSweepContext *THIS, P2tTriangle* t);
+
+void p2t_sweepcontext_add_to_map (P2tSweepContext *THIS, P2tTriangle* triangle);
+
+P2tPoint* p2t_sweepcontext_get_point (P2tSweepContext *THIS, const int index);
+
+P2tPoint* SweepContext_GetPoints (P2tSweepContext *THIS);
+
+void p2t_sweepcontext_remove_from_map (P2tSweepContext *THIS, P2tTriangle* triangle);
+
+void p2t_sweepcontext_add_hole (P2tSweepContext *THIS, P2tPointPtrArray polyline);
+
+void p2t_sweepcontext_add_point (P2tSweepContext *THIS, P2tPoint* point);
+
+P2tAdvancingFront* p2t_sweepcontext_front (P2tSweepContext *THIS);
+
+void p2t_sweepcontext_mesh_clean (P2tSweepContext *THIS, P2tTriangle* triangle);
+
+P2tTrianglePtrArray p2t_sweepcontext_get_triangles (P2tSweepContext *THIS);
+P2tTrianglePtrList p2t_sweepcontext_get_map (P2tSweepContext *THIS);
+
+void p2t_sweepcontext_init_triangulation (P2tSweepContext *THIS);
+void p2t_sweepcontext_init_edges (P2tSweepContext *THIS, P2tPointPtrArray polyline);
+
+#endif
index fdf96d50b17bd619a612dd829f9f48a1426ff0bb..59b9986b3c6015ae2f1eb23170056fb98ccaf376 100644 (file)
@@ -1,52 +1,52 @@
 #include <glib.h>
 #include "bounded-line.h"
 
-P2trBoundedLine*\r
-p2tr_bounded_line_new (const P2trVector2 *start,\r
-                       const P2trVector2 *end)\r
-{\r
-  P2trBoundedLine* line = g_slice_new (P2trBoundedLine);\r
-  p2tr_bounded_line_init (line, start, end);\r
-  return line;\r
-}\r
-\r
-void\r
-p2tr_bounded_line_init (P2trBoundedLine   *line,\r
-                        const P2trVector2 *start,\r
-                        const P2trVector2 *end)\r
-{\r
-  /* Traditional line Equation:\r
-   * y - mx - n = 0   <==>   y = mx + n\r
-   * Slope Equation:\r
-   * m = dy / dx\r
-   * Slope + Traditional:\r
-   * dx * y - dy * x - dx * n = 0\r
-   * And the remaining part can be found as\r
-   * dx * y0 - dy * x0 = dx * n\r
-   * So the final equation is:\r
-   * dx * y - dy * x - (dx * y0 - dy * x0) = 0\r
-   */\r
-  gdouble dx = end->x - start->x;\r
-  gdouble dy = end->y - start->y;\r
-\r
-  gdouble dxXn = start->y * dx - start->x * dy;\r
-\r
-  p2tr_line_init(&line->infinite, -dy, dx, -dxXn);\r
-\r
-  p2tr_vector2_copy(&line->start, start);\r
-  p2tr_vector2_copy(&line->end, end);\r
-}\r
-\r
-gboolean\r
-p2tr_bounded_line_intersect (const P2trBoundedLine *l1,\r
-                             const P2trBoundedLine *l2)\r
-{\r
-  return p2tr_line_different_sides (&l1->infinite, &l2->start, &l2->end)\r
-    && p2tr_line_different_sides (&l2->infinite, &l1->start, &l1->end);\r
-}\r
-\r
-void\r
-p2tr_bounded_line_free (P2trBoundedLine *line)\r
-{\r
-  g_slice_free (P2trBoundedLine, line);\r
-}\r
+P2trBoundedLine*
+p2tr_bounded_line_new (const P2trVector2 *start,
+                       const P2trVector2 *end)
+{
+  P2trBoundedLine* line = g_slice_new (P2trBoundedLine);
+  p2tr_bounded_line_init (line, start, end);
+  return line;
+}
+
+void
+p2tr_bounded_line_init (P2trBoundedLine   *line,
+                        const P2trVector2 *start,
+                        const P2trVector2 *end)
+{
+  /* Traditional line Equation:
+   * y - mx - n = 0   <==>   y = mx + n
+   * Slope Equation:
+   * m = dy / dx
+   * Slope + Traditional:
+   * dx * y - dy * x - dx * n = 0
+   * And the remaining part can be found as
+   * dx * y0 - dy * x0 = dx * n
+   * So the final equation is:
+   * dx * y - dy * x - (dx * y0 - dy * x0) = 0
+   */
+  gdouble dx = end->x - start->x;
+  gdouble dy = end->y - start->y;
+
+  gdouble dxXn = start->y * dx - start->x * dy;
+
+  p2tr_line_init(&line->infinite, -dy, dx, -dxXn);
+
+  p2tr_vector2_copy(&line->start, start);
+  p2tr_vector2_copy(&line->end, end);
+}
+
+gboolean
+p2tr_bounded_line_intersect (const P2trBoundedLine *l1,
+                             const P2trBoundedLine *l2)
+{
+  return p2tr_line_different_sides (&l1->infinite, &l2->start, &l2->end)
+    && p2tr_line_different_sides (&l2->infinite, &l1->start, &l1->end);
+}
+
+void
+p2tr_bounded_line_free (P2trBoundedLine *line)
+{
+  g_slice_free (P2trBoundedLine, line);
+}
index 5e33eaf73d568b3942cab96870f3b52a3e34993b..db5c40cfac535ef41dedb1939540bb202d446f8a 100644 (file)
@@ -1,26 +1,26 @@
-#ifndef __P2TC_REFINE_BOUNDED_LINE_H__\r
-#define __P2TC_REFINE_BOUNDED_LINE_H__\r
+#ifndef __P2TC_REFINE_BOUNDED_LINE_H__
+#define __P2TC_REFINE_BOUNDED_LINE_H__
 
-#include <glib.h>\r
+#include <glib.h>
 #include "vector2.h"
 #include "line.h"
-\r
-typedef struct\r
-{\r
-  P2trLine infinite;\r
-  P2trVector2 start, end;\r
-} P2trBoundedLine;\r
-\r
-P2trBoundedLine*  p2tr_bounded_line_new       (const P2trVector2 *start,\r
-                                               const P2trVector2 *end);\r
-\r
-void              p2tr_bounded_line_init      (P2trBoundedLine   *line,\r
-                                               const P2trVector2 *start,\r
-                                               const P2trVector2 *end);\r
-\r
-gboolean          p2tr_bounded_line_intersect (const P2trBoundedLine *l1,\r
-                                               const P2trBoundedLine *l2);\r
-\r
-void              p2tr_bounded_line_free      (P2trBoundedLine *line);\r
-\r
+
+typedef struct
+{
+  P2trLine infinite;
+  P2trVector2 start, end;
+} P2trBoundedLine;
+
+P2trBoundedLine*  p2tr_bounded_line_new       (const P2trVector2 *start,
+                                               const P2trVector2 *end);
+
+void              p2tr_bounded_line_init      (P2trBoundedLine   *line,
+                                               const P2trVector2 *start,
+                                               const P2trVector2 *end);
+
+gboolean          p2tr_bounded_line_intersect (const P2trBoundedLine *l1,
+                                               const P2trBoundedLine *l2);
+
+void              p2tr_bounded_line_free      (P2trBoundedLine *line);
+
 #endif
\ No newline at end of file
index ad6e1abb95529e28647679c37abc9552b5cfd580..9f0cc205abf29342ac6c2ce0d0a4e239e5d555fb 100644 (file)
@@ -1,15 +1,15 @@
 #include <glib.h>
 #include "circle.h"
 
-gboolean\r
-p2tr_circle_test_point_outside (P2trCircle  *circle,\r
-                                P2trVector2 *pt)\r
-{\r
-  gdouble dx = circle->center.x - pt->x;\r
-  gdouble dy = circle->center.y - pt->y;\r
-\r
-  gdouble d_squared = dx * dx + dy * dy;\r
-  gdouble radius_squared = circle->radius * circle->radius;\r
-\r
-  return d_squared > radius_squared;\r
+gboolean
+p2tr_circle_test_point_outside (P2trCircle  *circle,
+                                P2trVector2 *pt)
+{
+  gdouble dx = circle->center.x - pt->x;
+  gdouble dy = circle->center.y - pt->y;
+
+  gdouble d_squared = dx * dx + dy * dy;
+  gdouble radius_squared = circle->radius * circle->radius;
+
+  return d_squared > radius_squared;
 }
\ No newline at end of file
index 02b1cc3d0dd9cec3d9cd4ab99282c55566b97240..845f73756bb8421b2a9e9916fb307f89e5c2fe39 100644 (file)
@@ -1,14 +1,14 @@
-#ifndef __P2TC_REFINE_CIRCLE_H__\r
-#define __P2TC_REFINE_CIRCLE_H__\r
-\r
-#include <glib.h>\r
+#ifndef __P2TC_REFINE_CIRCLE_H__
+#define __P2TC_REFINE_CIRCLE_H__
+
+#include <glib.h>
 #include "vector2.h"
-\r
-typedef struct {\r
-  P2trVector2 center;\r
-  gdouble radius;\r
-} P2trCircle;\r
-\r
-gboolean  p2tr_circle_test_point_outside (P2trCircle *circle, P2trVector2 *pt);\r
-\r
+
+typedef struct {
+  P2trVector2 center;
+  gdouble radius;
+} P2trCircle;
+
+gboolean  p2tr_circle_test_point_outside (P2trCircle *circle, P2trVector2 *pt);
+
 #endif
\ No newline at end of file
index 4b0457f0f6c6d92cc6657a72f2f88205c764ea16..9c20e0e9474a0875cfbea581178fb37a972d976d 100644 (file)
@@ -1,70 +1,70 @@
 #include <glib.h>
 #include "line.h"
 
-void\r
-p2tr_line_init (P2trLine    *line,\r
-                gdouble      a,\r
-                gdouble      b,\r
-                gdouble      c)\r
-{\r
-  line->a = a;\r
-  line->b = b;\r
-  line->c = c;\r
-}\r
-\r
-gboolean\r
-p2tr_line_different_sides (const P2trLine    *line,\r
-                           const P2trVector2 *pt1,\r
-                           const P2trVector2 *pt2)\r
-{\r
-  gdouble side1 = line->a * pt1->x + line->b * pt1->y + line->c;\r
-  gdouble side2 = line->a * pt2->x + line->b * pt2->y + line->c;\r
-\r
-  /* Signs are different if the product is negative */\r
-  return side1 * side2 < 0;\r
-}\r
-\r
-P2trLineRelation\r
-p2tr_line_intersection (const P2trLine    *l1,\r
-                        const P2trLine    *l2,\r
-                        P2trVector2       *out_intersection)\r
-{\r
-  /* In order to find the intersection, we intend to solve\r
-   * the following set of equations:\r
-   *\r
-   *   ( A1 B1 ) ( x ) = ( -C1 )\r
-   *   ( A2 B2 ) ( y ) = ( -C2 )\r
-   *\r
-   * We can simplify the solution using Cramers Rule which\r
-   * gives the following results:\r
-   *\r
-   *   x = (-C1 * B2) - (-C2 * B1) / (A1 * B2 - A2 * B1)\r
-   *   y = (A1 * -C2) - (A2 * -C1) / (A1 * B2 - A2 * B1)\r
-   */\r
-  double d = l1->a * l2->b - l2->a * l1->b;\r
-\r
-  /* If the denominator in the result of applying Cramers rule\r
-   * is zero, then the lines have exactly the same slope, meaning\r
-   * they are either exactly the same or they are parallel and\r
-   * never intersect */\r
-  if (d == 0)\r
-    {\r
-      /* We want to check if the offsets of boths the lines are the\r
-       * same, i.e. whether:  C1 / A1 = C2 / A2\r
-       * This test can be done without zero division errors if we do\r
-       * it in like this:     C1 * A2 = C2 * A1\r
-       */\r
-      if (l1->c * l2->a == l1->a * l2->c)\r
-        return P2TR_LINE_RELATION_SAME;\r
-      else\r
-        return P2TR_LINE_RELATION_PARALLEL;\r
-    }\r
-\r
-  if (out_intersection != NULL)\r
-    {\r
-      out_intersection->x = (-l1->c * l2->b + l2->c * l1->b) / d;\r
-      out_intersection->y = (l1->a * -l2->c + l2->a * l1->c) / d;\r
-    }\r
-\r
-  return P2TR_LINE_RELATION_INTERSECTING;\r
+void
+p2tr_line_init (P2trLine    *line,
+                gdouble      a,
+                gdouble      b,
+                gdouble      c)
+{
+  line->a = a;
+  line->b = b;
+  line->c = c;
+}
+
+gboolean
+p2tr_line_different_sides (const P2trLine    *line,
+                           const P2trVector2 *pt1,
+                           const P2trVector2 *pt2)
+{
+  gdouble side1 = line->a * pt1->x + line->b * pt1->y + line->c;
+  gdouble side2 = line->a * pt2->x + line->b * pt2->y + line->c;
+
+  /* Signs are different if the product is negative */
+  return side1 * side2 < 0;
+}
+
+P2trLineRelation
+p2tr_line_intersection (const P2trLine    *l1,
+                        const P2trLine    *l2,
+                        P2trVector2       *out_intersection)
+{
+  /* In order to find the intersection, we intend to solve
+   * the following set of equations:
+   *
+   *   ( A1 B1 ) ( x ) = ( -C1 )
+   *   ( A2 B2 ) ( y ) = ( -C2 )
+   *
+   * We can simplify the solution using Cramers Rule which
+   * gives the following results:
+   *
+   *   x = (-C1 * B2) - (-C2 * B1) / (A1 * B2 - A2 * B1)
+   *   y = (A1 * -C2) - (A2 * -C1) / (A1 * B2 - A2 * B1)
+   */
+  double d = l1->a * l2->b - l2->a * l1->b;
+
+  /* If the denominator in the result of applying Cramers rule
+   * is zero, then the lines have exactly the same slope, meaning
+   * they are either exactly the same or they are parallel and
+   * never intersect */
+  if (d == 0)
+    {
+      /* We want to check if the offsets of boths the lines are the
+       * same, i.e. whether:  C1 / A1 = C2 / A2
+       * This test can be done without zero division errors if we do
+       * it in like this:     C1 * A2 = C2 * A1
+       */
+      if (l1->c * l2->a == l1->a * l2->c)
+        return P2TR_LINE_RELATION_SAME;
+      else
+        return P2TR_LINE_RELATION_PARALLEL;
+    }
+
+  if (out_intersection != NULL)
+    {
+      out_intersection->x = (-l1->c * l2->b + l2->c * l1->b) / d;
+      out_intersection->y = (l1->a * -l2->c + l2->a * l1->c) / d;
+    }
+
+  return P2TR_LINE_RELATION_INTERSECTING;
 }
\ No newline at end of file
index c68e05fabb256492346190a71f9f4f6c3443b7a2..9431fefcb0f750e73180d0550938e9351c4297fa 100644 (file)
@@ -1,34 +1,34 @@
-#ifndef __P2TC_REFINE_LINE_H__\r
-#define __P2TC_REFINE_LINE_H__\r
-\r
+#ifndef __P2TC_REFINE_LINE_H__
+#define __P2TC_REFINE_LINE_H__
+
 #include <glib.h>
-#include "vector2.h"\r
-\r
-/* A line is the equation of the following form:\r
- *   a * X + b * Y + c = 0\r
- */\r
-typedef struct {\r
-  gdouble a, b, c;\r
-} P2trLine;\r
-\r
-typedef enum\r
-{\r
-  P2TR_LINE_RELATION_INTERSECTING = 0,\r
-  P2TR_LINE_RELATION_PARALLEL = 1,\r
-  P2TR_LINE_RELATION_SAME = 2\r
-} P2trLineRelation;\r
-\r
-void              p2tr_line_init            (P2trLine    *line,\r
-                                             gdouble      a,\r
-                                             gdouble      b,\r
-                                             gdouble      c);\r
-\r
-gboolean          p2tr_line_different_sides (const P2trLine    *line,\r
-                                             const P2trVector2 *pt1,\r
-                                             const P2trVector2 *pt2);\r
-\r
-P2trLineRelation  p2tr_line_intersection    (const P2trLine    *l1,\r
-                                             const P2trLine    *l2,\r
-                                             P2trVector2       *out_intersection);\r
-\r
+#include "vector2.h"
+
+/* A line is the equation of the following form:
+ *   a * X + b * Y + c = 0
+ */
+typedef struct {
+  gdouble a, b, c;
+} P2trLine;
+
+typedef enum
+{
+  P2TR_LINE_RELATION_INTERSECTING = 0,
+  P2TR_LINE_RELATION_PARALLEL = 1,
+  P2TR_LINE_RELATION_SAME = 2
+} P2trLineRelation;
+
+void              p2tr_line_init            (P2trLine    *line,
+                                             gdouble      a,
+                                             gdouble      b,
+                                             gdouble      c);
+
+gboolean          p2tr_line_different_sides (const P2trLine    *line,
+                                             const P2trVector2 *pt1,
+                                             const P2trVector2 *pt2);
+
+P2trLineRelation  p2tr_line_intersection    (const P2trLine    *l1,
+                                             const P2trLine    *l2,
+                                             P2trVector2       *out_intersection);
+
 #endif
\ No newline at end of file
index b6279c7c6d5ec72527a442205823773315648f16..954a0fdfe72d8d83ab03edafec0b9f11324d9989 100644 (file)
@@ -1,66 +1,66 @@
-#include <math.h>\r
-#include <glib.h>\r
-#include "rmath.h"\r
-\r
-gdouble\r
-p2tr_math_length_sq (gdouble x1, gdouble y1,\r
-                     gdouble x2, gdouble y2)\r
-{\r
-  return P2TR_VECTOR2_DISTANCE_SQ2 (x1, y1, x2, y2);\r
-}\r
-\r
-gdouble\r
-p2tr_math_length_sq2 (const P2trVector2 *pt1,\r
-                      const P2trVector2 *pt2)\r
-{\r
-  return p2tr_math_length_sq (pt1->x, pt1->y, pt2->x, pt2->y);\r
-}\r
-\r
-static inline gdouble\r
-p2tr_matrix_det2 (gdouble a00, gdouble a01,\r
-                  gdouble a10, gdouble a11)\r
-{\r
-    return a00 * a11 - a10 * a01;\r
-}\r
-\r
-static inline gdouble\r
-p2tr_matrix_det3 (gdouble a00, gdouble a01, gdouble a02,\r
-                  gdouble a10, gdouble a11, gdouble a12,\r
-                  gdouble a20, gdouble a21, gdouble a22)\r
-{\r
-    return\r
-        + a00 * (a11 * a22 - a21 * a12)\r
-        - a01 * (a10 * a22 - a20 * a12)\r
-        + a02 * (a10 * a21 - a20 * a11);\r
-}\r
-\r
-static inline gdouble\r
-p2tr_matrix_det4 (gdouble a00, gdouble a01, gdouble a02, gdouble a03,\r
-                  gdouble a10, gdouble a11, gdouble a12, gdouble a13,\r
-                  gdouble a20, gdouble a21, gdouble a22, gdouble a23,\r
-                  gdouble a30, gdouble a31, gdouble a32, gdouble a33)\r
-{\r
-    return\r
-        + a00 * p2tr_matrix_det3 (a11, a12, a13,\r
-                                 a21, a22, a23,\r
-                                 a31, a32, a33)\r
-        - a01 * p2tr_matrix_det3 (a10, a12, a13,\r
-                                  a20, a22, a23,\r
-                                  a30, a32, a33)\r
-        + a02 * p2tr_matrix_det3 (a10, a11, a13,\r
-                                  a20, a21, a23,\r
-                                  a30, a31, a33)\r
-        - a03 * p2tr_matrix_det3 (a10, a11, a12,\r
-                                  a20, a21, a22,\r
-                                  a30, a31, a32);\r
-}\r
-\r
-void\r
-p2tr_math_triangle_circumcircle (const P2trVector2 *A,\r
-                                 const P2trVector2 *B,\r
-                                 const P2trVector2 *C,\r
-                                 P2trCircle    *circle)\r
-{\r
+#include <math.h>
+#include <glib.h>
+#include "rmath.h"
+
+gdouble
+p2tr_math_length_sq (gdouble x1, gdouble y1,
+                     gdouble x2, gdouble y2)
+{
+  return P2TR_VECTOR2_DISTANCE_SQ2 (x1, y1, x2, y2);
+}
+
+gdouble
+p2tr_math_length_sq2 (const P2trVector2 *pt1,
+                      const P2trVector2 *pt2)
+{
+  return p2tr_math_length_sq (pt1->x, pt1->y, pt2->x, pt2->y);
+}
+
+static inline gdouble
+p2tr_matrix_det2 (gdouble a00, gdouble a01,
+                  gdouble a10, gdouble a11)
+{
+    return a00 * a11 - a10 * a01;
+}
+
+static inline gdouble
+p2tr_matrix_det3 (gdouble a00, gdouble a01, gdouble a02,
+                  gdouble a10, gdouble a11, gdouble a12,
+                  gdouble a20, gdouble a21, gdouble a22)
+{
+    return
+        + a00 * (a11 * a22 - a21 * a12)
+        - a01 * (a10 * a22 - a20 * a12)
+        + a02 * (a10 * a21 - a20 * a11);
+}
+
+static inline gdouble
+p2tr_matrix_det4 (gdouble a00, gdouble a01, gdouble a02, gdouble a03,
+                  gdouble a10, gdouble a11, gdouble a12, gdouble a13,
+                  gdouble a20, gdouble a21, gdouble a22, gdouble a23,
+                  gdouble a30, gdouble a31, gdouble a32, gdouble a33)
+{
+    return
+        + a00 * p2tr_matrix_det3 (a11, a12, a13,
+                                 a21, a22, a23,
+                                 a31, a32, a33)
+        - a01 * p2tr_matrix_det3 (a10, a12, a13,
+                                  a20, a22, a23,
+                                  a30, a32, a33)
+        + a02 * p2tr_matrix_det3 (a10, a11, a13,
+                                  a20, a21, a23,
+                                  a30, a31, a33)
+        - a03 * p2tr_matrix_det3 (a10, a11, a12,
+                                  a20, a21, a22,
+                                  a30, a31, a32);
+}
+
+void
+p2tr_math_triangle_circumcircle (const P2trVector2 *A,
+                                 const P2trVector2 *B,
+                                 const P2trVector2 *C,
+                                 P2trCircle    *circle)
+{
   /*       | Ax Bx Cx |
    * D = + | Ay By Cy | * 2
    *       | +1 +1 +1 |
@@ -93,176 +93,176 @@ p2tr_math_triangle_circumcircle (const P2trVector2 *A,
       1,    1,    1) * invD;
 
   circle->radius = sqrt (P2TR_VECTOR2_DISTANCE_SQ (A, &circle->center));
-}\r
-\r
-/* The point in triangle test which is implemented below is based on the\r
- * algorithm which appears on:\r
- *\r
- *    http://www.blackpawn.com/texts/pointinpoly/default.html\r
- */\r
-void\r
-p2tr_math_triangle_barcycentric (const P2trVector2 *A,\r
-                                 const P2trVector2 *B,\r
-                                 const P2trVector2 *C,\r
-                                 const P2trVector2 *P,\r
-                                 gdouble           *u,\r
-                                 gdouble           *v)\r
-{\r
-  gdouble dot00, dot01, dot02, dot11, dot12, invDenom;\r
-\r
-  /* Compute the vectors offsetted so that A is the origin */\r
-  P2trVector2 v0, v1, v2;\r
-  p2tr_vector2_sub(C, A, &v0);\r
-  p2tr_vector2_sub(B, A, &v1);\r
-  p2tr_vector2_sub(P, A, &v2);\r
-\r
-  /* Compute dot products */\r
-  dot00 = P2TR_VECTOR2_DOT(&v0, &v0);\r
-  dot01 = P2TR_VECTOR2_DOT(&v0, &v1);\r
-  dot02 = P2TR_VECTOR2_DOT(&v0, &v2);\r
-  dot11 = P2TR_VECTOR2_DOT(&v1, &v1);\r
-  dot12 = P2TR_VECTOR2_DOT(&v1, &v2);\r
-\r
-  /* Compute barycentric coordinates */\r
-  invDenom = 1 / (dot00 * dot11 - dot01 * dot01);\r
-  *u = (dot11 * dot02 - dot01 * dot12) * invDenom;\r
-  *v = (dot00 * dot12 - dot01 * dot02) * invDenom;\r
-}\r
-\r
-#define INTRIANGLE_EPSILON 0e-9\r
-\r
-P2trInTriangle\r
-p2tr_math_intriangle (const P2trVector2 *A,\r
-                      const P2trVector2 *B,\r
-                      const P2trVector2 *C,\r
-                      const P2trVector2 *P)\r
-{\r
-  gdouble u, v;\r
-  return p2tr_math_intriangle2 (A, B, C, P, &u, &v);\r
-}\r
-\r
-P2trInTriangle\r
-p2tr_math_intriangle2 (const P2trVector2 *A,\r
-                       const P2trVector2 *B,\r
-                       const P2trVector2 *C,\r
-                       const P2trVector2 *P,\r
-                       gdouble           *u,\r
-                       gdouble           *v)\r
-{\r
-  p2tr_math_triangle_barcycentric (A, B, C, P, u, v);\r
-  \r
-  /* Check if point is in triangle - i.e. whether (u + v) < 1 and both\r
-   * u and v are positive */\r
-  if ((*u >= INTRIANGLE_EPSILON) && (*v >= INTRIANGLE_EPSILON) && (*u + *v < 1 - INTRIANGLE_EPSILON))\r
-    return P2TR_INTRIANGLE_IN;\r
-  else if ((*u >= -INTRIANGLE_EPSILON) && (*v >= -INTRIANGLE_EPSILON) && (*u + *v <= 1 + INTRIANGLE_EPSILON))\r
-    return P2TR_INTRIANGLE_ON;\r
-  else\r
-    return P2TR_INTRIANGLE_OUT;\r
-}\r
-\r
-/* The point in triangle circumcircle test, and the 3-point orientation\r
- * test, are both based on the work of Jonathan Richard Shewchuk. The\r
- * technique used here is described in his paper "Adaptive Precision\r
- * Floating-Point Arithmetic and Fast Robust Geometric Predicates"\r
- */\r
-\r
-#define ORIENT2D_EPSILON 1e-9\r
-\r
-P2trOrientation p2tr_math_orient2d (const P2trVector2 *A,\r
-                                    const P2trVector2 *B,\r
-                                    const P2trVector2 *C)\r
-{\r
-  /* We are trying to compute this determinant:\r
-   * |Ax Ay 1|\r
-   * |Bx By 1|\r
-   * |Cx Cy 1|\r
-   */\r
-  gdouble result = p2tr_matrix_det3 (\r
-      A->x, A->y, 1,\r
-      B->x, B->y, 1,\r
-      C->x, C->y, 1\r
-  );\r
-\r
-  if (result > ORIENT2D_EPSILON)\r
-    return P2TR_ORIENTATION_CCW;\r
-  else if (result < -ORIENT2D_EPSILON)\r
-    return P2TR_ORIENTATION_CW;\r
-  else\r
-    return P2TR_ORIENTATION_LINEAR;\r
-}\r
-\r
-#define INCIRCLE_EPSILON 1e-9\r
-\r
-P2trInCircle\r
-p2tr_math_incircle (const P2trVector2 *A,\r
-                    const P2trVector2 *B,\r
-                    const P2trVector2 *C,\r
-                    const P2trVector2 *D)\r
-{\r
-  /* We are trying to compute this determinant:\r
-   * |Ax Ay Ax^2+Ay^2 1|\r
-   * |Bx By Bx^2+By^2 1|\r
-   * |Cx Cy Cx^2+Cy^2 1|\r
-   * |Dx Dy Dx^2+Dy^2 1|\r
-   */\r
-  gdouble result = p2tr_matrix_det4 (\r
-      A->x, A->y, P2TR_VECTOR2_LEN_SQ(A), 1,\r
-      B->x, B->y, P2TR_VECTOR2_LEN_SQ(B), 1,\r
-      C->x, C->y, P2TR_VECTOR2_LEN_SQ(C), 1,\r
-      D->x, D->y, P2TR_VECTOR2_LEN_SQ(D), 1\r
-  );\r
-\r
-  if (result > INCIRCLE_EPSILON)\r
-    return P2TR_INCIRCLE_IN;\r
-  else if (result < INCIRCLE_EPSILON)\r
-    return P2TR_INCIRCLE_OUT;\r
-  else\r
-    return P2TR_INCIRCLE_ON;\r
-}\r
-\r
-/* The point inside diametral-circle test and the point inside diametral\r
- * lens test, are both based on the work of Jonathan Richard Shewchuk.\r
- * The techniques used here are partially described in his paper\r
- * "Delaunay Refinement Algorithms for Triangular Mesh Generation".\r
- *\r
- * W is inside the diametral circle (lens) of the line XY if and only if\r
- * the angle XWY is larger than 90 (120) degrees. We know how to compute\r
- * the cosine of that angle very easily like so:\r
- *\r
- * cos XWY = (WX * WY) / (|WX| * |WY|)\r
- *\r
- * Since XWY is larger than 90 (120) degrees, cos XWY <= 0 (-0.5) so:\r
- *\r
- * Diametral Circle               | Diametral Lens\r
- * -------------------------------+-----------------------------------\r
- * 0 >= (WX * WY) / (|WX| * |WY|) | - 0.5 >= (WX * WY) / (|WX| * |WY|)\r
- * 0 >= WX * WY                   | - 0.5 * |WX| * |WY| >= WX * WY\r
- */\r
-\r
-gboolean\r
-p2tr_math_diametral_circle_contains (const P2trVector2 *X,\r
-                                     const P2trVector2 *Y,\r
-                                     const P2trVector2 *W)\r
-{\r
-  P2trVector2 WX, WY;\r
-\r
-  p2tr_vector2_sub(X, W, &WX);\r
-  p2tr_vector2_sub(Y, W, &WY);\r
-\r
-  return P2TR_VECTOR2_DOT(&WX, &WY) <= 0;\r
-}\r
-\r
-gboolean\r
-p2tr_math_diametral_lens_contains (const P2trVector2 *X,\r
-                                   const P2trVector2 *Y,\r
-                                   const P2trVector2 *W)\r
-{\r
-  P2trVector2 WX, WY;\r
-\r
-  p2tr_vector2_sub(X, W, &WX);\r
-  p2tr_vector2_sub(Y, W, &WY);\r
-\r
-  return P2TR_VECTOR2_DOT(&WX, &WY)\r
-      <= 0.5 * p2tr_vector2_norm(&WX) * p2tr_vector2_norm(&WY);\r
-}\r
+}
+
+/* The point in triangle test which is implemented below is based on the
+ * algorithm which appears on:
+ *
+ *    http://www.blackpawn.com/texts/pointinpoly/default.html
+ */
+void
+p2tr_math_triangle_barcycentric (const P2trVector2 *A,
+                                 const P2trVector2 *B,
+                                 const P2trVector2 *C,
+                                 const P2trVector2 *P,
+                                 gdouble           *u,
+                                 gdouble           *v)
+{
+  gdouble dot00, dot01, dot02, dot11, dot12, invDenom;
+
+  /* Compute the vectors offsetted so that A is the origin */
+  P2trVector2 v0, v1, v2;
+  p2tr_vector2_sub(C, A, &v0);
+  p2tr_vector2_sub(B, A, &v1);
+  p2tr_vector2_sub(P, A, &v2);
+
+  /* Compute dot products */
+  dot00 = P2TR_VECTOR2_DOT(&v0, &v0);
+  dot01 = P2TR_VECTOR2_DOT(&v0, &v1);
+  dot02 = P2TR_VECTOR2_DOT(&v0, &v2);
+  dot11 = P2TR_VECTOR2_DOT(&v1, &v1);
+  dot12 = P2TR_VECTOR2_DOT(&v1, &v2);
+
+  /* Compute barycentric coordinates */
+  invDenom = 1 / (dot00 * dot11 - dot01 * dot01);
+  *u = (dot11 * dot02 - dot01 * dot12) * invDenom;
+  *v = (dot00 * dot12 - dot01 * dot02) * invDenom;
+}
+
+#define INTRIANGLE_EPSILON 0e-9
+
+P2trInTriangle
+p2tr_math_intriangle (const P2trVector2 *A,
+                      const P2trVector2 *B,
+                      const P2trVector2 *C,
+                      const P2trVector2 *P)
+{
+  gdouble u, v;
+  return p2tr_math_intriangle2 (A, B, C, P, &u, &v);
+}
+
+P2trInTriangle
+p2tr_math_intriangle2 (const P2trVector2 *A,
+                       const P2trVector2 *B,
+                       const P2trVector2 *C,
+                       const P2trVector2 *P,
+                       gdouble           *u,
+                       gdouble           *v)
+{
+  p2tr_math_triangle_barcycentric (A, B, C, P, u, v);
+  
+  /* Check if point is in triangle - i.e. whether (u + v) < 1 and both
+   * u and v are positive */
+  if ((*u >= INTRIANGLE_EPSILON) && (*v >= INTRIANGLE_EPSILON) && (*u + *v < 1 - INTRIANGLE_EPSILON))
+    return P2TR_INTRIANGLE_IN;
+  else if ((*u >= -INTRIANGLE_EPSILON) && (*v >= -INTRIANGLE_EPSILON) && (*u + *v <= 1 + INTRIANGLE_EPSILON))
+    return P2TR_INTRIANGLE_ON;
+  else
+    return P2TR_INTRIANGLE_OUT;
+}
+
+/* The point in triangle circumcircle test, and the 3-point orientation
+ * test, are both based on the work of Jonathan Richard Shewchuk. The
+ * technique used here is described in his paper "Adaptive Precision
+ * Floating-Point Arithmetic and Fast Robust Geometric Predicates"
+ */
+
+#define ORIENT2D_EPSILON 1e-9
+
+P2trOrientation p2tr_math_orient2d (const P2trVector2 *A,
+                                    const P2trVector2 *B,
+                                    const P2trVector2 *C)
+{
+  /* We are trying to compute this determinant:
+   * |Ax Ay 1|
+   * |Bx By 1|
+   * |Cx Cy 1|
+   */
+  gdouble result = p2tr_matrix_det3 (
+      A->x, A->y, 1,
+      B->x, B->y, 1,
+      C->x, C->y, 1
+  );
+
+  if (result > ORIENT2D_EPSILON)
+    return P2TR_ORIENTATION_CCW;
+  else if (result < -ORIENT2D_EPSILON)
+    return P2TR_ORIENTATION_CW;
+  else
+    return P2TR_ORIENTATION_LINEAR;
+}
+
+#define INCIRCLE_EPSILON 1e-9
+
+P2trInCircle
+p2tr_math_incircle (const P2trVector2 *A,
+                    const P2trVector2 *B,
+                    const P2trVector2 *C,
+                    const P2trVector2 *D)
+{
+  /* We are trying to compute this determinant:
+   * |Ax Ay Ax^2+Ay^2 1|
+   * |Bx By Bx^2+By^2 1|
+   * |Cx Cy Cx^2+Cy^2 1|
+   * |Dx Dy Dx^2+Dy^2 1|
+   */
+  gdouble result = p2tr_matrix_det4 (
+      A->x, A->y, P2TR_VECTOR2_LEN_SQ(A), 1,
+      B->x, B->y, P2TR_VECTOR2_LEN_SQ(B), 1,
+      C->x, C->y, P2TR_VECTOR2_LEN_SQ(C), 1,
+      D->x, D->y, P2TR_VECTOR2_LEN_SQ(D), 1
+  );
+
+  if (result > INCIRCLE_EPSILON)
+    return P2TR_INCIRCLE_IN;
+  else if (result < INCIRCLE_EPSILON)
+    return P2TR_INCIRCLE_OUT;
+  else
+    return P2TR_INCIRCLE_ON;
+}
+
+/* The point inside diametral-circle test and the point inside diametral
+ * lens test, are both based on the work of Jonathan Richard Shewchuk.
+ * The techniques used here are partially described in his paper
+ * "Delaunay Refinement Algorithms for Triangular Mesh Generation".
+ *
+ * W is inside the diametral circle (lens) of the line XY if and only if
+ * the angle XWY is larger than 90 (120) degrees. We know how to compute
+ * the cosine of that angle very easily like so:
+ *
+ * cos XWY = (WX * WY) / (|WX| * |WY|)
+ *
+ * Since XWY is larger than 90 (120) degrees, cos XWY <= 0 (-0.5) so:
+ *
+ * Diametral Circle               | Diametral Lens
+ * -------------------------------+-----------------------------------
+ * 0 >= (WX * WY) / (|WX| * |WY|) | - 0.5 >= (WX * WY) / (|WX| * |WY|)
+ * 0 >= WX * WY                   | - 0.5 * |WX| * |WY| >= WX * WY
+ */
+
+gboolean
+p2tr_math_diametral_circle_contains (const P2trVector2 *X,
+                                     const P2trVector2 *Y,
+                                     const P2trVector2 *W)
+{
+  P2trVector2 WX, WY;
+
+  p2tr_vector2_sub(X, W, &WX);
+  p2tr_vector2_sub(Y, W, &WY);
+
+  return P2TR_VECTOR2_DOT(&WX, &WY) <= 0;
+}
+
+gboolean
+p2tr_math_diametral_lens_contains (const P2trVector2 *X,
+                                   const P2trVector2 *Y,
+                                   const P2trVector2 *W)
+{
+  P2trVector2 WX, WY;
+
+  p2tr_vector2_sub(X, W, &WX);
+  p2tr_vector2_sub(Y, W, &WY);
+
+  return P2TR_VECTOR2_DOT(&WX, &WY)
+      <= 0.5 * p2tr_vector2_norm(&WX) * p2tr_vector2_norm(&WY);
+}
index 2109cacb931364fdfc0227df1dcb90c5f34a0ecb..167fe8eea69cb9bf8e7d6daea13c5603ca41cd16 100644 (file)
@@ -1,78 +1,78 @@
-#ifndef __P2TC_REFINE_MATH_H__\r
-#define __P2TC_REFINE_MATH_H__\r
-\r
-#include <glib.h>\r
-#include "vector2.h"\r
+#ifndef __P2TC_REFINE_MATH_H__
+#define __P2TC_REFINE_MATH_H__
+
+#include <glib.h>
+#include "vector2.h"
 #include "circle.h"
-\r
+
 gdouble   p2tr_math_length_sq  (gdouble x1,
                                 gdouble y1,
                                 gdouble x2,
                                 gdouble y2);
-\r
+
 gdouble   p2tr_math_length_sq2 (const P2trVector2 *pt1,
-                                const P2trVector2 *pt2);\r
-\r
-\r
-/**\r
- * Find the circumscribing circle of a triangle defined by the given\r
- * points.\r
- * @param[in] A The first vertex of the triangle\r
- * @param[in] B The second vertex of the triangle\r
- * @param[in] C The third vertex of the triangle\r
- * @param[out] circle The circumscribing circle of the triangle\r
+                                const P2trVector2 *pt2);
+
+
+/**
+ * Find the circumscribing circle of a triangle defined by the given
+ * points.
+ * @param[in] A The first vertex of the triangle
+ * @param[in] B The second vertex of the triangle
+ * @param[in] C The third vertex of the triangle
+ * @param[out] circle The circumscribing circle of the triangle
  */
-void      p2tr_math_triangle_circumcircle (const P2trVector2 *A,\r
-                                           const P2trVector2 *B,\r
-                                           const P2trVector2 *C,\r
-                                           P2trCircle    *circle);\r
-\r
-typedef enum\r
-{\r
-  P2TR_INTRIANGLE_OUT = -1,\r
-  P2TR_INTRIANGLE_ON = 0,\r
-  P2TR_INTRIANGLE_IN = 1\r
+void      p2tr_math_triangle_circumcircle (const P2trVector2 *A,
+                                           const P2trVector2 *B,
+                                           const P2trVector2 *C,
+                                           P2trCircle    *circle);
+
+typedef enum
+{
+  P2TR_INTRIANGLE_OUT = -1,
+  P2TR_INTRIANGLE_ON = 0,
+  P2TR_INTRIANGLE_IN = 1
 } P2trInTriangle;
 
-/**\r
- * Return the barycentric coordinates of a point inside a triangle. This\r
- * means that the computation returns @ref u and @ref v so that the\r
- * following equation is satisfied:\r
- * {{{ AP = u * AB + v * AC }}}\r
- *\r
- * @param[in] A The first point of the triangle\r
- * @param[in] B The second point of the triangle\r
- * @param[in] C The third point of the triangle\r
- * @param[in] P The point whose barycentric coordinates should be\r
- *              computed\r
- * @param[out] u The first barycentric coordinate\r
- * @param[out] v The second barycentric coordinate\r
- */\r
-void p2tr_math_triangle_barcycentric (const P2trVector2 *A,\r
-                                      const P2trVector2 *B,\r
-                                      const P2trVector2 *C,\r
-                                      const P2trVector2 *P,\r
-                                      gdouble           *u,\r
-                                      gdouble           *v);\r
-\r
-P2trInTriangle p2tr_math_intriangle (const P2trVector2 *A,\r
-                                     const P2trVector2 *B,\r
-                                     const P2trVector2 *C,\r
-                                     const P2trVector2 *P);\r
-\r
-P2trInTriangle p2tr_math_intriangle2 (const P2trVector2 *A,\r
-                                      const P2trVector2 *B,\r
-                                      const P2trVector2 *C,\r
-                                      const P2trVector2 *P,\r
-                                      gdouble           *u,\r
-                                      gdouble           *v);\r
+/**
+ * Return the barycentric coordinates of a point inside a triangle. This
+ * means that the computation returns @ref u and @ref v so that the
+ * following equation is satisfied:
+ * {{{ AP = u * AB + v * AC }}}
+ *
+ * @param[in] A The first point of the triangle
+ * @param[in] B The second point of the triangle
+ * @param[in] C The third point of the triangle
+ * @param[in] P The point whose barycentric coordinates should be
+ *              computed
+ * @param[out] u The first barycentric coordinate
+ * @param[out] v The second barycentric coordinate
+ */
+void p2tr_math_triangle_barcycentric (const P2trVector2 *A,
+                                      const P2trVector2 *B,
+                                      const P2trVector2 *C,
+                                      const P2trVector2 *P,
+                                      gdouble           *u,
+                                      gdouble           *v);
+
+P2trInTriangle p2tr_math_intriangle (const P2trVector2 *A,
+                                     const P2trVector2 *B,
+                                     const P2trVector2 *C,
+                                     const P2trVector2 *P);
 
-typedef enum\r
-{\r
-  P2TR_ORIENTATION_CW = -1,\r
-  P2TR_ORIENTATION_LINEAR = 0,\r
-  P2TR_ORIENTATION_CCW = 1\r
-} P2trOrientation;\r
+P2trInTriangle p2tr_math_intriangle2 (const P2trVector2 *A,
+                                      const P2trVector2 *B,
+                                      const P2trVector2 *C,
+                                      const P2trVector2 *P,
+                                      gdouble           *u,
+                                      gdouble           *v);
+
+typedef enum
+{
+  P2TR_ORIENTATION_CW = -1,
+  P2TR_ORIENTATION_LINEAR = 0,
+  P2TR_ORIENTATION_CCW = 1
+} P2trOrientation;
 
 P2trOrientation p2tr_math_orient2d (const P2trVector2 *A,
                                     const P2trVector2 *B,
@@ -85,16 +85,16 @@ typedef enum
   P2TR_INCIRCLE_OUT
 } P2trInCircle;
 
-P2trInCircle p2tr_math_incircle (const P2trVector2 *A,\r
-                                 const P2trVector2 *B,\r
-                                 const P2trVector2 *C,\r
-                                 const P2trVector2 *D);\r
-\r
-gboolean  p2tr_math_diametral_circle_contains (const P2trVector2 *X,\r
-                                               const P2trVector2 *Y,\r
-                                               const P2trVector2 *W);\r
-\r
-gboolean  p2tr_math_diametral_lens_contains   (const P2trVector2 *X,\r
-                                               const P2trVector2 *Y,\r
-                                               const P2trVector2 *W);\r
+P2trInCircle p2tr_math_incircle (const P2trVector2 *A,
+                                 const P2trVector2 *B,
+                                 const P2trVector2 *C,
+                                 const P2trVector2 *D);
+
+gboolean  p2tr_math_diametral_circle_contains (const P2trVector2 *X,
+                                               const P2trVector2 *Y,
+                                               const P2trVector2 *W);
+
+gboolean  p2tr_math_diametral_lens_contains   (const P2trVector2 *X,
+                                               const P2trVector2 *Y,
+                                               const P2trVector2 *W);
 #endif
\ No newline at end of file
index 45a6b7f239aae6e2fbc3aaa3b9e99125b669b040..2b3ea0f631201cc50ff05f42eb46c83dc05c0617 100644 (file)
@@ -1,52 +1,52 @@
-#include <math.h>\r
-#include <glib.h>\r
-#include "vector2.h"\r
-\r
-gdouble\r
-p2tr_vector2_dot (const P2trVector2 *a,\r
-                  const P2trVector2 *b)\r
-{\r
-  return P2TR_VECTOR2_DOT (a, b);\r
-}\r
-\r
-gboolean\r
-p2tr_vector2_is_same (const P2trVector2 *a,\r
-                      const P2trVector2 *b)\r
-{\r
-  if (a == NULL || b == NULL)\r
-    return ! ((a == NULL) ^ (b == NULL));\r
-  else\r
-    return a->x == b->x && a->y == b->y;\r
-}\r
-\r
-void\r
-p2tr_vector2_sub (const P2trVector2 *a,\r
-                  const P2trVector2 *b,\r
-                  P2trVector2       *dest)\r
-{\r
-  dest->x = a->x - b->x;\r
-  dest->y = a->y - b->y;\r
-}\r
-\r
-void\r
-p2tr_vector2_center (const P2trVector2 *a,\r
-                     const P2trVector2 *b,\r
-                     P2trVector2       *dest)\r
-{\r
-  dest->x = (a->x + b->x) * 0.5;\r
-  dest->y = (a->y + b->y) * 0.5;\r
-}\r
-\r
-gdouble\r
-p2tr_vector2_norm (const P2trVector2 *v)\r
-{\r
-  return sqrt (P2TR_VECTOR2_LEN_SQ (v));\r
-}\r
-\r
-void\r
-p2tr_vector2_copy (P2trVector2       *dest,\r
-                   const P2trVector2 *src)\r
-{\r
-  dest->x = src->x;\r
-  dest->y = src->y;\r
-}\r
+#include <math.h>
+#include <glib.h>
+#include "vector2.h"
+
+gdouble
+p2tr_vector2_dot (const P2trVector2 *a,
+                  const P2trVector2 *b)
+{
+  return P2TR_VECTOR2_DOT (a, b);
+}
+
+gboolean
+p2tr_vector2_is_same (const P2trVector2 *a,
+                      const P2trVector2 *b)
+{
+  if (a == NULL || b == NULL)
+    return ! ((a == NULL) ^ (b == NULL));
+  else
+    return a->x == b->x && a->y == b->y;
+}
+
+void
+p2tr_vector2_sub (const P2trVector2 *a,
+                  const P2trVector2 *b,
+                  P2trVector2       *dest)
+{
+  dest->x = a->x - b->x;
+  dest->y = a->y - b->y;
+}
+
+void
+p2tr_vector2_center (const P2trVector2 *a,
+                     const P2trVector2 *b,
+                     P2trVector2       *dest)
+{
+  dest->x = (a->x + b->x) * 0.5;
+  dest->y = (a->y + b->y) * 0.5;
+}
+
+gdouble
+p2tr_vector2_norm (const P2trVector2 *v)
+{
+  return sqrt (P2TR_VECTOR2_LEN_SQ (v));
+}
+
+void
+p2tr_vector2_copy (P2trVector2       *dest,
+                   const P2trVector2 *src)
+{
+  dest->x = src->x;
+  dest->y = src->y;
+}
index 08386ad4679e417c3d82f7096f17f04bb7cf9153..e202b3dec3c3dabb4237588f6bde993cca4bdc47 100644 (file)
@@ -1,69 +1,69 @@
-#ifndef __P2TR_REFINE_VECTOR2_H__\r
-#define __P2TR_REFINE_VECTOR2_H__\r
-\r
-#include <glib.h>\r
-\r
-/**\r
- * \struct P2trVector2\r
- * A struct for representing a vector with 2 coordinates (a point in 2D)\r
- */\r
-typedef struct {\r
-  /** The first coordinate of the vector */\r
-  gdouble x;\r
-  /** The second coordinate of the vector */\r
-  gdouble y;\r
-} P2trVector2;\r
-\r
-#define P2TR_VECTOR2_LEN_SQ2(X, Y)              \\r
-    ((X) * (X) + (Y) * (Y))\r
-\r
-#define P2TR_VECTOR2_LEN_SQ(V)                  \\r
-    (P2TR_VECTOR2_LEN_SQ2((V)->x, (V)->y))\r
-\r
-#define P2TR_VECTOR2_DOT(V1,V2)                 \\r
-    ((V1)->x * (V2)->x + (V1)->y * (V2)->y)\r
-\r
-#define P2TR_VECTOR2_DISTANCE_SQ2(X1,Y1,X2,Y2)  \\r
-    (P2TR_VECTOR2_LEN_SQ2((X1) - (X2), (Y1) - (Y2)))\r
-\r
-#define P2TR_VECTOR2_DISTANCE_SQ(V1,V2)         \\r
-    (P2TR_VECTOR2_DISTANCE_SQ2((V1)->x, (V1)->y, (V2)->x, (V2)->y))\r
-\r
-/** Compute the dot product of two vectors */\r
-gdouble       p2tr_vector2_dot       (const P2trVector2 *a, const P2trVector2 *b);\r
-\r
-/** Check if all the coordinates of the two vectors are the same */\r
-gboolean      p2tr_vector2_is_same   (const P2trVector2 *a, const P2trVector2 *b);\r
-\r
-/**\r
- * Compute the difference of two vectors\r
- * @param[in] a The vector to subtract from\r
- * @param[in] b The vector to be subtracted\r
- * @param[out] dest The vector in which the result should be stored\r
- */\r
-void          p2tr_vector2_sub       (const P2trVector2 *a, const P2trVector2 *b, P2trVector2 *dest);\r
-\r
-/**\r
- * Compute the center point of the edge defined between two points\r
- * @param[in] a The first side of the edge\r
- * @param[in] b The second side of the edge\r
- * @param[out] dest The vector in which the result should be stored\r
- */\r
-void          p2tr_vector2_center    (const P2trVector2 *a, const P2trVector2 *b, P2trVector2 *dest);\r
-\r
-/**\r
- * Compute the norm of a vector (the length of the line from the origin\r
- * to the 2D point it represents)\r
- * @param[in] v The vector whose norm should be computed\r
- * @return The norm of the vector\r
- */\r
-gdouble       p2tr_vector2_norm      (const P2trVector2 *v);\r
-\r
-/**\r
- * Copy a vector\r
- * @param[out] dest The destination of the copy operation\r
- * @param[in] src The vector to copy\r
- */\r
-void          p2tr_vector2_copy      (P2trVector2 *dest, const P2trVector2 *src);\r
-\r
+#ifndef __P2TR_REFINE_VECTOR2_H__
+#define __P2TR_REFINE_VECTOR2_H__
+
+#include <glib.h>
+
+/**
+ * \struct P2trVector2
+ * A struct for representing a vector with 2 coordinates (a point in 2D)
+ */
+typedef struct {
+  /** The first coordinate of the vector */
+  gdouble x;
+  /** The second coordinate of the vector */
+  gdouble y;
+} P2trVector2;
+
+#define P2TR_VECTOR2_LEN_SQ2(X, Y)              \
+    ((X) * (X) + (Y) * (Y))
+
+#define P2TR_VECTOR2_LEN_SQ(V)                  \
+    (P2TR_VECTOR2_LEN_SQ2((V)->x, (V)->y))
+
+#define P2TR_VECTOR2_DOT(V1,V2)                 \
+    ((V1)->x * (V2)->x + (V1)->y * (V2)->y)
+
+#define P2TR_VECTOR2_DISTANCE_SQ2(X1,Y1,X2,Y2)  \
+    (P2TR_VECTOR2_LEN_SQ2((X1) - (X2), (Y1) - (Y2)))
+
+#define P2TR_VECTOR2_DISTANCE_SQ(V1,V2)         \
+    (P2TR_VECTOR2_DISTANCE_SQ2((V1)->x, (V1)->y, (V2)->x, (V2)->y))
+
+/** Compute the dot product of two vectors */
+gdouble       p2tr_vector2_dot       (const P2trVector2 *a, const P2trVector2 *b);
+
+/** Check if all the coordinates of the two vectors are the same */
+gboolean      p2tr_vector2_is_same   (const P2trVector2 *a, const P2trVector2 *b);
+
+/**
+ * Compute the difference of two vectors
+ * @param[in] a The vector to subtract from
+ * @param[in] b The vector to be subtracted
+ * @param[out] dest The vector in which the result should be stored
+ */
+void          p2tr_vector2_sub       (const P2trVector2 *a, const P2trVector2 *b, P2trVector2 *dest);
+
+/**
+ * Compute the center point of the edge defined between two points
+ * @param[in] a The first side of the edge
+ * @param[in] b The second side of the edge
+ * @param[out] dest The vector in which the result should be stored
+ */
+void          p2tr_vector2_center    (const P2trVector2 *a, const P2trVector2 *b, P2trVector2 *dest);
+
+/**
+ * Compute the norm of a vector (the length of the line from the origin
+ * to the 2D point it represents)
+ * @param[in] v The vector whose norm should be computed
+ * @return The norm of the vector
+ */
+gdouble       p2tr_vector2_norm      (const P2trVector2 *v);
+
+/**
+ * Copy a vector
+ * @param[out] dest The destination of the copy operation
+ * @param[in] src The vector to copy
+ */
+void          p2tr_vector2_copy      (P2trVector2 *dest, const P2trVector2 *src);
+
 #endif
\ No newline at end of file
index 0431c902641f1e1af3ddc9a6485f7e4f0ec215e2..659f7fd3cec04e380b24e5dff6d1d62b4f4974ee 100644 (file)
@@ -33,8 +33,8 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef __P2TC_RENDER_SVG_PLOT_H__\r
-#define __P2TC_RENDER_SVG_PLOT_H__\r
+#ifndef __P2TC_RENDER_SVG_PLOT_H__
+#define __P2TC_RENDER_SVG_PLOT_H__
 
 #include <refine/refine.h>