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

clamp(x, a, b)
Alias for: constrain
constrain(x, a, b) click to toggle source

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
Also aliased as: clamp
distance(x1, y1, x2, y2) click to toggle source

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
grayscale(val = nil) click to toggle source

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
lerp(a, b, amt) click to toggle source

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
map(value, a1, a2, b1, b2) click to toggle source

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
noise(x, y = 0) click to toggle source

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
normalize(value, a, b) click to toggle source

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
to_deg(angle) click to toggle source

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
to_rad(angle) click to toggle source

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

dot_grid_gradient(ix, iy, x, y) click to toggle source

@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
random_gradient(ix, iy) click to toggle source

@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