static gboolean p2tr_cdt_has_empty_circum_circle (P2trCDT *self, P2trTriangle *tri) { P2trCircle circum; P2trPoint *p; P2trHashSetIter iter; p2tr_triangle_get_circum_circle (tri, &circum); p2tr_hash_set_iter_init (&iter, self->mesh->points); while (p2tr_hash_set_iter_next (&iter, (gpointer*)&p)) { /** TODO: FIXME - is a point on a constrained edge really not a * problem?! */ if (p2tr_point_has_constrained_edge (p) /* The points of a triangle can't violate its own empty * circumcircle property */ || p == tri->edges[0]->end || p == tri->edges[1]->end || p == tri->edges[2]->end) continue; if (! p2tr_circle_test_point_outside(&circum, &p->c) && p2tr_cdt_visible_from_tri (self, tri, &p->c)) return FALSE; } return TRUE; }
void p2tr_cdt_validate_edges (P2trCDT *self) { P2trHashSetIter iter; P2trEdge *e; p2tr_hash_set_iter_init (&iter, self->mesh->edges); while (p2tr_hash_set_iter_next (&iter, (gpointer*)&e)) { if (! e->constrained && e->tri == NULL) p2tr_exception_geometric ("Found a non constrained edge without a triangle"); if (e->tri != NULL) { gboolean found = FALSE; gint i = 0; for (i = 0; i < 3; i++) if (e->tri->edges[i] == e) { found = TRUE; break; } if (! found) p2tr_exception_geometric ("An edge has a triangle to which it does not belong!"); } } }
void p2tr_cdt_validate_unused (P2trCDT* self) { P2trEdge *ed; P2trTriangle *tri; P2trHashSetIter iter; p2tr_hash_set_iter_init (&iter, self->mesh->edges); while (p2tr_hash_set_iter_next (&iter, (gpointer*)&ed)) { g_assert (ed->mirror != NULL); g_assert (! p2tr_edge_is_removed (ed)); } p2tr_hash_set_iter_init (&iter, self->mesh->triangles); while (p2tr_hash_set_iter_next (&iter, (gpointer*)&tri)) g_assert (! p2tr_triangle_is_removed (tri)); }
void p2tr_cdt_validate_cdt (P2trCDT *self) { P2trHashSetIter iter; P2trTriangle *tri; p2tr_hash_set_iter_init (&iter, self->mesh->triangles); while (p2tr_hash_set_iter_next (&iter, (gpointer*)&tri)) if (! p2tr_cdt_has_empty_circum_circle(self, tri)) p2tr_exception_geometric ("Not a CDT!"); }
void p2tr_plot_svg (P2trMesh *T, FILE *outfile) { P2trHashSetIter siter; P2trTriangle *tr; g_debug ("Starting to write SVG output\n"); p2tr_plot_svg_plot_init (outfile); p2tr_hash_set_iter_init (&siter, T->triangles); while (p2tr_hash_set_iter_next (&siter, (gpointer*)&tr)) p2tr_plot_svg_plot_triangle (tr, "black", outfile); p2tr_plot_svg_plot_end (outfile); g_debug ("Finished writing SVG output\n"); }
GeglScMeshSampling* gegl_sc_mesh_sampling_compute (GeglScOutline *outline, P2trMesh *mesh) { GHashTable *pt2sample = g_hash_table_new (g_direct_hash, g_direct_equal); P2trPoint *pt = NULL; P2trHashSetIter iter; p2tr_hash_set_iter_init (&iter, mesh->points); while (p2tr_hash_set_iter_next (&iter, (gpointer*) &pt)) { GeglScSampleList *sl; if (p2tr_point_is_fully_in_domain (pt)) sl = gegl_sc_sample_list_compute (outline, pt->c.x, pt->c.y); else sl = gegl_sc_sample_list_direct (); g_hash_table_insert (pt2sample, pt, sl); } return pt2sample; }
/* Whenever a new point was inserted, it may disturb triangles * that are extremly skinny and therefor their circumscribing * circles are very large and will contain that point, even though they * may be very far from that point. * We have no choice but to check these and fix them if necessary */ static void p2tr_cdt_on_new_point (P2trCDT *self, P2trPoint *pt) { GList *bad_tris = NULL; P2trTriangle *tri; P2trHashSetIter iter; p2tr_hash_set_iter_init (&iter, self->mesh->triangles); while (p2tr_hash_set_iter_next (&iter, (gpointer*)&tri)) { if (p2tr_triangle_circumcircle_contains_point (tri, &pt->c) != P2TR_INCIRCLE_OUT) { bad_tris = g_list_prepend (bad_tris, tri); p2tr_triangle_ref (tri); } } p2tr_cdt_flip_fix (self, bad_tris); g_list_free (bad_tris); }