示例#1
0
文件: bbtree.c 项目: ClavinSBU/gts
static void surface_distance_foreach_boundary (GtsEdge * e,
					       gpointer * data)
{
  gdouble * delta = data[1];
  GtsRange * range = data[2];
  gdouble * total_length = data[3], length;
  GtsRange range_edge;

  if (gts_edge_is_boundary (e, NULL)) {
    GtsSegment * s =  GTS_SEGMENT (e);

    gts_bb_tree_segment_distance (data[0], s, data[4], *delta, &range_edge);

    if (range_edge.min < range->min)
      range->min = range_edge.min;
    if (range_edge.max > range->max)
      range->max = range_edge.max;
    range->n += range_edge.n;
    
    length = gts_point_distance (GTS_POINT (s->v1), GTS_POINT (s->v2));
    *total_length += length;
    range->sum += length*range_edge.mean;
    range->sum2 += length*range_edge.mean*range_edge.mean;
  }
}
示例#2
0
文件: bbtree.c 项目: ClavinSBU/gts
/**
 * gts_bbox_segment:
 * @klass: a #GtsBBoxClass.
 * @s: a #GtsSegment.
 * 
 * Returns: a new #GtsBBox bounding box of @s.
 */
GtsBBox * gts_bbox_segment (GtsBBoxClass * klass, GtsSegment * s)
{
  GtsBBox * bbox;
  GtsPoint * p1, * p2;

  g_return_val_if_fail (s != NULL, NULL);
  g_return_val_if_fail (klass != NULL, NULL);

  bbox = gts_bbox_new (klass, s, 0., 0., 0., 0., 0., 0.);

  p1 = GTS_POINT (s->v1); 
  p2 = GTS_POINT (s->v2);
  if (p1->x > p2->x) {
    bbox->x2 = p1->x; bbox->x1 = p2->x;
  }
  else {
    bbox->x1 = p1->x; bbox->x2 = p2->x;
  }
  if (p1->y > p2->y) {
    bbox->y2 = p1->y; bbox->y1 = p2->y;
  }
  else {
    bbox->y1 = p1->y; bbox->y2 = p2->y;
  }
  if (p1->z > p2->z) {
    bbox->z2 = p1->z; bbox->z1 = p2->z;
  }
  else {
    bbox->z1 = p1->z; bbox->z2 = p2->z;
  }

  return bbox;
}
示例#3
0
文件: triangle.c 项目: finetjul/gts
/**
 * gts_triangles_are_folded:
 * @triangles: a list of #GtsTriangle.
 * @A: a #GtsVertex.
 * @B: another #GtsVertex.
 * @max: the maximum value of the square of the cosine of the angle between
 * two triangles.
 *
 * Given a list of triangles sharing @A and @B as vertices, checks if any
 * two triangles in the list make an angle larger than a given value defined
 * by @max.
 *
 * Returns: %TRUE if any pair of triangles in @triangles makes an angle larger
 * than the maximum value, %FALSE otherwise.
 */
gboolean gts_triangles_are_folded (GSList * triangles,
                                   GtsVertex * A, GtsVertex * B,
                                   gdouble max)
{
    GSList * i;

    g_return_val_if_fail (A != NULL, TRUE);
    g_return_val_if_fail (B != NULL, TRUE);

    i = triangles;
    while (i) {
        GtsVertex * C = triangle_use_vertices (i->data, A, B);
        GSList * j = i->next;
        while (j) {
            GtsVertex * D = triangle_use_vertices (j->data, A, B);
            if (points_are_folded (GTS_POINT (A),
                                   GTS_POINT (B),
                                   GTS_POINT (C),
                                   GTS_POINT (D),
                                   max))
                return TRUE;
            j = j->next;
        }
        i = i->next;
    }
    return FALSE;
}
示例#4
0
文件: triangle.c 项目: finetjul/gts
/**
 * gts_triangle_interpolate_height:
 * @t: a #GtsTriangle.
 * @p: a #GtsPoint.
 *
 * Fills the z-coordinate of point @p belonging to the plane
 * projection of triangle @t with the linearly interpolated value of
 * the z-coordinates of the vertices of @t.
 */
void gts_triangle_interpolate_height (GtsTriangle * t, GtsPoint * p)
{
    GtsPoint * p1, * p2, * p3;
    gdouble x1, x2, y1, y2, det;

    g_return_if_fail (t != NULL);
    g_return_if_fail (p != NULL);

    p1 = GTS_POINT (GTS_SEGMENT (t->e1)->v1);
    p2 = GTS_POINT (GTS_SEGMENT (t->e1)->v2);
    p3 = GTS_POINT (gts_triangle_vertex (t));

    x1 = p2->x - p1->x;
    y1 = p2->y - p1->y;
    x2 = p3->x - p1->x;
    y2 = p3->y - p1->y;
    det = x1*y2 - x2*y1;
    if (det == 0.)
        p->z = (p1->z + p2->z + p3->z)/3.;
    else {
        gdouble x = p->x - p1->x;
        gdouble y = p->y - p1->y;
        gdouble a = (x*y2 - y*x2)/det;
        gdouble b = (y*x1 - x*y1)/det;

        p->z = (1. - a - b)*p1->z + a*p2->z + b*p3->z;
    }
}
示例#5
0
文件: bbtree.c 项目: ClavinSBU/gts
/**
 * gts_bbox_triangle:
 * @klass: a #GtsBBoxClass.
 * @t: a #GtsTriangle.
 *
 * Returns: a new #GtsBBox bounding box of @t.
 */
GtsBBox * gts_bbox_triangle (GtsBBoxClass * klass,
			     GtsTriangle * t)
{
  GtsBBox * bbox;
  GtsPoint * p;

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

  p = GTS_POINT (GTS_SEGMENT (t->e1)->v1);
  bbox = gts_bbox_new (klass, t, p->x, p->y, p->z, p->x, p->y, p->z);

  p = GTS_POINT (GTS_SEGMENT (t->e1)->v2);
  if (p->x > bbox->x2) bbox->x2 = p->x;
  if (p->x < bbox->x1) bbox->x1 = p->x;
  if (p->y > bbox->y2) bbox->y2 = p->y;
  if (p->y < bbox->y1) bbox->y1 = p->y;
  if (p->z > bbox->z2) bbox->z2 = p->z;
  if (p->z < bbox->z1) bbox->z1 = p->z;
  p = GTS_POINT (gts_triangle_vertex (t));
  if (p->x > bbox->x2) bbox->x2 = p->x;
  if (p->x < bbox->x1) bbox->x1 = p->x;
  if (p->y > bbox->y2) bbox->y2 = p->y;
  if (p->y < bbox->y1) bbox->y1 = p->y;
  if (p->z > bbox->z2) bbox->z2 = p->z;
  if (p->z < bbox->z1) bbox->z1 = p->z;
  
  return bbox;
}
示例#6
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));
}
示例#7
0
文件: happrox.c 项目: ClavinSBU/gts
static GtsSurface * happrox_list (GSList * points,
				  gboolean keep_enclosing,
				  gboolean closed,
				  CostFunc cost_func,
				  gpointer cost_data,
				  GtsStopFunc stop_func,
				  gpointer stop_data)
{
  GtsSurface * s = gts_surface_new (gts_surface_class (),
				    GTS_FACE_CLASS (list_face_class ()),
				    gts_edge_class (),
				    gts_vertex_class ());
  GtsTriangle * t;
  GtsVertex * w1, * w2, * w3;
  GtsListFace * f;

  /* creates enclosing triangle */
  t = gts_triangle_enclosing (gts_triangle_class (), points, 10.);
  gts_triangle_vertices (t, &w1, &w2, &w3);
  GTS_POINT (w1)->z = GTS_POINT (w2)->z = GTS_POINT (w3)->z = 
    keep_enclosing ? -10. : -1e30;

  f = GTS_LIST_FACE (gts_face_new (s->face_class, t->e1, t->e2, t->e3));
  gts_surface_add_face (s, GTS_FACE (f));
  f->points = points;

  /* refine surface */
  surface_hf_refine (s, cost_func, cost_data, stop_func, stop_data);

  /* destroy unused vertices */
  gts_surface_foreach_face (s, (GtsFunc) destroy_unused, NULL);
  
  /* destroy enclosing triangle */
  if (!keep_enclosing) {
    gts_allow_floating_vertices = TRUE;
    gts_object_destroy (GTS_OBJECT (w1));
    gts_object_destroy (GTS_OBJECT (w2));
    gts_object_destroy (GTS_OBJECT (w3));
    gts_allow_floating_vertices = FALSE;
  }
  else if (closed) {
    GSList * l = gts_surface_boundary (s);
    GtsFace * f;

    g_assert (g_slist_length (l) == 3);
    f = gts_face_new (s->face_class, l->data, l->next->data, l->next->next->data);
    gts_surface_add_face (s, f);
    if (!gts_face_is_compatible (f, s))
      gts_triangle_revert (GTS_TRIANGLE (f));
    g_slist_free (l);
    gts_object_destroy (GTS_OBJECT (t));
  }
  else
    gts_object_destroy (GTS_OBJECT (t));

  return s;
}
示例#8
0
static gboolean angle_obtuse (GtsVertex * v, GtsFace * f)
{
  GtsEdge * e = gts_triangle_edge_opposite (GTS_TRIANGLE (f), v);
  GtsVector vec1, vec2;

  gts_vector_init (vec1, GTS_POINT (v), GTS_POINT (GTS_SEGMENT (e)->v1));
  gts_vector_init (vec2, GTS_POINT (v), GTS_POINT (GTS_SEGMENT (e)->v2));

  return (gts_vector_scalar (vec1, vec2) < 0.0);
}
示例#9
0
文件: misc.c 项目: MicBosi/GTS
void gts_write_triangle (GtsTriangle * t, 
			 GtsPoint * o,
			 FILE * fptr)
{
  gdouble xo = o ? o->x : 0.0;
  gdouble yo = o ? o->y : 0.0;
  gdouble zo = o ? o->z : 0.0;

  g_return_if_fail (t != NULL && fptr != NULL);

  fprintf (fptr, "(hdefine geometry \"t%d\" { =\n", id (t));
  fprintf (fptr, "OFF 3 1 0\n"
	   "%g %g %g\n%g %g %g\n%g %g %g\n3 0 1 2\n})\n"
	   "(geometry \"t%d\" { : \"t%d\"})\n"
	   "(normalization \"t%d\" none)\n",
	   GTS_POINT (GTS_SEGMENT (t->e1)->v1)->x - xo, 
	   GTS_POINT (GTS_SEGMENT (t->e1)->v1)->y - yo,
	   GTS_POINT (GTS_SEGMENT (t->e1)->v1)->z - zo,
	   GTS_POINT (GTS_SEGMENT (t->e1)->v2)->x - xo, 
	   GTS_POINT (GTS_SEGMENT (t->e1)->v2)->y - yo, 
	   GTS_POINT (GTS_SEGMENT (t->e1)->v2)->z - zo,
	   GTS_POINT (gts_triangle_vertex (t))->x - xo,
	   GTS_POINT (gts_triangle_vertex (t))->y - yo,
	   GTS_POINT (gts_triangle_vertex (t))->z - zo,
	   id (t), id (t), id (t));
}
示例#10
0
void gts_triangulate_convex_polygon(GtsSurface *s, GtsEdgePool *pool, GCList *p)
{
	guint poly_length = g_clist_length(p);
	
	while (poly_length > 2) {
		while (poly_length > 3) {
			
			GtsVector e1, e2; 
			GtsPoint *v1 = GTS_POINT(p->prev->data);
			GtsPoint *v2 = GTS_POINT(p->data);
			GtsPoint *v3 = GTS_POINT(p->next->data);
			GtsPoint *v4 = GTS_POINT(p->next->next->data);
			
			if (v1 == v3 || v2 == v4) {
				g_debug("kill degenerated triangle"); 
				GCList *p1 = p;
				GCList *p2 = p->next;
				p=g_clist_delete_link(p,p1);
				p=g_clist_delete_link(p,p2);
				poly_length -= 2; 
				continue; 
			}
			
			gts_vector_init(e1, v1, v3);
			gts_vector_init(e2, v2, v4);
			
			if (gts_vector_scalar(e1, e1) < gts_vector_scalar(e2, e2)) {
				add_face_from_polygon_corner(s, pool, 
							     GTS_VERTEX(v1), 
							     GTS_VERTEX(v2),
							     GTS_VERTEX(v3)); 
				p = g_clist_delete_link(p, p);
			} else {
				add_face_from_polygon_corner(s, pool, 
							     GTS_VERTEX(v2), 
							     GTS_VERTEX(v3),
							     GTS_VERTEX(v4)); 
				p = g_clist_delete_link(p, p->next);
			}
			--poly_length; 
			
		}
		if (g_clist_length(p) > 2) {
			add_face_from_polygon_corner(s, pool, 
						     GTS_VERTEX(p->prev->data), 
						     GTS_VERTEX(p->data),
						     GTS_VERTEX(p->next->data));
			p = g_clist_delete_link(p, p);
			--poly_length; 
		}
		
	}
	g_clist_free(p);
}
示例#11
0
文件: triangle.c 项目: finetjul/gts
/**
 * gts_triangle_normal:
 * @t: a #GtsTriangle.
 * @x: the x coordinate of the normal.
 * @y: the y coordinate of the normal.
 * @z: the z coordinate of the normal.
 *
 * Computes the coordinates of the oriented normal of @t as the
 * cross-product of two edges, using the left-hand rule. The normal is
 * not normalized.  If this triangle is part of a closed and oriented
 * surface, the normal points to the outside of the surface.
 */
void gts_triangle_normal (GtsTriangle * t,
                          gdouble * x,
                          gdouble * y,
                          gdouble * z)
{
    GtsVertex * v1, * v2 = NULL, * v3 = NULL;
    GtsPoint * p1, * p2, * p3;
    gdouble x1, y1, z1, x2, y2, z2;

    g_return_if_fail (t != NULL);

    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 {
        fprintf (stderr, "t: %p t->e1: %p t->e2: %p t->e3: %p t->e1->v1: %p t->e1->v2: %p t->e2->v1: %p t->e2->v2: %p t->e3->v1: %p t->e3->v2: %p\n",
                 t, t->e1, t->e2,
                 t->e3, GTS_SEGMENT (t->e1)->v1, GTS_SEGMENT (t->e1)->v2,
                 GTS_SEGMENT (t->e2)->v1, GTS_SEGMENT (t->e2)->v2,
                 GTS_SEGMENT (t->e3)->v1, GTS_SEGMENT (t->e3)->v2);
        g_assert_not_reached ();
    }

    p1 = GTS_POINT (v1);
    p2 = GTS_POINT (v2);
    p3 = GTS_POINT (v3);

    x1 = p2->x - p1->x;
    y1 = p2->y - p1->y;
    z1 = p2->z - p1->z;

    x2 = p3->x - p1->x;
    y2 = p3->y - p1->y;
    z2 = p3->z - p1->z;

    *x = y1*z2 - z1*y2;
    *y = z1*x2 - x1*z2;
    *z = x1*y2 - y1*x2;
}
示例#12
0
/**
 * gts_segment_midvertex:
 * @s: a #GtsSegment.
 * @klass: a #GtsVertexClass to be used for the new vertex.
 *
 * Returns: a new #GtsVertex, midvertex of @s.
 */
GtsVertex * gts_segment_midvertex (GtsSegment * s, GtsVertexClass * klass)
{
  GtsPoint * p1, * p2;

  g_return_val_if_fail (s != NULL, NULL);
  g_return_val_if_fail (klass != NULL, NULL);

  p1 = GTS_POINT (s->v1); p2 = GTS_POINT (s->v2);
  return gts_vertex_new (klass,
			 (p1->x + p2->x)/2., 
			 (p1->y + p2->y)/2.,
			 (p1->z + p2->z)/2.);
}
示例#13
0
文件: optimize.c 项目: 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);
}
示例#14
0
/* Helper function for inGtsSurface::aabb() */
static void vertex_aabb(GtsVertex *vertex, std::pair<Vector3r,Vector3r> *bb)
{
	GtsPoint *_p=GTS_POINT(vertex);
	Vector3r p(_p->x,_p->y,_p->z);
	bb->first=bb->first.cwiseMin(p);
	bb->second=bb->second.cwiseMax(p);
}
示例#15
0
gint gts_polygon_orientation(GCList *polygon, GtsVector retval) 
{
	GtsVector a,b; 
	
	retval[0] = retval[1] = retval[2] = 0.0; 
	
	if (polygon->next == polygon->prev) /* only two points */ 
		return 0;
		
	gts_vector_init(a, GTS_POINT(polygon->data), GTS_POINT(polygon->prev->data)); 
	gts_vector_init(b, GTS_POINT(polygon->data), GTS_POINT(polygon->next->data)); 
	
	gts_vector_cross(retval, a, b);
	gts_vector_normalize(retval); 
	
	return 1; 
}
示例#16
0
文件: bbtree.c 项目: ClavinSBU/gts
/**
 * gts_bb_tree_triangle_distance:
 * @tree: a bounding box tree.
 * @t: a #GtsTriangle.
 * @distance: a #GtsBBoxDistFunc.
 * @delta: spatial scale of the sampling to be used.
 * @range: a #GtsRange to be filled with the results.
 * 
 * Given a triangle @t, points are sampled regularly on its surface
 * using @delta as increment. The distance from each of these points
 * to the closest object of @tree is computed using @distance and the
 * gts_bb_tree_point_distance() function. The fields of @range are
 * filled with the number of points sampled, the minimum, average and
 * maximum value and the standard deviation.  
 */
void gts_bb_tree_triangle_distance (GNode * tree,
				    GtsTriangle * t,
				    GtsBBoxDistFunc distance,
				    gdouble delta,
				    GtsRange * range)
{
  GtsPoint * p1, * p2, * p3, * p;
  GtsVector p1p2, p1p3;
  gdouble l1, t1, dt1;
  guint i, n1;

  g_return_if_fail (tree != NULL);
  g_return_if_fail (t != NULL);
  g_return_if_fail (distance != NULL);
  g_return_if_fail (delta > 0.);
  g_return_if_fail (range != NULL);

  gts_triangle_vertices (t, 
			 (GtsVertex **) &p1, 
			 (GtsVertex **) &p2, 
			 (GtsVertex **) &p3);

  gts_vector_init (p1p2, p1, p2);
  gts_vector_init (p1p3, p1, p3);
  gts_range_init (range);
  p = GTS_POINT (gts_object_new (GTS_OBJECT_CLASS (gts_point_class ())));

  l1 = sqrt (gts_vector_scalar (p1p2, p1p2));
  n1 = l1/delta + 1;
  dt1 = 1.0/(gdouble) n1;
  t1 = 0.0;
  for (i = 0; i <= n1; i++, t1 += dt1) {
    gdouble t2 = 1. - t1;
    gdouble x = t2*p1p3[0];
    gdouble y = t2*p1p3[1];
    gdouble z = t2*p1p3[2];
    gdouble l2 = sqrt (x*x + y*y + z*z);
    guint j, n2 = (guint) (l2/delta + 1);
    gdouble dt2 = t2/(gdouble) n2;

    x = t2*p1->x + t1*p2->x;
    y = t2*p1->y + t1*p2->y;
    z = t2*p1->z + t1*p2->z;
    
    t2 = 0.0;
    for (j = 0; j <= n2; j++, t2 += dt2) {
      p->x = x + t2*p1p3[0];
      p->y = y + t2*p1p3[1];
      p->z = z + t2*p1p3[2];

      gts_range_add_value (range,
		    gts_bb_tree_point_distance (tree, p, distance, NULL));
    }
  }

  gts_object_destroy (GTS_OBJECT (p));
  gts_range_update (range);
}
示例#17
0
int 
pygts_segment_compare(GtsSegment* s1,GtsSegment* s2)
{
  if( (pygts_point_compare(GTS_POINT(s1->v1),GTS_POINT(s2->v1))==0 &&
       pygts_point_compare(GTS_POINT(s1->v2),GTS_POINT(s2->v2))==0) || 
      (pygts_point_compare(GTS_POINT(s1->v1),GTS_POINT(s2->v2))==0 &&
       pygts_point_compare(GTS_POINT(s1->v2),GTS_POINT(s2->v1))==0) ) {
    return 0;
  }
  return -1;
}
示例#18
0
static gdouble angle_from_cotan (GtsVertex * vo, 
				 GtsVertex * v1, GtsVertex * v2)
{
  /* cf. Appendix B and the caption of Table 1 from [Meyer et al 2002] */
  GtsVector u, v;
  gdouble udotv, denom;

  gts_vector_init (u, GTS_POINT (vo), GTS_POINT (v1));
  gts_vector_init (v, GTS_POINT (vo), GTS_POINT (v2));

  udotv = gts_vector_scalar (u, v);
  denom = sqrt (gts_vector_scalar (u,u)*gts_vector_scalar (v,v) 
		- udotv*udotv);

  /* Note: I assume this is what they mean by using atan2 (). -Ray Jones */

  /* tan = denom/udotv = y/x (see man page for atan2) */
  return (fabs (atan2 (denom, udotv)));
}
示例#19
0
static gdouble cotan (GtsVertex * vo, GtsVertex * v1, GtsVertex * v2)
{
  /* cf. Appendix B of [Meyer et al 2002] */
  GtsVector u, v;
  gdouble udotv, denom;

  gts_vector_init (u, GTS_POINT (vo), GTS_POINT (v1));
  gts_vector_init (v, GTS_POINT (vo), GTS_POINT (v2));

  udotv = gts_vector_scalar (u, v);
  denom = sqrt (gts_vector_scalar (u,u)*gts_vector_scalar (v,v) -
		udotv*udotv);


  /* denom can be zero if u==v.  Returning 0 is acceptable, based on
   * the callers of this function below. */
  if (denom == 0.0) return (0.0);

  return (udotv/denom);
}
示例#20
0
文件: bbtree.c 项目: ClavinSBU/gts
/**
 * gts_bb_tree_segment_distance:
 * @tree: a bounding box tree.
 * @s: a #GtsSegment.
 * @distance: a #GtsBBoxDistFunc.
 * @delta: spatial scale of the sampling to be used.
 * @range: a #GtsRange to be filled with the results.
 * 
 * Given a segment @s, points are sampled regularly on its length
 * using @delta as increment. The distance from each of these points
 * to the closest object of @tree is computed using @distance and the
 * gts_bb_tree_point_distance() function. The fields of @range are
 * filled with the number of points sampled, the minimum, average and
 * maximum value and the standard deviation.  
 */
void gts_bb_tree_segment_distance (GNode * tree,
				   GtsSegment * s,
				   gdouble (*distance) (GtsPoint *, 
							gpointer),
				   gdouble delta,
				   GtsRange * range)
{
  GtsPoint * p1, * p2, * p;
  GtsVector p1p2;
  gdouble l, t, dt;
  guint i, n;

  g_return_if_fail (tree != NULL);
  g_return_if_fail (s != NULL);
  g_return_if_fail (distance != NULL);
  g_return_if_fail (delta > 0.);
  g_return_if_fail (range != NULL);

  p1 = GTS_POINT (s->v1);
  p2 = GTS_POINT (s->v2);

  gts_vector_init (p1p2, p1, p2);
  gts_range_init (range);
  p = GTS_POINT (gts_object_new (GTS_OBJECT_CLASS (gts_point_class())));

  l = sqrt (gts_vector_scalar (p1p2, p1p2));
  n = (guint) (l/delta + 1);
  dt = 1.0/(gdouble) n;
  t = 0.0;
  for (i = 0; i <= n; i++, t += dt) {
    p->x = p1->x + t*p1p2[0];
    p->y = p1->y + t*p1p2[1];
    p->z = p1->z + t*p1p2[2];
    
    gts_range_add_value (range,
			 gts_bb_tree_point_distance (tree, p, distance, NULL));
  }

  gts_object_destroy (GTS_OBJECT (p));
  gts_range_update (range);
}
示例#21
0
文件: gts2stl.c 项目: Gilles86/afni
static void write_face (GtsTriangle * t)
{
  GtsVertex * v1, * v2, * v3;
  GtsVector n;

  gts_triangle_vertices (t, &v1, &v2, &v3);
  gts_triangle_normal (t, &n[0], &n[1], &n[2]);
  gts_vector_normalize (n);
  printf ("facet normal %g %g %g\nouter loop\n", n[0], n[1], n[2]);
  printf ("vertex %g %g %g\n", 
	  GTS_POINT (v1)->x, GTS_POINT (v1)->y, GTS_POINT (v1)->z);
  printf ("vertex %g %g %g\n", 
	  GTS_POINT (v2)->x, GTS_POINT (v2)->y, GTS_POINT (v2)->z);
  printf ("vertex %g %g %g\n", 
	  GTS_POINT (v3)->x, GTS_POINT (v3)->y, GTS_POINT (v3)->z);
  puts ("endloop\nendfacet");
}
示例#22
0
文件: happrox.c 项目: ClavinSBU/gts
static void triangle_plane (GtsTriangle * f, GtsVector p)
{
  GtsPoint * v1, * v2, * v3;
  gdouble x1, x2, y1, y2, det;

  v1 = GTS_POINT (GTS_SEGMENT (f->e1)->v1);
  v2 = GTS_POINT (GTS_SEGMENT (f->e1)->v2);
  v3 = GTS_POINT (gts_triangle_vertex (f));

  x1 = v2->x - v1->x;
  y1 = v2->y - v1->y;
  x2 = v3->x - v1->x;
  y2 = v3->y - v1->y;
  det = x1*y2 - x2*y1;
  g_assert (det != 0.);

  p[0] = (y2*(v2->z - v1->z) - y1*(v3->z - v1->z))/det;
  p[1] = (-x2*(v2->z - v1->z) + x1*(v3->z - v1->z))/det;
  p[2] = ((- v1->x*y2 + v1->y*x2)*(v2->z - v1->z) +
	  (- v1->y*x1 + v1->x*y1)*(v3->z - v1->z))/det + v1->z;
}
示例#23
0
static void smooth_vertex (GtsVertex * v, gpointer * data)
{
  GtsSurface * s = data[0];

  if (!gts_vertex_is_boundary (v, s)) {
    gdouble * lambda = data[1];
    GSList * vertices = gts_vertex_neighbors (v, NULL, s);
    GSList * i;
    GtsVector U0 = { 0., 0., 0.};
    guint n = 0;
    
    i = vertices;
    while (i) {
      GtsPoint * p = i->data;
      U0[0] += p->x;
      U0[1] += p->y;
      U0[2] += p->z;
      n++;
      i = i->next;
    }
    g_slist_free (vertices);
    
    if (n > 0) {
      GTS_POINT (v)->x += (*lambda)*(U0[0]/n - GTS_POINT (v)->x);
      GTS_POINT (v)->y += (*lambda)*(U0[1]/n - GTS_POINT (v)->y);
      GTS_POINT (v)->z += (*lambda)*(U0[2]/n - GTS_POINT (v)->z);
    }
  }
}
示例#24
0
文件: bbtree.c 项目: ClavinSBU/gts
/**
 * gts_bbox_overlaps_triangle:
 * @bb: a #GtsBBox.
 * @t: a #GtsTriangle.
 *
 * This is a wrapper around the fast overlap test of Tomas
 * Akenine-Moller (http://www.cs.lth.se/home/Tomas_Akenine_Moller/).
 *
 * Returns: %TRUE if @bb overlaps with @t, %FALSE otherwise.
 */
gboolean gts_bbox_overlaps_triangle (GtsBBox * bb, GtsTriangle * t)
{
  double bc[3], bh[3], tv[3][3];
  GtsPoint * p1, * p2, * p3;

  g_return_val_if_fail (bb != NULL, FALSE);
  g_return_val_if_fail (t != NULL, FALSE);

  bc[0] = (bb->x2 + bb->x1)/2.;
  bh[0] = (bb->x2 - bb->x1)/2.;
  bc[1] = (bb->y2 + bb->y1)/2.;
  bh[1] = (bb->y2 - bb->y1)/2.;
  bc[2] = (bb->z2 + bb->z1)/2.;
  bh[2] = (bb->z2 - bb->z1)/2.;
  p1 = GTS_POINT (GTS_SEGMENT (t->e1)->v1);
  p2 = GTS_POINT (GTS_SEGMENT (t->e1)->v2);
  p3 = GTS_POINT (gts_triangle_vertex (t));
  tv[0][0] = p1->x; tv[0][1] = p1->y; tv[0][2] = p1->z;
  tv[1][0] = p2->x; tv[1][1] = p2->y; tv[1][2] = p2->z;
  tv[2][0] = p3->x; tv[2][1] = p3->y; tv[2][2] = p3->z;

  return triBoxOverlap (bc, bh, tv);
}
示例#25
0
文件: bbtree.c 项目: ClavinSBU/gts
/**
 * gts_bbox_overlaps_segment:
 * @bb: a #GtsBBox.
 * @s: a #GtsSegment.
 *
 * This functions uses gts_bbox_overlaps_triangle() with a degenerate
 * triangle.
 *
 * Returns: %TRUE if @bb overlaps with @s, %FALSE otherwise.
 */
gboolean gts_bbox_overlaps_segment (GtsBBox * bb, GtsSegment * s)
{
  double bc[3], bh[3], tv[3][3];
  GtsPoint * p1, * p2, * p3;

  g_return_val_if_fail (bb != NULL, FALSE);
  g_return_val_if_fail (s != NULL, FALSE);

  bc[0] = (bb->x2 + bb->x1)/2.;
  bh[0] = (bb->x2 - bb->x1)/2.;
  bc[1] = (bb->y2 + bb->y1)/2.;
  bh[1] = (bb->y2 - bb->y1)/2.;
  bc[2] = (bb->z2 + bb->z1)/2.;
  bh[2] = (bb->z2 - bb->z1)/2.;
  p1 = GTS_POINT (s->v1);
  p2 = GTS_POINT (s->v2);
  p3 = p1;
  tv[0][0] = p1->x; tv[0][1] = p1->y; tv[0][2] = p1->z;
  tv[1][0] = p2->x; tv[1][1] = p2->y; tv[1][2] = p2->z;
  tv[2][0] = p3->x; tv[2][1] = p3->y; tv[2][2] = p3->z;

  return triBoxOverlap (bc, bh, tv);
}
示例#26
0
static gdouble region_area (GtsVertex * v, GtsFace * f)
{
  /* cf. Section 3.3 of [Meyer et al 2002] */
  
  if (gts_triangle_area (GTS_TRIANGLE (f)) == 0.0) return (0.0);

  if (triangle_obtuse (v, f)) {
    if (angle_obtuse (v, f))
      return (gts_triangle_area (GTS_TRIANGLE (f))/2.0);
    else
      return (gts_triangle_area (GTS_TRIANGLE (f))/4.0);
  } else {
    GtsEdge * e = gts_triangle_edge_opposite (GTS_TRIANGLE (f), v);

    return ((cotan (GTS_SEGMENT (e)->v1, v, GTS_SEGMENT (e)->v2)* 
             gts_point_distance2 (GTS_POINT (v), 
				  GTS_POINT (GTS_SEGMENT (e)->v2)) +
             cotan (GTS_SEGMENT (e)->v2, v, GTS_SEGMENT (e)->v1)* 
             gts_point_distance2 (GTS_POINT (v), 
                                  GTS_POINT (GTS_SEGMENT (e)->v1)))
            /8.0);
  }
}
示例#27
0
/**
 * 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;
}
示例#28
0
文件: triangle.c 项目: finetjul/gts
/**
 * gts_triangle_enclosing:
 * @klass: the class of the new triangle.
 * @points: a list of #GtsPoint.
 * @scale: a scaling factor (must be larger than one).
 *
 * Builds a new triangle (including new vertices and edges) enclosing
 * the plane projection of all the points in @points. This triangle is
 * equilateral and encloses a rectangle defined by the maximum and
 * minimum x and y coordinates of the points. @scale is an homothetic
 * scaling factor. If equal to one, the triangle encloses exactly the
 * enclosing rectangle.
 *
 * Returns: a new #GtsTriangle.
 */
GtsTriangle * gts_triangle_enclosing (GtsTriangleClass * klass,
                                      GSList * points, gdouble scale)
{
    gdouble xmax, xmin, ymax, ymin;
    gdouble xo, yo, r;
    GtsVertex * v1, * v2, * v3;
    GtsEdge * e1, * e2, * e3;

    if (points == NULL)
        return NULL;

    xmax = xmin = GTS_POINT (points->data)->x;
    ymax = ymin = GTS_POINT (points->data)->y;
    points = points->next;
    while (points) {
        GtsPoint * p = points->data;
        if (p->x > xmax) xmax = p->x;
        else if (p->x < xmin) xmin = p->x;
        if (p->y > ymax) ymax = p->y;
        else if (p->y < ymin) ymin = p->y;
        points = points->next;
    }
    xo = (xmax + xmin)/2.;
    yo = (ymax + ymin)/2.;
    r = scale*sqrt((xmax - xo)*(xmax - xo) + (ymax - yo)*(ymax - yo));
    if (r == 0.0) r = scale;
    v1 = gts_vertex_new (gts_vertex_class (),
                         xo + r*SQRT3, yo - r, 0.0);
    v2 = gts_vertex_new (gts_vertex_class (),
                         xo, yo + 2.*r, 0.0);
    v3 = gts_vertex_new (gts_vertex_class (),
                         xo - r*SQRT3, yo - r, 0.0);
    e1 = gts_edge_new (gts_edge_class (), v1, v2);
    e2 = gts_edge_new (gts_edge_class (), v2, v3);
    e3 = gts_edge_new (gts_edge_class (), v3, v1);
    return gts_triangle_new (gts_triangle_class (), e1, e2, e3);
}
示例#29
0
static void write_edge (GtsSegment * s, FILE * fp)
{
  fprintf (fp, "VECT 1 2 0 2 0 %g %g %g %g %g %g\n",
	   GTS_POINT (s->v1)->x,
	   GTS_POINT (s->v1)->y,
	   GTS_POINT (s->v1)->z,
	   GTS_POINT (s->v2)->x,
	   GTS_POINT (s->v2)->y,
	   GTS_POINT (s->v2)->z);
}
示例#30
0
文件: triangle.c 项目: finetjul/gts
/**
 * gts_triangle_perimeter:
 * @t: a #GtsTriangle.
 *
 * Returns: the perimeter of the triangle @t.
 */
gdouble gts_triangle_perimeter (GtsTriangle * t)
{
    GtsVertex * v;

    g_return_val_if_fail (t != NULL, 0.0);

    v = gts_triangle_vertex (t);
    return
        gts_point_distance (GTS_POINT (GTS_SEGMENT (t->e1)->v1),
                            GTS_POINT (GTS_SEGMENT (t->e1)->v2)) +
        gts_point_distance (GTS_POINT (GTS_SEGMENT (t->e1)->v1),
                            GTS_POINT (v)) +
        gts_point_distance (GTS_POINT (GTS_SEGMENT (t->e1)->v2),
                            GTS_POINT (v));
}