Ejemplo n.º 1
0
Archivo: optimize.c Proyecto: bert/gts
static gdouble edge_swap_cost (GtsEdge * e)
{
    GSList * i;
    GtsTriangle * t1 = NULL, * t2 = NULL;
    GtsVertex * v1, * v2, * v3, * v4;
    GtsEdge * e1, * e2, * e3, * e4;
    gdouble ab, aa;

    i = e->triangles;
    while (i) {
        if (GTS_IS_FACE (i->data)) {
            if (!t1) t1 = i->data;
            else if (!t2) t2 = i->data;
            else return G_MAXDOUBLE;
        }
        i = i->next;
    }
    if (!t1 || !t2)
        return G_MAXDOUBLE;

    gts_triangle_vertices_edges (t1, e, &v1, &v2, &v3, &e, &e3, &e4);
    gts_triangle_vertices_edges (t2, e, &v2, &v1, &v4, &e, &e1, &e2);

    ab = triangles_angle (GTS_POINT (v1), GTS_POINT (v2),
                          GTS_POINT (v3), GTS_POINT (v4));
    aa = triangles_angle (GTS_POINT (v3), GTS_POINT (v4),
                          GTS_POINT (v2), GTS_POINT (v1));
    return fabs (ab) - fabs (aa);
}
Ejemplo n.º 2
0
Archivo: edge.c Proyecto: MicBosi/GTS
/**
 * gts_edge_swap:
 * @e: a #GtsEdge.
 * @s: a #GtsSurface.
 *
 * Performs an "edge swap" on the two triangles sharing @e and
 * belonging to @s.
 */
void gts_edge_swap (GtsEdge * e, GtsSurface * s)
{
    GtsTriangle * t1 = NULL, * t2 = NULL, * t;
    GtsFace * f;
    GSList * i;
    GtsVertex * v1, * v2, * v3, * v4, * v5, * v6;
    GtsEdge * e1, * e2, * e3, * e4;
    GtsSegment * v3v6;

    g_return_if_fail (e != NULL);
    g_return_if_fail (s != NULL);

    i = e->triangles;
    while (i) {
        if (GTS_IS_FACE (i->data) && gts_face_has_parent_surface (i->data, s)) {
            if (!t1)
                t1 = i->data;
            else if (!t2)
                t2 = i->data;
            else
                g_return_if_fail (gts_edge_face_number (e, s) == 2);
        }
        i = i->next;
    }
    g_assert (t1 && t2);

    gts_triangle_vertices_edges (t1, e, &v1, &v2, &v3, &e, &e1, &e2);
    gts_triangle_vertices_edges (t2, e, &v4, &v5, &v6, &e, &e3, &e4);
    g_assert (v2 == v4 && v1 == v5);

    v3v6 = gts_vertices_are_connected (v3, v6);
    if (!GTS_IS_EDGE (v3v6))
        v3v6 = GTS_SEGMENT (gts_edge_new (s->edge_class, v3, v6));
    f = gts_face_new (s->face_class, e1, GTS_EDGE (v3v6), e4);
    if ((t = gts_triangle_is_duplicate (GTS_TRIANGLE (f))) &&
            GTS_IS_FACE (t)) {
        gts_object_destroy (GTS_OBJECT (f));
        f = GTS_FACE (t);
    }
    gts_surface_add_face (s, f);

    f = gts_face_new (s->face_class, GTS_EDGE (v3v6), e2, e3);
    if ((t = gts_triangle_is_duplicate (GTS_TRIANGLE (f))) &&
            GTS_IS_FACE (t)) {
        gts_object_destroy (GTS_OBJECT (f));
        f = GTS_FACE (t);
    }
    gts_surface_add_face (s, f);

    gts_surface_remove_face (s, GTS_FACE (t1));
    gts_surface_remove_face (s, GTS_FACE (t2));
}
Ejemplo n.º 3
0
/**
 * gts_triangle_is_stabbed:
 * @t: a #GtsTriangle.
 * @p: a #GtsPoint.
 * @orientation: a pointer or %NULL.
 *
 * Returns: one of the vertices of @t, one of the edges of @t or @t if
 * any of these are stabbed by the ray starting at @p (included) and
 * ending at (@p->x, @p->y, +infty), %NULL otherwise. If the ray is
 * contained in the plane of the triangle %NULL is also returned. If
 * @orientation is not %NULL, it is set to the value of the
 * orientation of @p relative to @t (as given by
 * gts_point_orientation_3d()).
 */
GtsObject * gts_triangle_is_stabbed (GtsTriangle * t,
                                     GtsPoint * p,
                                     gdouble * orientation)
{
    GtsVertex * v1, * v2, * v3, * inverted = NULL;
    GtsEdge * e1, * e2, * e3, * tmp;
    gdouble o, o1, o2, o3;

    g_return_val_if_fail (t != NULL, NULL);
    g_return_val_if_fail (p != NULL, NULL);

    gts_triangle_vertices_edges (t, NULL, &v1, &v2, &v3, &e1, &e2, &e3);
    o = gts_point_orientation (GTS_POINT (v1), GTS_POINT (v2), GTS_POINT (v3));
    if (o == 0.)
        return NULL;
    if (o < 0.) {
        inverted = v1;
        v1 = v2;
        v2 = inverted;
        tmp = e2;
        e2 = e3;
        e3 = tmp;
    }
    o = gts_point_orientation_3d (GTS_POINT (v1),
                                  GTS_POINT (v2),
                                  GTS_POINT (v3),
                                  p);
    if (o < 0.)
        return NULL;
    o1 = gts_point_orientation (GTS_POINT (v1), GTS_POINT (v2), p);
    if (o1 < 0.)
        return NULL;
    o2 = gts_point_orientation (GTS_POINT (v2), GTS_POINT (v3), p);
    if (o2 < 0.)
        return NULL;
    o3 = gts_point_orientation (GTS_POINT (v3), GTS_POINT (v1), p);
    if (o3 < 0.)
        return NULL;
    if (orientation) *orientation = inverted ? -o : o;
    if (o1 == 0.) {
        if (o2 == 0.)
            return GTS_OBJECT (v2);
        if (o3 == 0.)
            return GTS_OBJECT (v1);
        return GTS_OBJECT (e1);
    }
    if (o2 == 0.) {
        if (o3 == 0.)
            return GTS_OBJECT (v3);
        return GTS_OBJECT (e2);
    }
    if (o3 == 0.)
        return GTS_OBJECT (e3);
    return GTS_OBJECT (t);
}
Ejemplo n.º 4
0
static gboolean triangle_is_hole (GtsTriangle * t)
{
  GtsEdge * e1, * e2, * e3;
  GtsVertex * v1, * v2, * v3;

  gts_triangle_vertices_edges (t, NULL, &v1, &v2, &v3, &e1, &e2, &e3);

  if ((GTS_IS_CONSTRAINT (e1) && GTS_SEGMENT (e1)->v2 != v1) ||
      (GTS_IS_CONSTRAINT (e2) && GTS_SEGMENT (e2)->v2 != v2) ||
      (GTS_IS_CONSTRAINT (e3) && GTS_SEGMENT (e3)->v2 != v3))
    return TRUE;
  return FALSE;
}
Ejemplo n.º 5
0
Archivo: optimize.c Proyecto: bert/gts
static void edge_swap (GtsEdge * e, GtsSurface * s, GtsEHeap * heap)
{
    GSList * i;
    GtsTriangle * t1 = NULL, * t2 = NULL;
    GtsVertex * v1, * v2, * v3, * v4;
    GtsEdge * e1, * e2, * e3, * e4;

    i = e->triangles;
    while (i) {
        if (GTS_IS_FACE (i->data)) {
            if (!t1) t1 = i->data;
            else if (!t2) t2 = i->data;
            else g_assert_not_reached ();
        }
        i = i->next;
    }
    g_assert (t1 && t2);

    gts_triangle_vertices_edges (t1, e, &v1, &v2, &v3, &e, &e3, &e4);
    gts_triangle_vertices_edges (t2, e, &v2, &v1, &v4, &e, &e1, &e2);

    gts_object_destroy (GTS_OBJECT (e));
    e = gts_edge_new (s->edge_class, v3, v4);
    gts_surface_add_face (s, gts_face_new (s->face_class, e, e4, e1));
    gts_surface_add_face (s, gts_face_new (s->face_class, e, e2, e3));

    HEAP_INSERT_EDGE (heap, e);
    HEAP_REMOVE_EDGE (heap, e1);
    HEAP_INSERT_EDGE (heap, e1);
    HEAP_REMOVE_EDGE (heap, e2);
    HEAP_INSERT_EDGE (heap, e2);
    HEAP_REMOVE_EDGE (heap, e3);
    HEAP_INSERT_EDGE (heap, e3);
    HEAP_REMOVE_EDGE (heap, e4);
    HEAP_INSERT_EDGE (heap, e4);
}
Ejemplo n.º 6
0
static void gts_constraint_split (GtsConstraint * c, 
				  GtsSurface * s,
				  GtsFifo * fifo)
{
  GSList * i;
  GtsVertex * v1, * v2;
  GtsEdge * e;

  g_return_if_fail (c != NULL);
  g_return_if_fail (s != NULL);

  v1 = GTS_SEGMENT (c)->v1;
  v2 = GTS_SEGMENT (c)->v2;
  e = GTS_EDGE (c);

  i = e->triangles;
  while (i) {
    GtsFace * f = i->data;
    if (GTS_IS_FACE (f) && gts_face_has_parent_surface (f, s)) {
      GtsVertex * v = gts_triangle_vertex_opposite (GTS_TRIANGLE (f), e);
      if (gts_point_orientation (GTS_POINT (v1), 
				 GTS_POINT (v2), 
				 GTS_POINT (v)) == 0.) {
	GSList * j = e->triangles;
	GtsFace * f1 = NULL;
	GtsEdge * e1, * e2;

	/* replaces edges with constraints */
	gts_triangle_vertices_edges (GTS_TRIANGLE (f), e,
				     &v1, &v2, &v, &e, &e1, &e2);
	if (!GTS_IS_CONSTRAINT (e1)) {
	  GtsEdge * ne1 = 
	    gts_edge_new (GTS_EDGE_CLASS (GTS_OBJECT (c)->klass), v2, v);
	  gts_edge_replace (e1, ne1);
	  gts_object_destroy (GTS_OBJECT (e1));
	  e1 = ne1;
	  if (fifo) gts_fifo_push (fifo, e1);
	}
	if (!GTS_IS_CONSTRAINT (e2)) {
	  GtsEdge * ne2 = 
	    gts_edge_new (GTS_EDGE_CLASS (GTS_OBJECT (c)->klass), v, v1);
	  gts_edge_replace (e2, ne2);
	  gts_object_destroy (GTS_OBJECT (e2));
	  e2 = ne2;
	  if (fifo) gts_fifo_push (fifo, e2);
	}

	/* look for face opposite */
	while (j && !f1) {
	  if (GTS_IS_FACE (j->data) && 
	      gts_face_has_parent_surface (j->data, s))
	    f1 = j->data;
	  j = j->next;
	}
	if (f1) { /* c is not a boundary of s */
	  GtsEdge * e3, * e4, * e5;
	  GtsVertex * v3;
	  gts_triangle_vertices_edges (GTS_TRIANGLE (f1), e,
				       &v1, &v2, &v3, &e, &e3, &e4);
	  e5 = gts_edge_new (s->edge_class, v, v3);
	  gts_surface_add_face (s, gts_face_new (s->face_class, e5, e2, e3));
	  gts_surface_add_face (s, gts_face_new (s->face_class, e5, e4, e1));
	  gts_object_destroy (GTS_OBJECT (f1));
	}
	gts_object_destroy (GTS_OBJECT (f));
	return;
      }
    }
    i = i->next;
  }
}