Make love.math a singleton. Remove code duplication. Add love.math.triangulate.

love::math::Math is now a singleton, so other modules can use it via
love::math::Math::instance.


Removed duplicate implementations of various rng helper functions.
ParticleSystem now uses love::math::Math's RNG.


New function: love.math.triangulate(vertices)

Accepts a table or list of x/y coordinate pairs and returns a table of tables.
The inner tables are the triangles the polygon is composed of.

Works on all *simple* polygons, i.e. a closed chain of vertices that does not
intersect itself. Attempting to triangulate non-simple polygons is undefined
behavior - in the best case it throws an error, in the worst case it returns
an invalid triangulation.

Polygons must be ordered in *clockwise order* with respect to the love
coordinate system. Attempting to triangulate a ccw polygon will throw an
error.

Examples:

  triangles = love.math.triangulate(0,0, 1,1, 2,0, 2,2, 0,2)
  triangles == {
      {1,1, 2,0, 2,2},
      {1,1, 2,2, 0,2},
      {1,1, 0,2, 0,0},
  }

  triangles = love.math.triangulate({0,0, 1,1, 2,0, 2,2, 0,2})
  -- same as above

  triangles = love.math.triangulate(0,2, 2,2, 2,0, 1,1, 0,0)
  -- error - polygons is in counterclockwise order

  triangles = love.math.triangulate(0,0, 1,3, 2,0, 2,2, 0,2)
  -- undefined behavior - polygon intersects itself (because of edge 1,3)
This commit is contained in:
vrld
2013-03-13 20:48:39 +01:00
parent d383434edf
commit ece4ff6472
8 changed files with 347 additions and 185 deletions
-33
View File
@@ -1,33 +0,0 @@
#include "math.h"
#include <limits>
#include <cmath>
namespace
{
// The BoxMuller transform generates two random numbers, one of which we
// cache here. A value of +infinity is used to signal the cache is invalid
// and that new numbers have to be generated.
float last_randnormal = std::numeric_limits<float>::infinity();
}
namespace love
{
float random_normal(float o)
{
// number in cache?
if (last_randnormal != std::numeric_limits<float>::infinity())
{
float r = last_randnormal;
last_randnormal = std::numeric_limits<float>::infinity();
return r * o;
}
// else: generate numbers using the Box-Muller transform
float a = sqrt(-2.0f * log(1. - random()));
float b = float(LOVE_M_PI) * 2.0f * (1. - random());
last_randnormal = a * cos(b);
return a * sin(b) * o;
}
} // namespace love
+8 -36
View File
@@ -68,6 +68,14 @@ struct vertex
float s, t;
};
struct Triangle
{
Triangle(const vertex &x, const vertex &y, const vertex &z)
: a(x), b(y), c(z)
{}
vertex a, b, c;
};
inline int next_p2(int x)
{
x += (x == 0);
@@ -81,42 +89,6 @@ inline float next_p2(float x)
return static_cast<float>(next_p2(static_cast<int>(x)));
}
/**
* Draws a random number from a uniform distribution.
* @returns Uniformly distributed random number in [0:1).
*/
inline float random()
{
// to satisfy picky compilers...
return float(double(rand() % RAND_MAX) / double(RAND_MAX));
}
/**
* Draws a random number from a uniform distribution.
* @return Uniformly distributed random number in [0:max).
*/
inline float random(float max)
{
return random() * max;
}
/**
* Draws a random number from a uniform distribution.
* @return Uniformly distributed random number in [min:max).
*/
inline float random(float min, float max)
{
return random(max - min) + min;
}
/**
* Draws a random number from a normal/gaussian distribution.
* @param o Standard deviation of the distribution.
* @returns Normal distributed random number with mean 0 and variance o^2.
*/
float random_normal(float o = 1.);
#define random_gaussian random_normal
} // love
#endif // LOVE_MATH_H