Commit 4ae59497 authored by cutealien's avatar cutealien

- line2d::getClosestPoint can now also get the closest point on the line...

- 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
parent f126da63
Changes in 1.8 (??.??.2011) 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. - 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). - 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).
......
...@@ -211,16 +211,23 @@ class line2d ...@@ -211,16 +211,23 @@ class line2d
} }
//! Get the closest point on this line to a point //! 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> c((f64)(point.X-start.X), (f64)(point.Y- start.Y));
vector2d<f64> v((f64)(end.X-start.X), (f64)(end.Y-start.Y)); vector2d<f64> v((f64)(end.X-start.X), (f64)(end.Y-start.Y));
f64 d = v.getLength(); f64 d = v.getLength();
if ( d == 0 ) // can't tell much when the line is just a single point
return start;
v /= d; v /= d;
f64 t = v.dotProduct(c); f64 t = v.dotProduct(c);
if ( checkOnlySegments )
{
if (t < 0) return vector2d<T>((T)start.X, (T)start.Y); if (t < 0) return vector2d<T>((T)start.X, (T)start.Y);
if (t > d) return vector2d<T>((T)end.X, (T)end.Y); if (t > d) return vector2d<T>((T)end.X, (T)end.Y);
}
v *= t; v *= t;
return vector2d<T>((T)(start.X + v.X), (T)(start.Y + v.Y)); return vector2d<T>((T)(start.X + v.X), (T)(start.Y + v.Y));
...@@ -232,18 +239,23 @@ class line2d ...@@ -232,18 +239,23 @@ class line2d
vector2d<T> end; vector2d<T> end;
}; };
// partial specialization to optimize <f32> lines // partial specialization to optimize <f32> lines (avoiding casts)
template <> 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 c = point - start;
vector2df v = end - start; vector2df v = end - start;
f32 d = (f32)v.getLength(); f32 d = (f32)v.getLength();
if ( d == 0 ) // can't tell much when the line is just a single point
return start;
v /= d; v /= d;
f32 t = v.dotProduct(c); f32 t = v.dotProduct(c);
if ( checkOnlySegments )
{
if (t < 0) return start; if (t < 0) return start;
if (t > d) return end; if (t > d) return end;
}
v *= t; v *= t;
return start + v; return start + v;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment