#pragma region CPL License /* Nuclex Native Framework Copyright (C) 2002-2015 Nuclex Development Labs This library is free software; you can redistribute it and/or modify it under the terms of the IBM Common Public License as published by the IBM Corporation; either version 1.0 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the IBM Common Public License for more details. You should have received a copy of the IBM Common Public License along with this library */ #pragma endregion // CPL License #ifndef NUCLEX_GEOMETRY_LINES_INTERPOLATORS_CURVE2INTERPOLATOR_H #define NUCLEX_GEOMETRY_LINES_INTERPOLATORS_CURVE2INTERPOLATOR_H #include "Nuclex/Geometry/Config.h" #include "Nuclex/Geometry/Lines/Curve2.h" #include "Nuclex/Geometry/Lines/Interpolators/NearestInterpolator.h" #include "Nuclex/Geometry/Lines/Interpolators/LinearInterpolator.h" #include "Nuclex/Geometry/Lines/Interpolators/CosineInterpolator.h" #include "Nuclex/Geometry/Lines/Interpolators/CubicInterpolator.h" namespace Nuclex { namespace Geometry { namespace Lines { namespace Interpolators { // ------------------------------------------------------------------------------------------- // /// Interpolates along the vertices of a 2D curve /// Type of values used to store the curve's vertices template struct Curve2Interpolator { #pragma region struct Point2VertexTraits /// Vertex traits for Point2 types when used in interpolators private: struct Point2VertexTraits { /// Type that is used to measure distance between vertices public: typedef TScalar TDistance; // Type that is used to specify the interpolation interval //public: typedef TScalar TScalar; /// A vertex with a value of zero public: static const Point2 ZeroVertex; /// Measures the distance between two vertices /// First vertex for the distance calculation /// Second vertex for the distance calculation /// The distance between the two vertices public: static TDistance DistanceBetween( const Point2 &first, const Point2 &second ) { return Point2::DistanceBetween(first, second); } /// Sums a point with another point /// Point to which another point wlll be added /// Other point that will be added to the point public: static void Add(Point2 &base, Point2 amount) { base.X += amount.X; base.Y += amount.Y; } /// Subtracts another point from a point /// Point from which another point wlll be subtracted /// Other point that will be substracted from the point public: static void Subtract(Point2 &base, Point2 amount) { base.X -= amount.X; base.Y -= amount.Y; } /// Scales a point by a factor /// Point that will be scaled by a factor /// Factor the point will be scaled by public: static void Scale(Point2 &base, TScalar factor) { base.X *= factor; base.Y *= factor; } /// Rounds a scalar / interval value to the closest integer /// Scalar / interval value that will be rounded /// The closest integer to the specified scalar / interval value public: static std::size_t RoundScalarToInteger(TScalar t) { return static_cast(t + 0.5); } /// Truncates a scalar / interval value to the next lower integer /// Scalar / interval value that will be truncated /// The next lower integer to the specified scalar / interval value public: static std::size_t TruncateScalarToInteger(float t) { return static_cast(t); } }; #pragma endregion // struct Point2VertexTraits /// Interpolator that searches for the nearest vertex public: typedef Interpolators::NearestInterpolator< Point2, Point2VertexTraits > NearestInterpolatorType; /// Interpolator that linearly interpolates along a path public: typedef Interpolators::LinearInterpolator< Point2, Point2VertexTraits > LinearInterpolatorType; /// Interpolator that uses cosine interpolation along a path public: typedef Interpolators::CosineInterpolator< Point2, Point2VertexTraits > CosineInterpolatorType; /// Interpolator that uses cubic interpolation along a path public: typedef Interpolators::CubicInterpolator< Point2, Point2VertexTraits > CubicInterpolatorType; /// Interpolates a point along the curve /// Time at which the point will be interpolated /// The point at the specified time public: static Point2 InterpolateByTime(const Curve2 &curve, TScalar t) { switch(curve.InterpolationMethod) { case CurveInterpolationMethod::Closest: { return NearestInterpolatorType::InterpolateByTime( curve.Vertices.begin(), curve.Vertices.end(), t ); } case CurveInterpolationMethod::Linear: { return LinearInterpolatorType::InterpolateByTime( curve.Vertices.begin(), curve.Vertices.end(), t ); } case CurveInterpolationMethod::Cosine: { return CosineInterpolatorType::InterpolateByTime( curve.Vertices.begin(), curve.Vertices.end(), t ); } case CurveInterpolationMethod::Cubic: { return CubicInterpolatorType::InterpolateByTime( curve.Vertices.begin(), curve.Vertices.end(), t ); } default: { throw std::runtime_error("Unknown interpolation method"); } } } /// Estimates the length of the curve /// The estimated length of the curve public: static TScalar EstimateLength(const Curve2 &curve) { switch(curve.InterpolationMethod) { case CurveInterpolationMethod::Closest: { return NearestInterpolatorType::EstimateLength( curve.Vertices.begin(), curve.Vertices.end() ); } case CurveInterpolationMethod::Linear: { return LinearInterpolatorType::EstimateLength( curve.Vertices.begin(), curve.Vertices.end() ); } case CurveInterpolationMethod::Cosine: { return CosineInterpolatorType::EstimateLength( curve.Vertices.begin(), curve.Vertices.end() ); } case CurveInterpolationMethod::Cubic: { return CubicInterpolatorType::EstimateLength( curve.Vertices.begin(), curve.Vertices.end() ); } default: { throw std::runtime_error("Unknown interpolation method"); } } } }; // ------------------------------------------------------------------------------------------- // template const Point2 Curve2Interpolator::Point2VertexTraits::ZeroVertex(0, 0); // ------------------------------------------------------------------------------------------- // }}}} // namespace Nuclex::Geometry::Lines::Interpolators #endif // NUCLEX_GEOMETRY_LINES_INTERPOLATORS_CURVE2INTERPOLATOR_H