paysages3d/src/basics/Curve.cpp
2016-07-23 22:58:32 +02:00

132 lines
3.1 KiB
C++

#include "Curve.h"
#include "PackStream.h"
#include <cstring>
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;
}
}