Files
Webcam/include/framework/geometry/geometric_tools.cpp

123 lines
3.2 KiB
C++

/* -----------------------------------------------------------------------------
GSFramework
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */
#include <cmath>
#include "geometry/geometric_tools.h"
namespace GS {
namespace Geometric {
//------------------------------------------------------------------------------
float TriArea2D(float x0, float y0, float x1, float y1, float x2, float y2)
{ return (x0 - x1) * (y1 - y2) - (x1 - x2) * (y0 - y1); }
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void Barycentric(const Vector4 &a, const Vector4 &b, const Vector4 &c, const Vector4 &p, float &u, float &v, float &w)
{
Vector4 m = (b - a).Cross(c - a);
float nu, nv, ood;
float x = fabs(m.x), y = fabs(m.y), z = fabs(m.z);
if (x >= y && x >= z)
{
nu = TriArea2D(p.y, p.z, b.y, b.z, c.y, c.z);
nv = TriArea2D(p.y, p.z, c.y, c.z, a.y, a.z);
ood = 1.f / m.x;
}
else if (y >= x && y >= z)
{
nu = TriArea2D(p.x, p.z, b.x, b.z, c.x, c.z);
nv = TriArea2D(p.x, p.z, c.x, c.z, a.x, a.z);
ood = 1.f / -m.y;
}
else
{
nu = TriArea2D(p.x, p.y, b.x, b.y, c.x, c.y);
nv = TriArea2D(p.x, p.y, c.x, c.y, a.x, a.y);
ood = 1.f / m.z;
}
u = nu * ood;
v = nv * ood;
w = 1.f - u - v;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
bool LineIntersectPlane(const Vector4 &a, const Vector4 &v, const Vector4 &n, const Vector4 &p, float &t)
{
float k = v.Dot(n);
if (Math::EqualZero(k))
return false;
t = (p.Dot(n) - a.Dot(n)) / k;
return true;
}
bool LineIntersectSphere(const Vector4 &a, const Vector4 &v, const Vector4 &c, float r, float t[2])
{
Vector4 e = c - a;
float k = e.Dot(v);
float d = r * r - (e.Len2() - k * k);
if (d < 0)
return false;
d = Math::Sqrt(d);
if (t)
{
t[0] = k - d;
t[1] = k + d;
}
return true;
}
float LineClosestPoint(const Vector4 &a, const Vector4 &b, const Vector4 &u, Vector4 *p)
{
Vector4 _u = u - a;
Vector4 _v = b - a;
float t = _u.Dot(_v) / _v.Dot(_v);
if (p)
p[0] = _v * t + a;
return t;
}
bool LineClosestPointToLine(const Vector4 &a, const Vector4 &b, const Vector4 &la, const Vector4 &lb, float t[2])
{
Vector4 u = b - a, v = lb - la;
float ul2 = u.Len2(), vl2 = v.Len2();
float d = u.Dot(v), k = ul2 * vl2 - d * d;
if (fabs(k) < 0.00000001f)
return false;
k = 1.f / k;
float uv = d, du = (la - a).Dot(u), dv = (a - la).Dot(v);
t[0] = (vl2 * du + uv * dv) * k;
t[1] = (uv * du + ul2 * dv) * k;
return true;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
float SegmentClosestPoint(const Vector4 &a, const Vector4 &b, const Vector4 &u, Vector4 *p)
{
Vector4 _u = u - a, _v = b - a;
float t = Types::Clamp(_u.Dot(_v) / _v.Dot(_v));
if (p)
p[0] = _v * t + a;
return t;
}
//------------------------------------------------------------------------------
} // Geometric
} // GS