12 : v{ x1, x2, x3, x4 } {}
21 return v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2] + v1[3] * v2[3];
30 : rows{ v1, v2, v3, v4 } {}
37 return Vector4(dot(rows[0], v), dot(rows[1], v), dot(rows[2], v), dot(rows[3], v));
42 { 1.f, 0.f, 0.f, 0.f },
43 { 0.f, 0.f, 1.f, 0.f },
44 { -3.f, 3.f, -2.f, -1.f },
45 { 2.f, -2.f, 1.f, 1.f },
53 return (p2.
y - p1.
y) / (p2.
x - p1.
x);
60 return lerp(getDerivative(p0, p1), getDerivative(p1, p2), d1 / (d1 + d2));
66 { { 0.f, 0.f },
true },
67 { { 1.f, 1.f },
true },
79 points.
resize(curve.size());
80 for (
Size i = 0; i < curve.size(); ++i) {
81 points[i] = std::make_pair(curve[i],
true);
91 points = curve.points.
clone();
100 return points[idx].first;
104 points[idx].first = newPoint;
109 auto iter = std::lower_bound(points.
begin(),
112 [](
const std::pair<CurvePoint, bool>& p,
const CurvePoint& q) { return p.first.x < q.x; });
113 if (iter == points.
end()) {
116 points.
insert(iter - points.
begin(), std::make_pair(newPoint, (iter - 1)->second));
121 if (points.
size() > 2) {
127 return points[idx].second;
131 points[idx].second = cubic;
136 for (
const auto& p : points) {
144 for (
const auto& p : points) {
151 auto lowerBoundIter = std::lower_bound(
152 points.
begin(), points.
end(), x, [](
const std::pair<CurvePoint, bool>& p,
const Float x) {
153 return p.first.x < x;
156 if (lowerBoundIter == points.
end() || lowerBoundIter == points.
begin()) {
159 idx = lowerBoundIter - points.
begin() - 1;
162 auto leftDy = [
this, idx] {
163 return points[idx - 1].second
164 ? getDerivative(points[idx - 1].first, points[idx].first, points[idx + 1].first)
165 : getDerivative(points[idx - 1].first, points[idx].first);
167 auto rightDy = [
this, idx] {
168 return points[idx + 1].second
169 ? getDerivative(points[idx].first, points[idx + 1].first, points[idx + 2].first)
170 : getDerivative(points[idx + 1].first, points[idx + 2].first);
173 if (points[idx].second && points.
size() > 2) {
175 return cubic(points[idx].first,
176 points[idx + 1].first,
177 getDerivative(points[idx].first, points[idx + 1].first),
180 }
else if (idx == points.
size() - 2) {
181 return cubic(points[idx].first,
182 points[idx + 1].first,
184 getDerivative(points[idx].first, points[idx + 1].first),
187 return cubic(points[idx].first, points[idx + 1].first, leftDy(), rightDy(), x);
190 return linear(points[idx].first, points[idx + 1].first, x);
195 return p1.
y + (x - p1.
x) / (p2.
x - p1.
x) * (p2.
y - p1.
y);
202 const Float x)
const {
204 const Float t = (x - p1.
x) / d;
206 const Vector4 ys(p1.
y, p2.
y, dy1 * d, dy2 * d);
211 std::sort(points.
begin(),
213 [](
const std::pair<CurvePoint, bool>& p1,
const std::pair<CurvePoint, bool>& p2) {
214 return p1.first.x < p2.first.x;
#define SPH_ASSERT(x,...)
const Matrix4 CURVE_MATRIX
uint32_t Size
Integral type used to index arrays (by default).
double Float
Precision used withing the code. Use Float instead of float or double where precision is important.
INLINE T lerp(const T v1, const T v2, const TAmount amount)
constexpr INLINE T sqr(const T &f) noexcept
Return a squared value.
INLINE T sqrt(const T f)
Return a squared root of a value.
constexpr INLINE Float pow< 3 >(const Float v)
constexpr INLINE Float pow< 2 >(const Float v)
#define INLINE
Macros for conditional compilation based on selected compiler.
#define NAMESPACE_SPH_END
Generic dynamically allocated resizable storage.
void resize(const TCounter newSize)
Resizes the array to new size.
INLINE Iterator< StorageType > end() noexcept
StorageType & emplaceBack(TArgs &&... args)
Constructs a new element at the end of the array in place, using the provided arguments.
void remove(const TCounter idx)
Removes an element with given index from the array.
void insert(const TCounter position, U &&value)
Inserts a new element to given position in the array.
INLINE TCounter size() const noexcept
INLINE Iterator< StorageType > begin() noexcept
Array clone() const
Performs a deep copy of all elements of the array.
Represents a user-defined function, defined by a set of points interpolated by either piecewise linea...
const CurvePoint & getPoint(const Size idx) const
Returns the position of idx-th point.
Interval rangeY() const
Returns the extent of the curve in y-direction.
Curve & operator=(const Curve &curve)
void setPoint(const Size idx, const CurvePoint &newPoint)
Modifies the position of idx-th points.
Size getPointCnt() const
Returns the number of points defining the curve.
void addPoint(const CurvePoint &newPoint)
Adds a new point to the curve.
void setSegment(const Size idx, const bool cubic)
Modifies the interpolation type of idx-th segment.
Interval rangeX() const
Returns the extent of the curve in x-direction.
Float operator()(const Float x) const
Evaluates the function and returns the result.
bool getSegment(const Size idx) const
Returns the interpolation type of idx-th segment.
Curve()
Creates an identity function, defined in interval [0, 1].
void deletePoint(const Size idx)
Removes idx-th point from curve.
Object representing a 1D interval of real numbers.
INLINE Float lower() const
Returns lower bound of the interval.
INLINE void extend(const Float &value)
Extends the interval to contain given value.
INLINE Float upper() const
Returns upper bound of the interval.
Vector4 row(const Size i) const
Vector4 operator*(const Vector4 &v) const
Matrix4(const Vector4 &v1, const Vector4 &v2, const Vector4 &v3, const Vector4 &v4)
INLINE Float operator[](const Size i) const
Vector4(const Float x1, const Float x2, const Float x3, const Float x4)