Refectored PI constants definitions + added Maths::modInRange

This commit is contained in:
Michaël Lemaire 2015-12-31 00:36:22 +01:00
parent 92ec8bf9b3
commit dbcaf5fe90
15 changed files with 118 additions and 66 deletions

View file

@ -1,6 +1,7 @@
#include "Geometry.h"
#include <cmath>
#include "Maths.h"
#include "Vector3.h"
double Geometry::get2DAngle(double x, double y) {
@ -10,9 +11,9 @@ double Geometry::get2DAngle(double x, double y) {
if (y == 0.0) {
return 0.0;
} else if (y < 0.0) {
return 3.0 * M_PI_2;
return 3.0 * Maths::PI_2;
} else {
return M_PI_2;
return Maths::PI_2;
}
}
@ -22,9 +23,9 @@ double Geometry::get2DAngle(double x, double y) {
ret = asin(ny);
if (nx < 0.0) {
ret = M_PI - ret;
ret = Maths::PI - ret;
}
return ret < 0.0 ? ret + 2.0 * M_PI : ret;
return ret < 0.0 ? ret + 2.0 * Maths::PI : ret;
}
Vector3 Geometry::getNormalFromTriangle(const Vector3 &center, const Vector3 &bottom, const Vector3 &right) {

14
src/basics/Maths.cpp Normal file
View file

@ -0,0 +1,14 @@
#include "Maths.h"
#include <cmath>
double Maths::modInRange(double value, double min, double max) {
double size = max - min;
if (size < 0.0000000000001) {
return value;
} else {
double norm = (value - min) / size;
double modulo = norm - floor(norm);
return modulo * size + min;
}
}

27
src/basics/Maths.h Normal file
View file

@ -0,0 +1,27 @@
#ifndef MATHS_H
#define MATHS_H
#include "basics_global.h"
namespace paysages {
namespace basics {
/**
* Basic math utilities.
*/
class BASICSSHARED_EXPORT Maths {
public:
/**
* Constraint a value in the [min,max[ range, by applying a modulo.
*/
static double modInRange(double value, double min, double max);
static constexpr double PI = 3.141592653589793238462643383279;
static constexpr double PI_2 = PI / 2.0;
static constexpr double PI_4 = PI / 4.0;
static constexpr double TWOPI = 2.0 * PI;
};
}
}
#endif // MATHS_H

View file

@ -1,6 +1,7 @@
#include "Vector3.h"
#include <cmath>
#include "Maths.h"
#include "PackStream.h"
#include "RandomGenerator.h"
@ -80,9 +81,9 @@ static inline double _euclidGet2DAngle(double x, double y) {
if (y == 0.0) {
return 0.0;
} else if (y < 0.0) {
return 3.0 * M_PI_2;
return 3.0 * Maths::PI_2;
} else {
return M_PI_2;
return Maths::PI_2;
}
}
@ -92,9 +93,9 @@ static inline double _euclidGet2DAngle(double x, double y) {
ret = asin(ny);
if (nx < 0.0) {
ret = M_PI - ret;
ret = Maths::PI - ret;
}
return ret < 0.0 ? ret + 2.0 * M_PI : ret;
return ret < 0.0 ? ret + 2.0 * Maths::PI : ret;
}
VectorSpherical Vector3::toSpherical() const {
@ -103,7 +104,7 @@ VectorSpherical Vector3::toSpherical() const {
result.phi = _euclidGet2DAngle(x, -z);
result.theta = _euclidGet2DAngle(sqrt(x * x + z * z), y);
if (y < 0.0) {
result.theta -= 2.0 * M_PI;
result.theta -= 2.0 * Maths::PI;
}
result.r = getNorm();
@ -117,7 +118,7 @@ Vector3 Vector3::midPointTo(const Vector3 &other) const {
Vector3 Vector3::randomInSphere(double radius, bool only_surface, RandomGenerator &random) {
// TODO More uniform spatial repartition
// The current randomization clusters result near the center and at the poles
VectorSpherical vec = {only_surface ? radius : random.genDouble() * radius, (random.genDouble() - 0.5) * M_PI,
random.genDouble() * M_2PI};
VectorSpherical vec = {only_surface ? radius : random.genDouble() * radius, (random.genDouble() - 0.5) * Maths::PI,
random.genDouble() * Maths::TWOPI};
return Vector3(vec);
}

View file

@ -33,18 +33,4 @@ class InfinitePlane;
}
using namespace paysages::basics;
// Some useful constants
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
#ifndef M_PI_2
#define M_PI_2 1.57079632679489661923
#endif
#ifndef M_PI_4
#define M_PI_4 0.78539816339744830962
#endif
#ifndef M_2PI
#define M_2PI 6.28318530717958647692
#endif
#endif // BASICS_GLOBAL_H

View file

@ -1,6 +1,7 @@
#include "AtmosphereDefinition.h"
#include <cmath>
#include "Maths.h"
#include "PackStream.h"
#include "RandomGenerator.h"
#include "FloatNode.h"
@ -70,7 +71,7 @@ void AtmosphereDefinition::copy(DefinitionNode *_destination) const {
}
void AtmosphereDefinition::setDayTime(double value) {
sun->propTheta()->setValue((value + 0.75) * M_2PI);
sun->propTheta()->setValue((value + 0.75) * Maths::TWOPI);
}
void AtmosphereDefinition::setDayTime(int hour, int minute, int second) {
@ -78,7 +79,7 @@ void AtmosphereDefinition::setDayTime(int hour, int minute, int second) {
}
double AtmosphereDefinition::getDaytime() const {
double value = (sun->propTheta()->getValue() / M_2PI) - 0.75;
double value = (sun->propTheta()->getValue() / Maths::TWOPI) - 0.75;
if (value >= 0.0) {
value = fmod(value, 1.0);
} else {

View file

@ -1,5 +1,6 @@
#include "VegetationModelDefinition.h"
#include "Maths.h"
#include "VegetationDefinition.h"
#include "RandomGenerator.h"
#include "Matrix4.h"
@ -115,7 +116,7 @@ static void addBranchRecurse(RandomGenerator &random, vector<CappedCylinder> &br
Vector3 new_direction = pivot1.multPoint(direction);
for (int i = 0; i < split_count; i++) {
Matrix4 pivot2 = Matrix4::newRotateAxis(
randomizeValue(random, M_PI * 2.0 / to_double(split_count), 0.9, 1.1), direction);
randomizeValue(random, Maths::PI * 2.0 / to_double(split_count), 0.9, 1.1), direction);
new_direction = pivot2.multPoint(new_direction);
Vector3 new_base = base.add(direction.scale(randomizeValue(random, length, 0.4, 1.0)));

View file

@ -1,6 +1,7 @@
#include "OpenGLRenderer.h"
#include <QMatrix4x4>
#include "Maths.h"
#include "OpenGLFunctions.h"
#include "CameraDefinition.h"
#include "OpenGLSharedState.h"
@ -249,7 +250,8 @@ void OpenGLRenderer::cameraChangeEvent(CameraDefinition *camera) {
QMatrix4x4 projection;
projection.setToIdentity();
projection.perspective(perspective.yfov * 180.0 / M_PI, perspective.xratio, perspective.znear, perspective.zfar);
projection.perspective(perspective.yfov * 180.0 / Maths::PI, perspective.xratio, perspective.znear,
perspective.zfar);
*view_matrix = projection *transform;

View file

@ -1,6 +1,7 @@
#include "OpenGLVegetationImpostor.h"
#include <cassert>
#include "Maths.h"
#include "OpenGLShaderProgram.h"
#include "OpenGLSharedState.h"
#include "OpenGLVertexArray.h"
@ -21,11 +22,11 @@
// Get the rotation matrix for an impostor grid index
static inline Matrix4 matrixForIndex(int index) {
if (index == 0) {
return Matrix4::newRotateZ(M_PI_2);
return Matrix4::newRotateZ(Maths::PI_2);
} else if (index < 6) {
return Matrix4::newRotateY(M_2PI * to_double(index - 1) * 0.2).mult(Matrix4::newRotateZ(M_PI_4));
return Matrix4::newRotateY(Maths::TWOPI * to_double(index - 1) * 0.2).mult(Matrix4::newRotateZ(Maths::PI_4));
} else {
return Matrix4::newRotateY(M_2PI * to_double(index - 6) * 0.1);
return Matrix4::newRotateY(Maths::TWOPI * to_double(index - 6) * 0.1);
}
}
@ -119,7 +120,7 @@ int OpenGLVegetationImpostor::getIndex(const Vector3 &camera, const Vector3 &ins
if (diff.theta > 1.0) {
return 0;
} else {
double angle = diff.phi / M_2PI;
double angle = diff.phi / Maths::TWOPI;
if (diff.theta > 0.4) {
angle = (angle >= 0.9) ? 0.0 : (angle + 0.1);
return 1 + trunc_to_int(5.0 * angle);

View file

@ -9,6 +9,7 @@
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include "Maths.h"
#include "System.h"
#include "ParallelWork.h"
#include "PackStream.h"
@ -196,13 +197,13 @@ static Color _texture4D(Texture4D *tex, double r, double mu, double muS, double
/* Rayleigh phase function */
static double _phaseFunctionR(double mu) {
return (3.0 / (16.0 * M_PI)) * (1.0 + mu * mu);
return (3.0 / (16.0 * Maths::PI)) * (1.0 + mu * mu);
}
/* Mie phase function */
static double _phaseFunctionM(double mu) {
return 1.5 * 1.0 / (4.0 * M_PI) * (1.0 - mieG * mieG) * pow(1.0 + (mieG * mieG) - 2.0 * mieG * mu, -3.0 / 2.0) *
(1.0 + mu * mu) / (2.0 + mieG * mieG);
return 1.5 * 1.0 / (4.0 * Maths::PI) * (1.0 - mieG * mieG) *
pow(1.0 + (mieG * mieG) - 2.0 * mieG * mu, -3.0 / 2.0) * (1.0 + mu * mu) / (2.0 + mieG * mieG);
}
/* approximated single Mie scattering (cf. approximate Cm in paragraph "Angular precision") */
@ -512,8 +513,8 @@ static Color _inscatterS(double r, double mu, double muS, double nu, int first,
Texture4D *deltaSM) {
Color raymie = COLOR_BLACK;
double dphi = M_PI / to_double(INSCATTER_SPHERICAL_INTEGRAL_SAMPLES);
double dtheta = M_PI / to_double(INSCATTER_SPHERICAL_INTEGRAL_SAMPLES);
double dphi = Maths::PI / to_double(INSCATTER_SPHERICAL_INTEGRAL_SAMPLES);
double dtheta = Maths::PI / to_double(INSCATTER_SPHERICAL_INTEGRAL_SAMPLES);
r = clamp(r, Rg, Rt);
mu = clamp(mu, -1.0, 1.0);
@ -539,7 +540,7 @@ static Color _inscatterS(double r, double mu, double muS, double nu, int first,
if (ctheta < cthetamin) {
/* if ground visible in direction w
* compute transparency gtransp between x and ground */
greflectance = AVERAGE_GROUND_REFLECTANCE / M_PI;
greflectance = AVERAGE_GROUND_REFLECTANCE / Maths::PI;
dground = -r * ctheta - sqrt(r * r * (ctheta * ctheta - 1.0) + Rg * Rg);
gtransp = _transmittance3(Rg, -(r * ctheta + dground) / Rg, dground);
}
@ -634,8 +635,8 @@ static int _jWorker(ParallelWork *, int layer, void *data) {
void _irradianceNProg(Texture2D *destination, Texture4D *deltaSR, Texture4D *deltaSM, int first) {
int x, y;
double dphi = M_PI / to_double(IRRADIANCE_INTEGRAL_SAMPLES);
double dtheta = M_PI / to_double(IRRADIANCE_INTEGRAL_SAMPLES);
double dphi = Maths::PI / to_double(IRRADIANCE_INTEGRAL_SAMPLES);
double dtheta = Maths::PI / to_double(IRRADIANCE_INTEGRAL_SAMPLES);
for (x = 0; x < SKY_W; x++) {
for (y = 0; y < SKY_H; y++) {
double r, muS;
@ -868,7 +869,7 @@ static Color _sunColor(Vector3 v, Vector3 s, double r, double mu, double radius)
Color transmittance = r <= Rt ? _transmittanceWithShadow(r, mu) : COLOR_WHITE; /* T(x,xo) */
double d = _limit(r, mu);
radius *= (1.0 + 15.0 * d / Rt); /* Inflating due to lens effect near horizon */
double isun = step(cos(radius * M_PI / 180.0), v.dotProduct(s)) * ISun; /* Lsun */
double isun = step(cos(radius * Maths::PI / 180.0), v.dotProduct(s)) * ISun; /* Lsun */
transmittance.r *= isun;
transmittance.g *= isun;
transmittance.b *= isun;

View file

@ -1,6 +1,7 @@
#include "SkyRasterizer.h"
#include <cmath>
#include "Maths.h"
#include "Vector3.h"
#include "Color.h"
#include "SoftwareRenderer.h"
@ -29,8 +30,8 @@ void SkyRasterizer::rasterizeToCanvas(CanvasPortion *canvas) {
Vector3 vertex1, vertex2, vertex3, vertex4;
Vector3 camera_location, direction;
step_i = M_PI * 2.0 / to_double(res_i);
step_j = M_PI / to_double(res_j);
step_i = Maths::PI * 2.0 / to_double(res_i);
step_j = Maths::PI / to_double(res_j);
camera_location = renderer->getCameraLocation(VECTOR_ZERO);

View file

@ -1,6 +1,7 @@
#include "BaseTestCase.h"
#include <cmath>
#include "Maths.h"
#include "SoftwareRenderer.h"
#include "CloudLayerDefinition.h"
#include "NoiseGenerator.h"
@ -186,7 +187,7 @@ TEST(Clouds, WalkingBoundaries)
static double _getLayerDensitySinX(Renderer*, CloudLayerDefinition*, Vector3 location)
{
double density = sin(location.x * (2.0 * M_PI));
double density = sin(location.x * (2.0 * Maths::PI));
return (density > 0.0) ? density : 0.0;
}

View file

@ -1,6 +1,7 @@
#include "BaseTestCase.h"
#include <cmath>
#include "Maths.h"
#include "Geometry.h"
#include "Vector3.h"
@ -23,22 +24,22 @@ TEST(Euclid, get2DAngle) {
EXPECT_DOUBLE_EQ(Geometry::get2DAngle(1.0, 0.0), 0.0);
EXPECT_DOUBLE_EQ(Geometry::get2DAngle(2.0, 0.0), 0.0);
EXPECT_DOUBLE_EQ(Geometry::get2DAngle(0.0, 0.1), M_PI_2);
EXPECT_DOUBLE_EQ(Geometry::get2DAngle(0.0, 1.0), M_PI_2);
EXPECT_DOUBLE_EQ(Geometry::get2DAngle(0.0, 2.0), M_PI_2);
EXPECT_DOUBLE_EQ(Geometry::get2DAngle(0.0, 0.1), Maths::PI_2);
EXPECT_DOUBLE_EQ(Geometry::get2DAngle(0.0, 1.0), Maths::PI_2);
EXPECT_DOUBLE_EQ(Geometry::get2DAngle(0.0, 2.0), Maths::PI_2);
EXPECT_DOUBLE_EQ(Geometry::get2DAngle(-0.1, 0.0), M_PI);
EXPECT_DOUBLE_EQ(Geometry::get2DAngle(-1.0, 0.0), M_PI);
EXPECT_DOUBLE_EQ(Geometry::get2DAngle(-2.0, 0.0), M_PI);
EXPECT_DOUBLE_EQ(Geometry::get2DAngle(-0.1, 0.0), Maths::PI);
EXPECT_DOUBLE_EQ(Geometry::get2DAngle(-1.0, 0.0), Maths::PI);
EXPECT_DOUBLE_EQ(Geometry::get2DAngle(-2.0, 0.0), Maths::PI);
EXPECT_DOUBLE_EQ(Geometry::get2DAngle(0.0, -0.1), 3.0 * M_PI_2);
EXPECT_DOUBLE_EQ(Geometry::get2DAngle(0.0, -1.0), 3.0 * M_PI_2);
EXPECT_DOUBLE_EQ(Geometry::get2DAngle(0.0, -2.0), 3.0 * M_PI_2);
EXPECT_DOUBLE_EQ(Geometry::get2DAngle(0.0, -0.1), 3.0 * Maths::PI_2);
EXPECT_DOUBLE_EQ(Geometry::get2DAngle(0.0, -1.0), 3.0 * Maths::PI_2);
EXPECT_DOUBLE_EQ(Geometry::get2DAngle(0.0, -2.0), 3.0 * Maths::PI_2);
EXPECT_DOUBLE_EQ(Geometry::get2DAngle(0.5, 0.5), M_PI_4);
EXPECT_DOUBLE_EQ(Geometry::get2DAngle(0.5, -0.5), 7.0 * M_PI_4);
EXPECT_DOUBLE_EQ(Geometry::get2DAngle(-0.5, 0.5), 3.0 * M_PI_4);
EXPECT_DOUBLE_EQ(Geometry::get2DAngle(-0.5, -0.5), 5.0 * M_PI_4);
EXPECT_DOUBLE_EQ(Geometry::get2DAngle(0.5, 0.5), Maths::PI_4);
EXPECT_DOUBLE_EQ(Geometry::get2DAngle(0.5, -0.5), 7.0 * Maths::PI_4);
EXPECT_DOUBLE_EQ(Geometry::get2DAngle(-0.5, 0.5), 3.0 * Maths::PI_4);
EXPECT_DOUBLE_EQ(Geometry::get2DAngle(-0.5, -0.5), 5.0 * Maths::PI_4);
}
/*TEST(Euclid, Vector3)
@ -85,7 +86,7 @@ TEST(Euclid, VectorSpherical) {
v1.z = 0.0;
v2 = v1.toSpherical();
EXPECT_DOUBLE_EQ(v2.r, 1.0);
EXPECT_DOUBLE_EQ(v2.phi, M_PI);
EXPECT_DOUBLE_EQ(v2.phi, Maths::PI);
EXPECT_DOUBLE_EQ(v2.theta, 0.0);
v1.x = 0.0;
@ -94,7 +95,7 @@ TEST(Euclid, VectorSpherical) {
v2 = v1.toSpherical();
EXPECT_DOUBLE_EQ(v2.r, 1.0);
EXPECT_DOUBLE_EQ(v2.phi, 0.0);
EXPECT_DOUBLE_EQ(v2.theta, M_PI_2);
EXPECT_DOUBLE_EQ(v2.theta, Maths::PI_2);
v1.x = 0.0;
v1.y = -1.0;
@ -102,14 +103,14 @@ TEST(Euclid, VectorSpherical) {
v2 = v1.toSpherical();
EXPECT_DOUBLE_EQ(v2.r, 1.0);
EXPECT_DOUBLE_EQ(v2.phi, 0.0);
EXPECT_DOUBLE_EQ(v2.theta, -M_PI_2);
EXPECT_DOUBLE_EQ(v2.theta, -Maths::PI_2);
v1.x = 0.0;
v1.y = 0.0;
v1.z = 1.0;
v2 = v1.toSpherical();
EXPECT_DOUBLE_EQ(v2.r, 1.0);
EXPECT_DOUBLE_EQ(v2.phi, 3.0 * M_PI_2);
EXPECT_DOUBLE_EQ(v2.phi, 3.0 * Maths::PI_2);
EXPECT_DOUBLE_EQ(v2.theta, 0.0);
v1.x = 0.0;
@ -117,12 +118,12 @@ TEST(Euclid, VectorSpherical) {
v1.z = -1.0;
v2 = v1.toSpherical();
EXPECT_DOUBLE_EQ(v2.r, 1.0);
EXPECT_DOUBLE_EQ(v2.phi, M_PI_2);
EXPECT_DOUBLE_EQ(v2.phi, Maths::PI_2);
EXPECT_DOUBLE_EQ(v2.theta, 0.0);
v1.x = v1.y = v1.z = 0.5;
v2 = v1.toSpherical();
EXPECT_DOUBLE_EQ(v2.r, sqrt(0.5 * 0.5 + 0.5 * 0.5 + 0.5 * 0.5));
EXPECT_DOUBLE_EQ(v2.phi, 7.0 * M_PI_4);
EXPECT_DOUBLE_EQ(v2.theta, M_PI_2 - 0.955316618125);
EXPECT_DOUBLE_EQ(v2.phi, 7.0 * Maths::PI_4);
EXPECT_DOUBLE_EQ(v2.theta, Maths::PI_2 - 0.955316618125);
}

13
src/tests/Maths_Test.cpp Normal file
View file

@ -0,0 +1,13 @@
#include "BaseTestCase.h"
#include "Maths.h"
TEST(Maths, modInRange) {
EXPECT_DOUBLE_EQ(0.7, Maths::modInRange(-0.3, 0.0, 1.0));
EXPECT_DOUBLE_EQ(0.0, Maths::modInRange(0.0, 0.0, 1.0));
EXPECT_DOUBLE_EQ(0.4, Maths::modInRange(0.4, 0.0, 1.0));
EXPECT_DOUBLE_EQ(0.0, Maths::modInRange(1.0, 0.0, 1.0));
EXPECT_DOUBLE_EQ(0.5, Maths::modInRange(1.5, 0.0, 1.0));
EXPECT_DOUBLE_EQ(5.2831853071795862, Maths::modInRange(-1.0, 0, Maths::TWOPI));
EXPECT_DOUBLE_EQ(-1.183185307179586, Maths::modInRange(5.1, -Maths::PI, Maths::PI));
}

View file

@ -1,6 +1,7 @@
#include "BaseTestCase.h"
#include <cmath>
#include "Maths.h"
#include "NoiseGenerator.h"
#include "TerrainDefinition.h"
#include "TerrainHeightMap.h"
@ -8,7 +9,7 @@
#include "FloatNode.h"
/* Noise sin period is defined at 20.0 */
#define X_FACTOR (M_PI / 10.0)
#define X_FACTOR (Maths::PI / 10.0)
static double _noise1dMock(double x) {
return sin(x * X_FACTOR) * 0.5 + 0.5;