コード例 #1
0
ファイル: triangle.c プロジェクト: finetjul/gts
/**
 * 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);
}
コード例 #2
0
ファイル: triangle.c プロジェクト: finetjul/gts
/**
 * gts_triangle_orientation:
 * @t: a #GtsTriangle.
 *
 * Checks for the orientation of the plane (x,y) projection of a
 * triangle. See gts_point_orientation() for details. This function
 * is geometrically robust.
 *
 * Returns: a number depending on the orientation of the vertices of @t.
 */
gdouble gts_triangle_orientation (GtsTriangle * t)
{
    GtsVertex * v1, * v2 = NULL, * v3 = NULL;

    g_return_val_if_fail (t != NULL, 0.0);

    v1 = GTS_SEGMENT (t->e1)->v1;
    if (GTS_SEGMENT (t->e1)->v1 == GTS_SEGMENT (t->e2)->v1) {
        v2 = GTS_SEGMENT (t->e2)->v2;
        v3 = GTS_SEGMENT (t->e1)->v2;
    }
    else if (GTS_SEGMENT (t->e1)->v2 == GTS_SEGMENT (t->e2)->v2) {
        v2 = GTS_SEGMENT (t->e1)->v2;
        v3 = GTS_SEGMENT (t->e2)->v1;
    }
    else if (GTS_SEGMENT (t->e1)->v1 == GTS_SEGMENT (t->e2)->v2) {
        v2 = GTS_SEGMENT (t->e2)->v1;
        v3 = GTS_SEGMENT (t->e1)->v2;
    }
    else if (GTS_SEGMENT (t->e1)->v2 == GTS_SEGMENT (t->e2)->v1) {
        v2 = GTS_SEGMENT (t->e1)->v2;
        v3 = GTS_SEGMENT (t->e2)->v2;
    }
    else
        g_assert_not_reached ();
    return gts_point_orientation (GTS_POINT (v1),
                                  GTS_POINT (v2),
                                  GTS_POINT (v3));
}
コード例 #3
0
ファイル: segment.c プロジェクト: BenBergman/geda-pcb
/**
 * gts_segments_are_intersecting:
 * @s1: a #GtsSegment.
 * @s2: a #GtsSegment.
 *
 * Returns: %GTS_IN if @s1 and @s2 are intersecting, %GTS_ON if one of the
 * endpoints of @s1 (resp. @s2) lies on @s2 (resp. @s1), %GTS_OUT otherwise.
 */
GtsIntersect gts_segments_are_intersecting (GtsSegment * s1, GtsSegment * s2)
{
  GtsPoint * p1, * p2, * p3, * p4;
  gdouble d1, d2, d3, d4;

  g_return_val_if_fail (s1 != NULL && s2 != NULL, FALSE);

  p1 = GTS_POINT (s1->v1); p2 = GTS_POINT (s1->v2);
  p3 = GTS_POINT (s2->v1); p4 = GTS_POINT (s2->v2);
  d1 = gts_point_orientation (p1, p2, p3);
  d2 = gts_point_orientation (p1, p2, p4);
  if ((d1 > 0.0 && d2 > 0.0) ||
      (d1 < 0.0 && d2 < 0.0))
    return GTS_OUT;
  d3 = gts_point_orientation (p3, p4, p1);
  d4 = gts_point_orientation (p3, p4, p2);
  if ((d3 > 0.0 && d4 > 0.0) ||
      (d3 < 0.0 && d4 < 0.0))
    return GTS_OUT;
  if (d1 == 0.0 || d2 == 0.0 || d3 == 0.0 || d4 == 0.0)
    return GTS_ON;
  return GTS_IN;
}
コード例 #4
0
ファイル: delaunay.c プロジェクト: Gilles86/afni
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;
  }
}