Current section

Files

Jump to
graphmath lib vec2 Vec2.ex
Raw

lib/vec2/Vec2.ex

defmodule Graphmath.Vec2 do
@moduledoc """
This is the 2D mathematics library for graphmath.
"""
@doc"""
`create_vec2` is used to create a 2d vector.
It takes a list of numbers and converts it into an array of form [x,y].
"""
@spec create_vec2() :: [float]
def create_vec2() do
[0,0]
end
@spec create_vec2([float]) :: [float]
def create_vec2 ( vec ) do
[x,y | _] = vec
[x,y]
end
@doc """
`add_vec2` is used to add a vec2 to another vec2.
It takes two vec2s and returns a vec2 which is the element-wise sum of those lists.
"""
@spec add_vec2( [float], [float]) :: [float]
def add_vec2( a, b) do
[ x,y | _] = a
[ u,v | _] = b
[ x+u, y+v ]
end
@doc """
`subtract_vec2` is used to subtract a vec2 from another vec2.
It takes two vec2s and returns the difference of the two.
"""
@spec subtract_vec2( [float], [float] ) :: [float]
def subtract_vec2( [x1, y1 | _], [x2,y2| _]) do
[x1-x2,y1-y2]
end
@doc """
`scale_vec2` is used to perform a scaling on a vec2.
Passing it a single number will cause all elements of the vec2 to be multipled by that number.
Passing it a vec2 will cause each element of to be multiplied by the corresponding element of the scale vec2.
"""
@spec scale_vec2( [float], [float] ) :: [float]
def scale_vec2( vec, [s1, s2 | _ ] ) do
[ x,y | _ ] = vec
[ x*s1, y * s2]
end
@spec scale_vec2( [float], float ) :: [float]
def scale_vec2( vec, scale ) do
[ x,y | _ ] = vec
[ x*scale, y*scale ]
end
@doc """
`dot_vec2` is used to find the inner product (dot product) of one vec2 and another.
Passing it two vec2s will cause it to return the inner product of those two vec2s.
"""
@spec dot_vec2( [float], [float] ) :: float
def dot_vec2( [x1,y1 |_ ], [x2,y2|_]) do
(x1*x2)+(y1*y2)
end
@doc """
`perp_prod_vec2` is used to find the perpindicular product of two vec2s.
The perpindicular product is the magnitude of the cross-product between the two vectors.
"""
@spec perp_prod_vec2( [float], [float] ) :: float
def perp_prod_vec2( [x1, y1 | _ ], [ x2,y2 | _ ] ) do
(x1*y2) -( x2*y1)
end
@doc """
`length_vec2` is used to find the length (L2 norm) of a vector.
The length is the square root of the sum of the squares.
"""
@spec length_vec2( [float] ) :: float
def length_vec2( [x1, y1 | _ ] ) do
:math.sqrt( (x1*x1) + (y1*y1) )
end
@doc """
`length_squared_vec2` is used to find the square of the length of a vector.
In many cases, this is sufficient for comparisions and avaoids a sqrt.
"""
@spec length_squared_vec2( [float] ) :: float
def length_squared_vec2( [ x1, y1 | _ ] ) do
(x1*x1) + (y1*y1)
end
@doc """
`length_manhatten_vec2` is used to find the Manhattan (L1 norm) length of a vector.
The Manhattan length is simply the sum of the components.
"""
@spec length_manhattan_vec2( [float] ) :: float
def length_manhattan_vec2( [x1, y1| _ ]) do
x1 + y1
end
@doc """
`normalize_vec2` is used to find the unit vector with the same direction as the supplied vector.
This is done by dividing each component by the vector's magnitude.
"""
@spec normalize_vec2( [float] ) :: [float]
def normalize_vec2( [x1, y1 | _ ] ) do
imag = 1 / :math.sqrt( (x1*x1) + (y1*y1) )
[x1 * imag, y1 * imag]
end
@doc """
`lerp_vec2` is used to linearly interpolate between two given vectors.
The interpolant is on the domain [0,1]. Behavior outside of that is undefined.
"""
@spec lerp_vec2( [float], [float], float) :: [float]
def lerp_vec2( [x1, y1 | _ ], [x2,y2| _], t ) do
[ ( t * x2) + ( (1-t) *x1 ), (t * y2) + ( (1-t) *y1)]
end
@doc """
`rotate_vec2` is used to rotate a vec CCW about the +Z axis a given number of radians.
"""
@spec rotate_vec2( [float], float) :: [float]
def rotate_vec2( [ x1, y1 | _ ], theta) do
ct = :math.cos(theta)
st = :math.sin(theta)
[ x1*ct + y1*st, x1*st - y1*ct]
end
@doc """
`compare_vec2` is used to check whether or not two vectors are within a length of each other.
"""
@spec compare_vec2( [float], [float], float) :: boolean
def compare_vec2( [x1,y1|_], [x2, y2 | _ ], l) do
dx = x2-x1
dy = y2-y1
l > :math.sqrt( dx*dx + dy*dy )
end
@doc """
`project_vec2` projects one vector onto another, and returns the resulting image.
"""
@spec project_vec2( [float], [float]) :: [float]
def project_vec2( [x1,y1|_], [x2,y2|_] ) do
coeff = ((x1*x2) +(y1*y2)) / (x2*x2 + y2*y2)
[x2*coeff, y2*coeff]
end
end