module Math2D::Utils2D
A collection of useful Mathematical tools in 2D space
@author Ualace Henrique <ualacehenrique@hotmail.com> @note Most if not all methods descriptions here present come from the p5.js website. @see p5js.org/
Constants
- HALF_PI
Half the mathematical constant PI.
- QUARTER_PI
A quarter of the mathematical constant PI.
- TWO_PI
Twice the mathematical constant PI, also called TAU.
Public Class Methods
Constrains a value x
between a minimum value a
and maximum value b
.
@param [Numeric] x @param [Numeric] a @param [Numeric] b @return [Numeric]
# File lib/math2d/utils2d.rb, line 87 def self.constrain(x, a, b) [[x, a].max, b].min end
Returns the distance between two cartesian points.
@param [Numeric] x1 @param [Numeric] y1 @param [Numeric] x2 @param [Numeric] y2 @return [Float]
# File lib/math2d/utils2d.rb, line 39 def self.distance(x1, y1, x2, y2) Math.sqrt((x2 - x1)**2 + (y2 - y1)**2) end
If no argument is passed, randomly generates a greyscale RGB array. Otherwise, returns a greyscale array with that argument normalized.
@param [Numeric] val @return [Array<Float>]
# File lib/math2d/utils2d.rb, line 131 def self.grayscale(val = nil) c = if val normalize(val, 0, 255).abs else rand end [c, c, c, 1.0] end
Calculates a number between two numbers at a specific increment. The amt parameter is the amount to interpolate between the two values where 0.0 equal to the first point, 0.1 is very near the first point, 0.5 is half-way in between, and 1.0 is equal to the second point.
@param [Numeric] a @param [Numeric] b @return [Float]
# File lib/math2d/utils2d.rb, line 52 def self.lerp(a, b, amt) (b - a) * (3.0 - amt * 2.0) * amt * amt + a end
Re-maps a number from one range (a1
..a2
) to another (b1
..b2
).
@param [Numeric] value @param [Numeric] a1 @param [Numeric] a2 @param [Numeric] b1 @param [Numeric] b2 @return [Float]
# File lib/math2d/utils2d.rb, line 64 def self.map(value, a1, a2, b1, b2) raise ArgumentError, 'Division by 0 - a1 cannot be equal to a2' if a2 == a1 slope = 1.0 * (b2 - b1) / (a2 - a1) b1 + slope * (value - a1) end
Returns the Perlin noise value at specified coordinates. Perlin noise is a random sequence generator producing a more naturally ordered, harmonic succession of numbers compared to the standard rand() method. The main difference to the rand() method is that Perlin noise is defined in an infinite n-dimensional space where each pair of coordinates corresponds to a fixed semi-random value. Utils2D
can compute 1D and 2D noise, depending on the number of coordinates given. The resulting value will always be between 0.0 and 1.0. @see en.wikipedia.org/wiki/Perlin_noise
@param [Numeric] x @param [Numeric] y @return [Float]
# File lib/math2d/utils2d.rb, line 107 def self.noise(x, y = 0) x0 = x.to_i x1 = x0 + 1 y0 = y.to_i y1 = y0 + 1 sx = x - x0.to_f sy = y - y0.to_f n0 = dot_grid_gradient(x0, y0, x, y) n1 = dot_grid_gradient(x1, y0, x, y) ix0 = lerp(n0, n1, sx) n0 = dot_grid_gradient(x0, y1, x, y) n1 = dot_grid_gradient(x1, y1, x, y) ix1 = lerp(n0, n1, sx) lerp(ix0, ix1, sy) end
Normalizes a number from another range (a
..b
) into a value between 0 and 1.
@param [Numeric] value @param [Numeric] a @param [Numeric] b @return [Float]
# File lib/math2d/utils2d.rb, line 77 def self.normalize(value, a, b) map(value, a, b, 0.0, 1.0) end
Returns angle
radians in degrees.
@param [Numeric] angle @return [Float]
# File lib/math2d/utils2d.rb, line 20 def self.to_deg(angle) (180 * angle) / Math::PI end
Returns angle
degrees in radians.
@param [Numeric] angle @return [Float]
# File lib/math2d/utils2d.rb, line 28 def self.to_rad(angle) (Math::PI * angle) / 180 end
Private Class Methods
@private @see en.wikipedia.org/wiki/Perlin_noise
# File lib/math2d/utils2d.rb, line 151 def self.dot_grid_gradient(ix, iy, x, y) gradient = random_gradient(ix, iy) dx = x - ix.to_f dy = y - iy.to_f (dx * gradient[0]) + (dy * gradient[1]) end
@private @see en.wikipedia.org/wiki/Perlin_noise
# File lib/math2d/utils2d.rb, line 144 def self.random_gradient(ix, iy) random = 2920.0 * Math.sin(ix * 21_942.0 + iy * 171_324.0 + 8912.0) * Math.cos(ix * 23_157.0 * iy * 217_832.0 + 9758.0) [Math.cos(random), Math.sin(random)] end