175 lines
3.3 KiB
C++
175 lines
3.3 KiB
C++
#include "Curve.h"
|
|
|
|
#include <cstring>
|
|
#include "PackStream.h"
|
|
|
|
const int MAX_NB_POINTS = 30;
|
|
|
|
Curve::Curve()
|
|
{
|
|
nbpoints = 0;
|
|
default_value = 0.0;
|
|
points = new CurvePoint[MAX_NB_POINTS];
|
|
}
|
|
|
|
Curve::~Curve()
|
|
{
|
|
delete[] points;
|
|
}
|
|
|
|
void Curve::copy(Curve* destination) const
|
|
{
|
|
destination->nbpoints = nbpoints;
|
|
destination->default_value = default_value;
|
|
for (int i = 0; i < nbpoints; i++)
|
|
{
|
|
destination->points[i] = points[i];
|
|
}
|
|
}
|
|
|
|
void Curve::save(PackStream* stream) const
|
|
{
|
|
stream->write(&default_value);
|
|
stream->write(&nbpoints);
|
|
for (int i = 0; i < nbpoints; i++)
|
|
{
|
|
stream->write(&points[i].position);
|
|
stream->write(&points[i].value);
|
|
}
|
|
}
|
|
|
|
void Curve::load(PackStream* stream)
|
|
{
|
|
stream->read(&default_value);
|
|
stream->read(&nbpoints);
|
|
for (int i = 0; i < nbpoints; i++)
|
|
{
|
|
stream->read(&points[i].position);
|
|
stream->read(&points[i].value);
|
|
}
|
|
}
|
|
|
|
void Curve::clear()
|
|
{
|
|
nbpoints = 0;
|
|
}
|
|
|
|
void Curve::setDefault(double value)
|
|
{
|
|
default_value = value;
|
|
}
|
|
|
|
int Curve::addPoint(const CurvePoint &point)
|
|
{
|
|
if (nbpoints < MAX_NB_POINTS)
|
|
{
|
|
points[nbpoints] = point;
|
|
return nbpoints++;
|
|
}
|
|
else
|
|
{
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
int Curve::addPoint(double position, double value)
|
|
{
|
|
CurvePoint point = {position, value};
|
|
return addPoint(point);
|
|
}
|
|
|
|
CurvePoint Curve::getPoint(int number) const
|
|
{
|
|
if (number >= 0 && number < nbpoints)
|
|
{
|
|
return points[number];
|
|
}
|
|
else
|
|
{
|
|
return {0.0, 0.0};
|
|
}
|
|
}
|
|
|
|
bool Curve::getPoint(int number, CurvePoint *point) const
|
|
{
|
|
if (number >= 0 && number < nbpoints)
|
|
{
|
|
*point = points[number];
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
void Curve::setPoint(int number, const CurvePoint &point)
|
|
{
|
|
if (number >= 0 && number < nbpoints)
|
|
{
|
|
points[number] = point;
|
|
}
|
|
}
|
|
|
|
void Curve::removePoint(int number)
|
|
{
|
|
if (number >= 0 && number < nbpoints)
|
|
{
|
|
if (nbpoints > 0 && number < nbpoints - 1)
|
|
{
|
|
memmove(points + number, points + number + 1, sizeof(CurvePoint) * (nbpoints - number - 1));
|
|
}
|
|
nbpoints--;
|
|
}
|
|
}
|
|
|
|
int _point_compare(const void* part1, const void* part2)
|
|
{
|
|
if (((CurvePoint*)part1)->position > ((CurvePoint*)part2)->position)
|
|
{
|
|
return 1;
|
|
}
|
|
else
|
|
{
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
void Curve::validate()
|
|
{
|
|
if (nbpoints > 1)
|
|
{
|
|
qsort(points, nbpoints, sizeof(CurvePoint), _point_compare);
|
|
}
|
|
}
|
|
|
|
double Curve::getValue(double position) const
|
|
{
|
|
int i;
|
|
double fact;
|
|
|
|
if (nbpoints == 0)
|
|
{
|
|
return default_value;
|
|
}
|
|
else if (nbpoints == 1 || position <= points[0].position)
|
|
{
|
|
return points[0].value;
|
|
}
|
|
else if (position >= points[nbpoints - 1].position)
|
|
{
|
|
return points[nbpoints - 1].value;
|
|
}
|
|
else
|
|
{
|
|
for (i = 1; i < nbpoints; i++)
|
|
{
|
|
if (position < points[i].position)
|
|
{
|
|
fact = (position - points[i - 1].position) / (points[i].position - points[i - 1].position);
|
|
return points[i - 1].value + (points[i].value - points[i - 1].value) * fact;
|
|
}
|
|
}
|
|
return points[nbpoints - 1].value;
|
|
}
|
|
}
|