-module(matrix@mat2f). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/matrix/mat2f.gleam"). -export([new/4, from_cols/2, from_diagonal/1, from_scale_angle/2, from_angle/1, transpose/1, diagonal/1, determinant/1, inverse/1, mul_vec2/2, mul_transpose_vec2/2, negate/1, absolute_value/1, add/2, subtract/2, multiply/2, divide/2, scale/2, scale_diagonal/2, reciprocal/1, sum/1, product/1]). -if(?OTP_RELEASE >= 27). -define(MODULEDOC(Str), -moduledoc(Str)). -define(DOC(Str), -doc(Str)). -else. -define(MODULEDOC(Str), -compile([])). -define(DOC(Str), -compile([])). -endif. ?MODULEDOC(" 2x2 matrices of floats\n"). -file("src/matrix/mat2f.gleam", 25). ?DOC( " Constructs a `Mat2f` from its components:\n" " ```text\n" " | a c |\n" " | b d |\n" " ```\n" ). -spec new(float(), float(), float(), float()) -> vec@vec2:vec2(vec@vec2:vec2(float())). new(A, B, C, D) -> {vec2, {vec2, A, B}, {vec2, C, D}}. -file("src/matrix/mat2f.gleam", 34). ?DOC( " Constructs a `Mat2f` from its two columns.\n" " ```text\n" " | ax bx |\n" " | ay by |\n" " ```\n" ). -spec from_cols(vec@vec2:vec2(float()), vec@vec2:vec2(float())) -> vec@vec2:vec2(vec@vec2:vec2(float())). from_cols(A, B) -> {vec2, A, B}. -file("src/matrix/mat2f.gleam", 43). ?DOC( " Constructs a `Mat2f` with the given diagonal and all other entries set to 0.\n" " ```text\n" " | x 0.0 |\n" " | 0.0 y |\n" " ```\n" ). -spec from_diagonal(vec@vec2:vec2(float())) -> vec@vec2:vec2(vec@vec2:vec2(float())). from_diagonal(Diag) -> new(erlang:element(2, Diag), +0.0, +0.0, erlang:element(3, Diag)). -file("src/matrix/mat2f.gleam", 48). ?DOC(" Constructs a `Mat2f` from scale factor (as a `Vec2f`) and a rotation in radians.\n"). -spec from_scale_angle(vec@vec2:vec2(float()), float()) -> vec@vec2:vec2(vec@vec2:vec2(float())). from_scale_angle(Scale, Angle) -> Sin = gleam_community@maths:sin(Angle), Cos = gleam_community@maths:cos(Angle), new( Cos * erlang:element(2, Scale), Sin * erlang:element(2, Scale), (-1.0 * Sin) * erlang:element(3, Scale), Cos * erlang:element(3, Scale) ). -file("src/matrix/mat2f.gleam", 55). ?DOC(" Constructs a `Mat2f` from a rotation angle in radians.\n"). -spec from_angle(float()) -> vec@vec2:vec2(vec@vec2:vec2(float())). from_angle(Angle) -> Sin = gleam_community@maths:sin(Angle), Cos = gleam_community@maths:cos(Angle), new(Cos, Sin, -1.0 * Sin, Cos). -file("src/matrix/mat2f.gleam", 62). ?DOC(" Transposes the `Mat2f` along the diagonal.\n"). -spec transpose(vec@vec2:vec2(vec@vec2:vec2(float()))) -> vec@vec2:vec2(vec@vec2:vec2(float())). transpose(Mat) -> new( erlang:element(2, erlang:element(2, Mat)), erlang:element(2, erlang:element(3, Mat)), erlang:element(3, erlang:element(2, Mat)), erlang:element(3, erlang:element(3, Mat)) ). -file("src/matrix/mat2f.gleam", 67). ?DOC(" Returns the diagonal of the `Mat2f`\n"). -spec diagonal(vec@vec2:vec2(vec@vec2:vec2(float()))) -> vec@vec2:vec2(float()). diagonal(Mat) -> {vec2, erlang:element(2, erlang:element(2, Mat)), erlang:element(3, erlang:element(3, Mat))}. -file("src/matrix/mat2f.gleam", 72). ?DOC(" Returns the determinant for the `Mat2f`.\n"). -spec determinant(vec@vec2:vec2(vec@vec2:vec2(float()))) -> float(). determinant(Mat) -> (erlang:element(2, erlang:element(2, Mat)) * erlang:element( 3, erlang:element(3, Mat) )) - (erlang:element(3, erlang:element(2, Mat)) * erlang:element( 2, erlang:element(3, Mat) )). -file("src/matrix/mat2f.gleam", 77). ?DOC(" Inverts the `Mat2f`, returning an error if the determinant is zero.\n"). -spec inverse(vec@vec2:vec2(vec@vec2:vec2(float()))) -> {ok, vec@vec2:vec2(vec@vec2:vec2(float()))} | {error, nil}. inverse(Mat) -> gleam@result:map( gleam@float:divide(1.0, determinant(Mat)), fun(Inv_det) -> new( erlang:element(3, erlang:element(3, Mat)) * Inv_det, (erlang:element(3, erlang:element(2, Mat)) * Inv_det) * -1.0, (erlang:element(2, erlang:element(3, Mat)) * Inv_det) * -1.0, erlang:element(2, erlang:element(2, Mat)) * Inv_det ) end ). -file("src/matrix/mat2f.gleam", 88). ?DOC(" Transforms a `Vec2f` by this `Mat2f`.\n"). -spec mul_vec2(vec@vec2:vec2(vec@vec2:vec2(float())), vec@vec2:vec2(float())) -> vec@vec2:vec2(float()). mul_vec2(Mat, Rhs) -> {vec2, (erlang:element(2, erlang:element(2, Mat)) * erlang:element(2, Rhs)) + (erlang:element( 2, erlang:element(3, Mat) ) * erlang:element(3, Rhs)), (erlang:element(3, erlang:element(2, Mat)) * erlang:element(2, Rhs)) + (erlang:element( 3, erlang:element(3, Mat) ) * erlang:element(3, Rhs))}. -file("src/matrix/mat2f.gleam", 96). ?DOC(" Transforms a `Vec2f` by the transpose of this `Mat2f`.\n"). -spec mul_transpose_vec2( vec@vec2:vec2(vec@vec2:vec2(float())), vec@vec2:vec2(float()) ) -> vec@vec2:vec2(float()). mul_transpose_vec2(Mat, Rhs) -> vec@vec2:map(Mat, fun(_capture) -> vec@vec2f:dot(_capture, Rhs) end). -file("src/matrix/mat2f.gleam", 101). ?DOC(" Negates all elements of the `Mat2f`\n"). -spec negate(vec@vec2:vec2(vec@vec2:vec2(float()))) -> vec@vec2:vec2(vec@vec2:vec2(float())). negate(Mat) -> vec@vec2:map(Mat, fun vec@vec2f:negate/1). -file("src/matrix/mat2f.gleam", 106). ?DOC(" Takes the absolute value of each element in the `Mat2f`.\n"). -spec absolute_value(vec@vec2:vec2(vec@vec2:vec2(float()))) -> vec@vec2:vec2(vec@vec2:vec2(float())). absolute_value(Mat) -> vec@vec2:map(Mat, fun vec@vec2f:absolute_value/1). -file("src/matrix/mat2f.gleam", 111). ?DOC(" Adds two `Mat2f` together.\n"). -spec add( vec@vec2:vec2(vec@vec2:vec2(float())), vec@vec2:vec2(vec@vec2:vec2(float())) ) -> vec@vec2:vec2(vec@vec2:vec2(float())). add(A, B) -> vec@vec2:map2(A, B, fun vec@vec2f:add/2). -file("src/matrix/mat2f.gleam", 116). ?DOC(" Subtracts one `Mat2f` from the other.\n"). -spec subtract( vec@vec2:vec2(vec@vec2:vec2(float())), vec@vec2:vec2(vec@vec2:vec2(float())) ) -> vec@vec2:vec2(vec@vec2:vec2(float())). subtract(A, B) -> vec@vec2:map2(A, B, fun vec@vec2f:subtract/2). -file("src/matrix/mat2f.gleam", 121). ?DOC(" Multiplies two `Mat2f` together.\n"). -spec multiply( vec@vec2:vec2(vec@vec2:vec2(float())), vec@vec2:vec2(vec@vec2:vec2(float())) ) -> vec@vec2:vec2(vec@vec2:vec2(float())). multiply(A, B) -> vec@vec2:map(B, fun(_capture) -> mul_vec2(A, _capture) end). -file("src/matrix/mat2f.gleam", 126). ?DOC(" Divides one `Mat2f` by another. Equivalent to multiplying the inverse of the second matrix.\n"). -spec divide( vec@vec2:vec2(vec@vec2:vec2(float())), vec@vec2:vec2(vec@vec2:vec2(float())) ) -> {ok, vec@vec2:vec2(vec@vec2:vec2(float()))} | {error, nil}. divide(A, B) -> gleam@result:map(inverse(B), fun(Inv_b) -> multiply(A, Inv_b) end). -file("src/matrix/mat2f.gleam", 132). ?DOC(" Scales the `Mat2f` by a `Float` factor.\n"). -spec scale(vec@vec2:vec2(vec@vec2:vec2(float())), float()) -> vec@vec2:vec2(vec@vec2:vec2(float())). scale(Mat, Scale) -> vec@vec2:map(Mat, fun(_capture) -> vec@vec2f:scale(_capture, Scale) end). -file("src/matrix/mat2f.gleam", 139). ?DOC( " Scales the `Mat2f` by a `Vec2f`.\n" "\n" " This is faster than creating a diagonal scaling matrix and then multiplying that.\n" ). -spec scale_diagonal( vec@vec2:vec2(vec@vec2:vec2(float())), vec@vec2:vec2(float()) ) -> vec@vec2:vec2(vec@vec2:vec2(float())). scale_diagonal(Mat, Scale) -> vec@vec2:map2(Mat, Scale, fun vec@vec2f:scale/2). -file("src/matrix/mat2f.gleam", 146). ?DOC( " Returns a matrix containing the reciprocal of each element of the `Mat2f`.\n" "\n" " If any of the elements is zero, an error is returned.\n" ). -spec reciprocal(vec@vec2:vec2(vec@vec2:vec2(float()))) -> {ok, vec@vec2:vec2(vec@vec2:vec2(float()))} | {error, nil}. reciprocal(Mat) -> _pipe@2 = vec@vec2:map(Mat, fun(Column) -> _pipe = Column, _pipe@1 = vec@vec2:map( _pipe, fun(_capture) -> gleam@float:divide(1.0, _capture) end ), vec@vec2:result(_pipe@1) end), vec@vec2:result(_pipe@2). -file("src/matrix/mat2f.gleam", 156). ?DOC(" Sums a list of `Mat2f`s.\n"). -spec sum(list(vec@vec2:vec2(vec@vec2:vec2(float())))) -> vec@vec2:vec2(vec@vec2:vec2(float())). sum(Mats) -> gleam@list:fold( Mats, {vec2, {vec2, +0.0, +0.0}, {vec2, +0.0, +0.0}}, fun add/2 ). -file("src/matrix/mat2f.gleam", 161). ?DOC(" Multiplies a list of `Mat2f`s.\n"). -spec product(list(vec@vec2:vec2(vec@vec2:vec2(float())))) -> vec@vec2:vec2(vec@vec2:vec2(float())). product(Mats) -> gleam@list:fold( Mats, {vec2, {vec2, 1.0, +0.0}, {vec2, +0.0, 1.0}}, fun multiply/2 ).