/** * Return the edge cluster of the specified edge from the specified end * point. THE EDGES IN THE CLUSTER MUST BE UNREFFED! * @param[in] P The point which is shared between all edges of the cluster * @param[in] E The edge whose cluster should be returned * @return The cluster of @ref E from the point @ref P */ P2trCluster* p2tr_cluster_get_for (P2trPoint *P, P2trEdge *E) { P2trCluster *cluster = g_slice_new (P2trCluster); gdouble temp_angle; P2trEdge *current, *next; cluster->min_angle = G_MAXDOUBLE; g_queue_init (&cluster->edges); if (P == E->end) P = P2TR_EDGE_START (E); else if (P != P2TR_EDGE_START (E)) p2tr_exception_programmatic ("Unexpected point for the edge!"); g_queue_push_head (&cluster->edges, E); current = E; next = p2tr_point_edge_cw (P, current); while (next != g_queue_peek_head (&cluster->edges) && (temp_angle = p2tr_edge_angle_between (current->mirror, next)) <= P2TR_CLUSTER_LIMIT_ANGLE && p2tr_cluster_cw_tri_between_is_in_domain (current, next)) { g_queue_push_tail (&cluster->edges, next); p2tr_edge_ref (next); current = next; next = p2tr_point_edge_cw (P, current); cluster->min_angle = MIN (cluster->min_angle, temp_angle); } current = E; next = p2tr_point_edge_ccw(P, current); while (next != g_queue_peek_tail (&cluster->edges) && (temp_angle = p2tr_edge_angle_between (current->mirror, next)) <= P2TR_CLUSTER_LIMIT_ANGLE && p2tr_cluster_cw_tri_between_is_in_domain (next, current)) { g_queue_push_head (&cluster->edges, next); p2tr_edge_ref (next); current = next; next = p2tr_point_edge_ccw (P, current); cluster->min_angle = MIN(cluster->min_angle, temp_angle); } return cluster; }
/** Insert a point into a triangle. This function assumes the point is * inside the triangle - not on one of its edges and not outside of it. */ void p2tr_cdt_insert_point_into_triangle (P2trCDT *self, P2trPoint *P, P2trTriangle *tri) { P2trVEdgeSet *flip_candidates = p2tr_vedge_set_new (); P2trPoint *A = tri->edges[0]->end; P2trPoint *B = tri->edges[1]->end; P2trPoint *C = tri->edges[2]->end; P2trEdge *CA = tri->edges[0]; P2trEdge *AB = tri->edges[1]; P2trEdge *BC = tri->edges[2]; P2trEdge *AP, *BP, *CP; p2tr_triangle_remove (tri); AP = p2tr_mesh_new_edge (self->mesh, A, P, FALSE); BP = p2tr_mesh_new_edge (self->mesh, B, P, FALSE); CP = p2tr_mesh_new_edge (self->mesh, C, P, FALSE); p2tr_triangle_unref (p2tr_mesh_new_triangle (self->mesh, AB, BP, AP->mirror)); p2tr_triangle_unref (p2tr_mesh_new_triangle (self->mesh, BC, CP, BP->mirror)); p2tr_triangle_unref (p2tr_mesh_new_triangle (self->mesh, CA, AP, CP->mirror)); p2tr_vedge_set_add (flip_candidates, CP); p2tr_vedge_set_add (flip_candidates, AP); p2tr_vedge_set_add (flip_candidates, BP); p2tr_vedge_set_add (flip_candidates, p2tr_edge_ref (CA)); p2tr_vedge_set_add (flip_candidates, p2tr_edge_ref (AB)); p2tr_vedge_set_add (flip_candidates, p2tr_edge_ref (BC)); /* Flip fix the newly created triangles to preserve the the * constrained delaunay property. The flip-fix function will unref the * new triangles for us! */ p2tr_cdt_flip_fix (self, flip_candidates); p2tr_vedge_set_free (flip_candidates); }
void _p2tr_point_insert_edge (P2trPoint *self, P2trEdge *e) { GList *iter = self->outgoing_edges; /* Remember: Edges are sorted in ASCENDING angle! */ while (iter != NULL && ((P2trEdge*)iter->data)->angle < e->angle) iter = iter->next; self->outgoing_edges = g_list_insert_before (self->outgoing_edges, iter, e); p2tr_edge_ref (e); }