#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