Exemple #1
0
/**
 * 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;
}
Exemple #2
0
/** 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);
}
Exemple #3
0
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);
}