%%%------------------------------------------------------------------- %%% erlrithmetician - linear algebra library for Erlang %%% Copyright (C) 2026 E. G. Bland %%% %%% This program is free software: you can redistribute it and/or modify %%% it under the terms of the GNU General Public License as published by %%% the Free Software Foundation, either version 3 of the License, or %%% (at your option) any later version. %%% %%% This program is distributed in the hope that it will be useful, %%% but WITHOUT ANY WARRANTY; without even the implied warranty of %%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the %%% GNU General Public License for more details. %%% %%% You should have received a copy of the GNU General Public License %%% along with this program. If not, see . %%%------------------------------------------------------------------- -module(transform3d). -export([rotate_xy/1, rotate_xz/1, rotate_yz/1, rotate_axis/2, scale/3, translate/3]). -spec rotate_xy(number()) -> mat:mat(float()). -spec rotate_xz(number()) -> mat:mat(float()). -spec rotate_yz(number()) -> mat:mat(float()). -spec rotate_axis(vec:vec(number()), number()) -> mat:mat(float()). -spec scale(number(), number(), number()) -> mat:mat(number()). -spec translate(number(), number(), number()) -> mat:mat(number()). rotate_xy(Theta) -> Cos = math:cos(Theta), Sin = math:sin(Theta), mat:new(array:from_list([vec:new3(Cos, Sin, 0), vec:new3(-Sin, Cos, 0), vec:new3(0, 0, 1)])). rotate_xz(Theta) -> Cos = math:cos(Theta), Sin = math:sin(Theta), mat:new(array:from_list([vec:new3(Cos, 0, -Sin), vec:new3(0, 1, 0), vec:new3(Sin, 0, Cos)])). rotate_yz(Theta) -> Cos = math:cos(Theta), Sin = math:sin(Theta), mat:new(array:from_list([vec:new3(1, 0, 0), vec:new3(0, Cos, Sin), vec:new3(0, -Sin, Cos)])). rotate_axis(Axis, Theta) -> Dim = vec:dim(Axis), case Dim of 3 -> AxisNorm = vec:normalise(Axis), X = vec:x(AxisNorm), Y = vec:y(AxisNorm), Z = vec:z(AxisNorm), Cos = math:cos(Theta), Sin = math:sin(Theta), mat:new(array:from_list([ vec:new3( Cos + (1 - Cos) * X * X, (1 - Cos) * X * Y + Sin * Z, (1 - Cos) * X * Z - Sin * Y ), vec:new3( (1 - Cos) * X * Y - Sin * Z, Cos + (1 - Cos) * Y * Y, (1 - Cos) * Y * Z + Sin * X ), vec:new3( (1 - Cos) * X * Z + Sin * Y, (1 - Cos) * Y * Z - Sin * X, Cos + (1 - Cos) * Z * Z ) ])); _ -> error({ axis_not_3d, { axis_dim, Dim } }) end. scale(Sx, Sy, Sz) -> mat:new(array:from_list([vec:new3(Sx, 0, 0), vec:new3(0, Sy, 0), vec:new3(0, 0, Sz)])). translate(Tx, Ty, Tz) -> mat:new(array:from_list([vec:new4(1, 0, 0, 0), vec:new4(0, 1, 0, 0), vec:new4(0, 0, 1, 0), vec:new4(Tx, Ty, Tz, 1)])).