示例#1
0
/**
 * Try to flip a given edge, If successfull, return the new edge (reffed!),
 * otherwise return NULL
 */
P2trEdge*
p2tr_cdt_try_flip (P2trCDT   *self,
                   P2trEdge  *to_flip)
{
  /*    C
   *  / | \
   * B-----A    to_flip: A->B
   *  \ | /     to_flip.Tri: ABC
   *    D
   */
  P2trPoint *A, *B, *C, *D;
  P2trEdge *AB, *CA, *AD, *DB, *BC, *DC;

  g_assert (! to_flip->constrained && ! to_flip->delaunay);

  A = P2TR_EDGE_START (to_flip);
  B = to_flip->end;
  C = p2tr_triangle_get_opposite_point (to_flip->tri, to_flip, FALSE);
  D = p2tr_triangle_get_opposite_point (to_flip->mirror->tri, to_flip->mirror, FALSE);

  AB = to_flip;

  /* Check if the quadriliteral ADBC is concave (because if it is, we
   * can't flip the edge) */
  if (p2tr_triangle_circumcircle_contains_point (AB->tri, &D->c) != P2TR_INCIRCLE_IN)
    return NULL;

  CA = p2tr_point_get_edge_to (C, A, FALSE);
  AD = p2tr_point_get_edge_to (A, D, FALSE);
  DB = p2tr_point_get_edge_to (D, B, FALSE);
  BC = p2tr_point_get_edge_to (B, C, FALSE);

  p2tr_edge_remove (AB);

  DC = p2tr_mesh_new_edge (self->mesh, D, C, FALSE);

  p2tr_triangle_unref (p2tr_mesh_new_triangle (self->mesh,
      CA, AD, DC));

  p2tr_triangle_unref (p2tr_mesh_new_triangle (self->mesh,
      DB, BC, DC->mirror));

  return DC;
}
示例#2
0
/* 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);
}