/**
 * graphene_triangle_contains_point:
 * @t: a #graphene_triangle_t
 * @p: a #graphene_point3d_t
 *
 * Checks whether the given triangle @t contains the point @p.
 *
 * Returns: `true` if the point is inside the triangle
 *
 * Since: 1.2
 */
bool
graphene_triangle_contains_point (const graphene_triangle_t *t,
                                  const graphene_point3d_t  *p)
{
  graphene_vec3_t point, v1, v2, v3;
  float dot_11, dot_12, dot_13;
  float dot_22, dot_23;
  float inv_denom, u, v;

  graphene_point3d_to_vec3 (p, &point);

  /* we use the barycoordinates from the given point to check
   * if the point is inside the triangle.
   *
   * see: http://www.blackpawn.com/texts/pointinpoly/default.html
   */
  graphene_vec3_subtract (&t->c, &t->a, &v1);
  graphene_vec3_subtract (&t->b, &t->a, &v2);
  graphene_vec3_subtract (&point, &t->a, &v3);

  dot_11 = graphene_vec3_dot (&v1, &v1);
  dot_12 = graphene_vec3_dot (&v1, &v2);
  dot_13 = graphene_vec3_dot (&v1, &v3);
  dot_22 = graphene_vec3_dot (&v2, &v2);
  dot_23 = graphene_vec3_dot (&v2, &v3);

  inv_denom = 1.f / (dot_11 * dot_22 - dot_12 * dot_12);
  u = (dot_22 * dot_13 - dot_12 * dot_23) * inv_denom;
  v = (dot_11 * dot_23 - dot_12 * dot_13) * inv_denom;

  return (u >= 0.f) && (v >= 0.f) && (u + v < 1.f);
}
Exemple #2
0
/**
 * graphene_ray_get_distance_to_point:
 * @r: a #graphene_ray_t
 * @p: a #graphene_point3d_t
 *
 * Computes the distance from the origin of the given ray to the given point.
 *
 * Returns: the distance of the point
 *
 * Since: 1.4
 */
float
graphene_ray_get_distance_to_point (const graphene_ray_t     *r,
                                    const graphene_point3d_t *p)
{
  graphene_vec3_t point;
  graphene_vec3_t tmp;
  float distance;

  graphene_point3d_to_vec3 (p, &point);

  graphene_vec3_subtract (&point, &r->origin, &tmp);
  distance = graphene_vec3_dot (&tmp, &r->direction);

  /* the point is behind the ray */
  if (distance < 0)
    {
      graphene_vec3_subtract (&r->origin, &point, &tmp);
      return graphene_vec3_length (&tmp);
    }

  /* get the position on the ray at the given distance */
  graphene_vec3_scale (&r->direction, distance, &tmp);
  graphene_vec3_add (&tmp, &r->origin, &tmp);

  graphene_vec3_subtract (&tmp, &point, &tmp);

  return graphene_vec3_length (&tmp);
}
/**
 * graphene_triangle_get_area:
 * @t: a #graphene_triangle_t
 *
 * Computes the area of the given #graphene_triangle_t.
 *
 * Returns: the area of the triangle
 *
 * Since: 1.2
 */
float
graphene_triangle_get_area (const graphene_triangle_t *t)
{
  graphene_vec3_t v1, v2, tmp;

  graphene_vec3_subtract (&t->c, &t->b, &v1);
  graphene_vec3_subtract (&t->a, &t->b, &v2);

  graphene_vec3_cross (&v1, &v2, &tmp);

  return graphene_vec3_length (&tmp) * .5f;
}
Exemple #4
0
/**
 * graphene_matrix_project_point:
 * @m: ...
 * @p: ...
 * @res: (out caller-allocates): ...
 *
 * ...
 *
 * Since: 1.0
 */
void
graphene_matrix_project_point (const graphene_matrix_t *m,
                               const graphene_point_t  *p,
                               graphene_point_t        *res)
{
  graphene_vec3_t pa, qa;
  graphene_vec3_t pback, qback, uback;
  float p_z, u_z, t;

  g_return_if_fail (m != NULL);
  g_return_if_fail (p != NULL);
  g_return_if_fail (res != NULL);

  graphene_vec3_init (&pa, p->x, p->y, 0.0f);
  graphene_vec3_init (&qa, p->x, p->y, 1.0f);

  graphene_matrix_transform_vec3 (m, &pa, &pback);
  graphene_matrix_transform_vec3 (m, &qa, &qback);

  graphene_vec3_subtract (&qback, &pback, &uback);

  p_z = graphene_vec3_get_z (&pback);
  u_z = graphene_vec3_get_z (&uback);
  t = -p_z / u_z;

  graphene_point_init (res,
                       graphene_vec3_get_x (&pback) + t * graphene_vec3_get_x (&uback),
                       graphene_vec3_get_y (&pback) + t * graphene_vec3_get_y (&uback));
}
/**
 * graphene_triangle_get_normal:
 * @t: a #graphene_triangle_t
 * @res: (out caller-allocates): return location for the normal vector
 *
 * Computes the normal vector of the given #graphene_triangle_t.
 *
 * Since: 1.2
 */
void
graphene_triangle_get_normal (const graphene_triangle_t *t,
                              graphene_vec3_t           *res)
{
  graphene_vec3_t v1, v2, tmp;
  float length_sq;

  graphene_vec3_subtract (&t->c, &t->b, &v1);
  graphene_vec3_subtract (&t->a, &t->b, &v2);

  graphene_vec3_cross (&v1, &v2, &tmp);

  length_sq = graphene_vec3_dot (&tmp, &tmp);
  if (length_sq > 0)
    graphene_vec3_scale (&tmp, 1.f / sqrtf (length_sq), res);
  else
    graphene_vec3_init_from_vec3 (res, graphene_vec3_zero ());
}
Exemple #6
0
/**
 * graphene_ray_get_closest_point_to_point:
 * @r: a #graphene_ray_t
 * @p: a #graphene_point3d_t
 * @res: (out caller-allocates): return location for the closest point3d
 *
 * Computes the point on the given #graphene_ray_t that is closest to the
 * given point @p.
 *
 * Since: 1.4
 */
void
graphene_ray_get_closest_point_to_point (const graphene_ray_t     *r,
                                         const graphene_point3d_t *p,
                                         graphene_point3d_t       *res)
{
  graphene_vec3_t point, result;
  float distance;

  graphene_point3d_to_vec3 (p, &point);
  graphene_vec3_subtract (&point, &r->origin, &result);

  distance = graphene_vec3_dot (&result, &r->direction);
  if (distance < 0)
    graphene_vec3_init_from_vec3 (&result, &r->origin);
  else
    {
      graphene_vec3_scale (&r->direction, distance, &result);
      graphene_vec3_add (&result, &r->origin, &result);
    }

  graphene_point3d_init_from_vec3 (res, &result);
}