common: add DistToLineSegment

This commit is contained in:
Eric Wasylishen 2017-04-23 02:05:19 -06:00
parent ed09b4af8d
commit 3f067e001a
3 changed files with 33 additions and 1 deletions

View File

@ -667,3 +667,14 @@ float DistToLine(const glm::vec3 &v, const glm::vec3 &w, const glm::vec3& p)
return glm::distance(p, p_projected_on_vw);
}
float DistToLineSegment(const glm::vec3 &v, const glm::vec3 &w, const glm::vec3& p)
{
const float frac = FractionOfLine(v, w, p);
if (frac > 1)
return glm::distance(w, p);
if (frac < 0)
return glm::distance(v, p);
return DistToLine(v, w, p);
}

View File

@ -296,10 +296,16 @@ glm::vec3 GLM_PolyRandomPoint(const std::vector<glm::vec3> &points);
float FractionOfLine(const glm::vec3 &v, const glm::vec3 &w, const glm::vec3& p);
/**
* Distance from `p` to the line v<->w
* Distance from `p` to the line v<->w (extending infinitely in either direction)
*/
float DistToLine(const glm::vec3 &v, const glm::vec3 &w, const glm::vec3& p);
/**
* Distance from `p` to the line segment v<->w.
* i.e., 0 if `p` is between v and w.
*/
float DistToLineSegment(const glm::vec3 &v, const glm::vec3 &w, const glm::vec3& p);
// Returns weights for f(0,0), f(1,0), f(0,1), f(1,1)
// from: https://en.wikipedia.org/wiki/Bilinear_interpolation#Unit_Square
static inline glm::vec4 bilinearWeights(const float x, const float y) {

View File

@ -542,6 +542,21 @@ TEST(mathlib, DistToLine) {
ASSERT_TRUE(fabs(0.5 - DistToLine(vec3(10,0,0), vec3(10,0,100), vec3(9.5,0,0))) < epsilon);
}
TEST(mathlib, DistToLineSegment) {
const float epsilon = 0.001;
ASSERT_TRUE(fabs(0 - DistToLineSegment(vec3(0,0,0), vec3(1,1,1), vec3(0,0,0))) < epsilon);
ASSERT_TRUE(fabs(0 - DistToLineSegment(vec3(0,0,0), vec3(1,1,1), vec3(0.5, 0.5, 0.5))) < epsilon);
ASSERT_TRUE(fabs(0 - DistToLineSegment(vec3(0,0,0), vec3(1,1,1), vec3(1,1,1))) < epsilon);
ASSERT_TRUE(fabs(sqrt(3) - DistToLineSegment(vec3(0,0,0), vec3(1,1,1), vec3(2,2,2))) < epsilon);
ASSERT_TRUE(fabs(sqrt(3) - DistToLineSegment(vec3(0,0,0), vec3(1,1,1), vec3(-1,-1,-1))) < epsilon);
ASSERT_TRUE(fabs(sqrt(2)/2 - DistToLineSegment(vec3(0,0,0), vec3(1,1,0), vec3(0,1,0))) < epsilon);
ASSERT_TRUE(fabs(sqrt(2)/2 - DistToLineSegment(vec3(0,0,0), vec3(1,1,0), vec3(1,0,0))) < epsilon);
ASSERT_TRUE(fabs(0.5 - DistToLineSegment(vec3(10,0,0), vec3(10,0,100), vec3(9.5,0,0))) < epsilon);
}
// mesh_t
TEST(mathlib, meshCreate) {