- line2d::getClosestPoint can now also get the closest point on the line additional to only checking for closest point on the line-segment.

- Avoid division by zero in line2d::getClosestPoint when start- and endpoint are identical.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@4112 dfc29bdd-3216-0410-991c-e03cc46cb475
master
cutealien 2012-03-21 15:13:41 +00:00
parent f126da6308
commit 4ae5949756
2 changed files with 23 additions and 7 deletions

View File

@ -1,5 +1,9 @@
Changes in 1.8 (??.??.2011)
- line2d::getClosestPoint can now also get the closest point on the line additional to only checking for closest point on the line-segment.
- avoid division by zero in line2d::getClosestPoint when start- and endpoint are identical
- Support for better collada texture wrapping support on loading.
- XML-reader now ignores all whitespace-only EXN_TEXT elements as old way didn't work in cross-platform way (and arguably also not well on Windows).

View File

@ -211,16 +211,23 @@ class line2d
}
//! Get the closest point on this line to a point
vector2d<T> getClosestPoint(const vector2d<T>& point) const
/** \param checkOnlySegments: Default (true) is to return a point on the line-segment (between begin and end) of the line.
When set to false the function will check for the first the closest point on the the line even when outside the segment. */
vector2d<T> getClosestPoint(const vector2d<T>& point, bool checkOnlySegments=true) const
{
vector2d<f64> c((f64)(point.X-start.X), (f64)(point.Y- start.Y));
vector2d<f64> v((f64)(end.X-start.X), (f64)(end.Y-start.Y));
f64 d = v.getLength();
if ( d == 0 ) // can't tell much when the line is just a single point
return start;
v /= d;
f64 t = v.dotProduct(c);
if ( checkOnlySegments )
{
if (t < 0) return vector2d<T>((T)start.X, (T)start.Y);
if (t > d) return vector2d<T>((T)end.X, (T)end.Y);
}
v *= t;
return vector2d<T>((T)(start.X + v.X), (T)(start.Y + v.Y));
@ -232,18 +239,23 @@ class line2d
vector2d<T> end;
};
// partial specialization to optimize <f32> lines
// partial specialization to optimize <f32> lines (avoiding casts)
template <>
inline vector2df line2d<irr::f32>::getClosestPoint(const vector2df& point) const
inline vector2df line2d<irr::f32>::getClosestPoint(const vector2df& point, bool checkOnlySegments) const
{
vector2df c = point - start;
vector2df v = end - start;
f32 d = (f32)v.getLength();
if ( d == 0 ) // can't tell much when the line is just a single point
return start;
v /= d;
f32 t = v.dotProduct(c);
if ( checkOnlySegments )
{
if (t < 0) return start;
if (t > d) return end;
}
v *= t;
return start + v;