2013-11-11 12:56:39 +00:00
|
|
|
#include "Vector3.inline.cpp"
|
2013-11-09 17:46:34 +00:00
|
|
|
|
2013-11-11 12:56:39 +00:00
|
|
|
#include <cmath>
|
2013-11-09 17:46:34 +00:00
|
|
|
#include "PackStream.h"
|
2015-10-15 17:51:24 +00:00
|
|
|
#include "RandomGenerator.h"
|
2013-11-09 17:46:34 +00:00
|
|
|
|
2013-11-11 12:56:39 +00:00
|
|
|
const Vector3 paysages::basics::VECTOR_ZERO(0.0, 0.0, 0.0);
|
|
|
|
const Vector3 paysages::basics::VECTOR_DOWN(0.0, -1.0, 0.0);
|
|
|
|
const Vector3 paysages::basics::VECTOR_UP(0.0, 1.0, 0.0);
|
|
|
|
const Vector3 paysages::basics::VECTOR_NORTH(0.0, 0.0, -1.0);
|
|
|
|
const Vector3 paysages::basics::VECTOR_SOUTH(0.0, 0.0, 1.0);
|
|
|
|
const Vector3 paysages::basics::VECTOR_WEST(-1.0, 0.0, 0.0);
|
|
|
|
const Vector3 paysages::basics::VECTOR_EAST(1.0, 0.0, 0.0);
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
Vector3::Vector3(const VectorSpherical &v)
|
|
|
|
: x(v.r * cos(v.phi) * cos(v.theta)), y(v.r * sin(v.theta)), z(-v.r * sin(v.phi) * cos(v.theta)) {
|
2013-11-11 12:56:39 +00:00
|
|
|
}
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
void Vector3::save(PackStream *stream) const {
|
2013-11-11 12:56:39 +00:00
|
|
|
stream->write(&x);
|
|
|
|
stream->write(&y);
|
|
|
|
stream->write(&z);
|
|
|
|
}
|
2015-11-09 21:30:46 +00:00
|
|
|
void Vector3::load(PackStream *stream) {
|
2013-11-11 12:56:39 +00:00
|
|
|
stream->read(&x);
|
|
|
|
stream->read(&y);
|
|
|
|
stream->read(&z);
|
|
|
|
}
|
2013-11-09 17:46:34 +00:00
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
static inline double _euclidGet2DAngle(double x, double y) {
|
2013-11-09 17:46:34 +00:00
|
|
|
// TEMP Copy of old euclid.c
|
|
|
|
double nx, ny, d, ret;
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
if (x == 0.0) {
|
|
|
|
if (y == 0.0) {
|
2013-11-09 17:46:34 +00:00
|
|
|
return 0.0;
|
2015-11-09 21:30:46 +00:00
|
|
|
} else if (y < 0.0) {
|
2013-11-09 17:46:34 +00:00
|
|
|
return 3.0 * M_PI_2;
|
2015-11-09 21:30:46 +00:00
|
|
|
} else {
|
2013-11-09 17:46:34 +00:00
|
|
|
return M_PI_2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
d = sqrt(x * x + y * y);
|
|
|
|
nx = x / d;
|
|
|
|
ny = y / d;
|
|
|
|
|
|
|
|
ret = asin(ny);
|
2015-11-09 21:30:46 +00:00
|
|
|
if (nx < 0.0) {
|
2013-11-09 17:46:34 +00:00
|
|
|
ret = M_PI - ret;
|
|
|
|
}
|
|
|
|
return ret < 0.0 ? ret + 2.0 * M_PI : ret;
|
|
|
|
}
|
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
VectorSpherical Vector3::toSpherical() const {
|
2013-11-09 17:46:34 +00:00
|
|
|
VectorSpherical result;
|
|
|
|
|
2013-11-11 12:56:39 +00:00
|
|
|
result.phi = _euclidGet2DAngle(x, -z);
|
|
|
|
result.theta = _euclidGet2DAngle(sqrt(x * x + z * z), y);
|
2015-11-09 21:30:46 +00:00
|
|
|
if (y < 0.0) {
|
2013-11-09 17:46:34 +00:00
|
|
|
result.theta -= 2.0 * M_PI;
|
|
|
|
}
|
2013-11-11 12:56:39 +00:00
|
|
|
result.r = getNorm();
|
2013-11-09 17:46:34 +00:00
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
2015-10-08 17:20:44 +00:00
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
Vector3 Vector3::midPointTo(const Vector3 &other) const {
|
2015-10-08 17:20:44 +00:00
|
|
|
return Vector3((other.x + x) * 0.5, (other.y + y) * 0.5, (other.z + z) * 0.5);
|
|
|
|
}
|
2015-10-15 17:51:24 +00:00
|
|
|
|
2015-11-09 21:30:46 +00:00
|
|
|
Vector3 Vector3::randomInSphere(double radius, bool only_surface) {
|
2015-10-15 17:51:24 +00:00
|
|
|
// TODO More uniform spatial repartition
|
|
|
|
// The current randomization clusters result near the center and at the poles
|
2015-11-09 21:30:46 +00:00
|
|
|
VectorSpherical vec = {only_surface ? radius : RandomGenerator::random() * radius,
|
|
|
|
(RandomGenerator::random() - 0.5) * M_PI, RandomGenerator::random() * M_2PI};
|
2015-10-15 17:51:24 +00:00
|
|
|
return Vector3(vec);
|
|
|
|
}
|