why is my double pendulum programm isn't working in p5js? - p5.js

var angle1 = 45;
var angle2 = 0;
var L1 = 200;var L2 = 200;
var m1 = 1;
var m2 = 1;
var angleV1 = 0;
var angleV2 = 0;
var g = 1;
var angleA1 =
((-g * (2 * m1 + m2) * sin(angle1) -
m2 * g * sin(angle1 - angle2) -
2 *
sin(angle1 - angle2) *
m2 *
(angleV2 * angleV2 * L2 +
angleV1 * angleV1 * L1 * cos(angle1 - angle2))) /
L1) *
(2 * m1 + m2 - m2 * cos(2 * angle1 - 2 * angle2));
var angleA2 =
((2 *
sin(angle1 - angle2) *
(angleV1 * angleV1 * L1 * (m1 + m2) +
g * (m1 + m2) * cos(angle1) +
angle2 * angle2 * L2 * m2 * cos(angle1 - angle2))) /
L2) *
(2 * m1 + m2 - m2 * cos(2 * angle1 - 2 * angle2));
angleV1 += angleA1;
angle1 += angleV1;
angleV2 += angleA2;
angle2 += angleV2;
var x1 = sin(angle1) * L1;
var y1 = cos(angle1) * L1;
var x2 = x1 + sin(angle2) * L2;
var y2 = y1 + cos(angle2) * L2;
line(0, 0, x1, y1);
line(x1, y1, x2, y2);

Related

Deriving an unknown matrix in an equation

I'm working on reverse-engineering a software system doing some computer graphics math. I've wound up in a weird situation where the following math is coming up:
M * X * M^-1 * A = B
Where M is a 3x3 constant invertible matrix, M^-1 is the inverse of M, X is a 3x3 matrix I can control, A is a 3x1 column vector I can also control. B is measurable.
How can I find what M is? I'm pretty sure that I could find the answer by expanding out all matrix components algebraically into a few massive equations - but it sure feels like there should be a more straightforward mechanism.
This looks like the Eigendecomposition of a matrix.
where the matrix A is decomposed into a diagonal matrix Λ and a vector of eigenvectors Q.
In your case you have
C = (M X M-1)
If you can confirm that indeed X in your case is a diagonal matrix, then you know M to be the eigenvectors of C. You can get C from C = A-1 B
As far as finding the eigenvectors, even for 3×3 matrices, is a genuinely hard problem. Typically you do a Shur Decomposition and recover the eigevectors.
I did find an online resource for the 3×3 problem, which I ported into C# for an other project. Original source here.
/// <summary>
/// Calculates the three eigenvalues analytically.
/// </summary>
/// <remarks>
/// Code taken from:
/// https://www.mpi-hd.mpg.de/personalhomes/globes/3x3/index.html
/// </remarks>
/// <returns>A vector containing the three eigenvalues.</returns>
public Vector3 GetEigenValues()
{
// Determine coefficients of characteristic polynomial. We write
// | A D F |
// A = | D* B E |
// | F* E* C |
var de = data.m_12 * data.m_23;
var dd = data.m_12 * data.m_12;
var ee = data.m_23 * data.m_23;
var ff = data.m_13 * data.m_13;
var m = data.m_11 + data.m_22 + data.m_33;
var c1 = (data.m_11 * data.m_22 + data.m_11 * data.m_33 + data.m_22 * data.m_33) - (dd + ee + ff);
var c0 = data.m_33 * dd + data.m_11 * ee + data.m_22 * ff - data.m_11 * data.m_22 * data.m_33 - 2.0 * data.m_13 * de;
var p = m * m - 3.0 * c1;
var q = m * (p - (3.0 / 2.0) * c1) - (27.0 / 2.0) * c0;
var sqrt_p = (float) Math.Sqrt(Math.Abs(p));
var sqrt_z = (float) Math.Sqrt(Math.Abs(27.0 * (0.25 * c1 * c1 * (p - c1) + c0 * (q + 27.0 / 4.0 * c0))));
var phi = (1 / 3f) * (float) Math.Atan2(sqrt_z, q);
var c = sqrt_p * (float) Math.Cos(phi);
var s = sqrt_p * (float)( Math.Abs(Math.Sin(phi))/ Math.Sqrt(3));
var w = (1 / 3f) * (m - c);
// sort the eigenvalues
if (c >= s)
{
return new Vector3(
w - s,
w + s,
w + c);
}
else if (c >= -s)
{
return new Vector3(
w - s,
w + c,
w + s);
}
else
{
return new Vector3(
w + c,
w - s,
w + s);
}
}
public Matrix3 GetEigenVectors() => GetEigenVectors(GetEigenValues());
public Matrix3 GetEigenVectors(Vector3 eigenValues)
{
Vector3 ev1 = GetEigenVector(eigenValues.X).Unit();
Vector3 ev2 = GetEigenVector(eigenValues.Y).Unit();
Vector3 ev3 = GetEigenVector(eigenValues.Z).Unit();
return FromColumns(ev1, ev2, ev3);
}
Vector3 GetEigenVector(float w)
{
return new Vector3(
data.m_12 * (data.m_23 - data.m_33 + w) - data.m_13 * (data.m_22 - data.m_23 - w)
+ data.m_22 * (data.m_33 - w) - data.m_23 * data.m_23 - w * (data.m_33 - w),
-data.m_11 * (data.m_23 - data.m_33 + w) + data.m_12 * (data.m_13 - data.m_33 + w)
- data.m_13 * data.m_13 + data.m_13 * data.m_23 + w * (data.m_23 - data.m_33 + w),
data.m_11 * (data.m_22 - data.m_23 - w) - data.m_12 * data.m_12 + data.m_12 * (data.m_13 + data.m_23)
+ data.m_13 * (w - data.m_22) - w * (data.m_22 - data.m_23 - w));
}
For your case you would do M=C.GetEigenVectors();
A final note here is that you can scale M up or down by a factor, and it wont change the equation since you are multiplying with M and M-1 at the same time. So you just need to find just one of the infinite matrices M that would make this equation work.

Rotate an image with bicubic interpolation without imrotate

I have implemented a code for image warping using bilinear interpolation:
Matlab image rotation
I would like to improve the code by using bicubic interpolation to rotate the image WITHOUT using the built-in functions like imrotate or imwarp and interp functions in MATLAB.
I successfully managed to implement a full working example.
Code is based on Anna1994's code: Matlab image rotation
Biqubic code is also based on Java (and C++) implementation posted here: http://www.paulinternet.nl/?page=bicubic
The following code applies image rotation example using biqubic interpolation:
function BicubicInterpolationTest()
close all;
% clear all;
img = 'cameraman.tif';
input_image =double(imread(img))./255;
H=size(input_image,1); % height
W=size(input_image,2); % width
th=120*pi/180; %Rotate 120 degrees
s0 = 2;
s1 = 2;
x0 = -W/2;
x1 = -H/2;
T=[1 0 x0 ; ...
0 1 x1 ; ...
0 0 1];
RST = [ (s0*cos(th)) (-s1*sin(th)) ((s0*x0*cos(th))-(s1*x1*sin(th))); ...
(s0*sin(th)) (s1*cos(th)) ((s0*x0*sin(th))+(s1*x1*cos(th))); ...
0 0 1];
M=inv(T)*RST;
N = inv(M);
output_image=zeros(H,W,size(input_image,3));
for i=1:W
for j=1:H
x = [i ; j ; 1];
y = N * x;
a = y(1)/y(3);
b = y(2)/y(3);
%Nearest neighbor
% a = round(a);
% b = round(b);
%Bilinear interpolation (applies RGB image):
% x1 = floor(a);
% y1 = floor(b);
% x2 = x1 + 1;
% y2 = y1 + 1;
% if ((x1 >= 1) && (y1 >= 1) && (x2 <= W) && (y2 <= H))
% %Load 2x2 pixels
% i11 = input_image(y1, x1, :); %Top left pixel
% i21 = input_image(y2, x1, :); %Bottom left pixel
% i12 = input_image(y1, x2, :); %Top right pixel
% i22 = input_image(y2, x2, :); %Bottom right pixel
%
% %Interpolation wieghts
% dx = x2 - a;
% dy = y2 - b;
%
% %Bi-lienar interpolation
% output_image(j, i, :) = i11*dx*dy + i21*dx*(1-dy) + i12*(1-dx)*dy + i22*(1-dx)*(1-dy);
% end
x1 = floor(a);
y1 = floor(b);
%Bicubic interpolation (applies grayscale image)
if ((x1 >= 2) && (y1 >= 2) && (x1 <= W-2) && (y1 <= H-2))
%Load 4x4 pixels
P = input_image(y1-1:y1+2, x1-1:x1+2);
%Interpolation wieghts
dx = a - x1;
dy = b - y1;
%Bi-bicubic interpolation
output_image(j, i) = bicubicInterpolate(P, dx, dy);
end
end
end
imshow(output_image);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Verify implementation by comparing with Matalb build in function imwarp:
tform = affine2d(M');
ref_image = imwarp(input_image, tform, 'OutputView', imref2d(size(input_image)), 'Interp', 'cubic');
figure;imshow(ref_image)
figure;imshow(output_image - ref_image)
max_diff = max(abs(output_image(:) - ref_image(:)));
disp(['Maximum difference from imwarp = ', num2str(max_diff)]);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%http://www.paulinternet.nl/?page=bicubic
%double cubicInterpolate (double p[4], double x) {
% return p[1] + 0.5 * x*(p[2] - p[0] + x*(2.0*p[0] - 5.0*p[1] + 4.0*p[2] - p[3] + x*(3.0*(p[1] - p[2]) + p[3] - p[0])));
%}
function q = cubicInterpolate(p, x)
q = p(2) + 0.5 * x*(p(3) - p(1) + x*(2.0*p(1) - 5.0*p(2) + 4.0*p(3) - p(4) + x*(3.0*(p(2) - p(3)) + p(4) - p(1))));
%http://www.paulinternet.nl/?page=bicubic
% double bicubicInterpolate (double p[4][4], double x, double y) {
% double arr[4];
% arr[0] = cubicInterpolate(p[0], y);
% arr[1] = cubicInterpolate(p[1], y);
% arr[2] = cubicInterpolate(p[2], y);
% arr[3] = cubicInterpolate(p[3], y);
% return cubicInterpolate(arr, x);
% }
function q = bicubicInterpolate(p, x, y)
q1 = cubicInterpolate(p(1,:), x);
q2 = cubicInterpolate(p(2,:), x);
q3 = cubicInterpolate(p(3,:), x);
q4 = cubicInterpolate(p(4,:), x);
q = cubicInterpolate([q1, q2, q3, q4], y);
I verified implementation by comparing to Matalb build in function imwarp
Result:
The following example uses the "CachedBicubicInterpolator" code version, and also supports RGB image:
function BicubicInterpolationTest2()
close all;
% clear all;
img = 'peppers.png';
input_image = double(imread(img))./255;
H=size(input_image,1); % height
W=size(input_image,2); % width
th=120*pi/180; %Rotate 120 degrees
s0 = 0.8;
s1 = 0.8;
x0 = -W/2;
x1 = -H/2;
T=[1 0 x0 ; ...
0 1 x1 ; ...
0 0 1];
RST = [ (s0*cos(th)) (-s1*sin(th)) ((s0*x0*cos(th))-(s1*x1*sin(th))); ...
(s0*sin(th)) (s1*cos(th)) ((s0*x0*sin(th))+(s1*x1*cos(th))); ...
0 0 1];
M=inv(T)*RST;
N = inv(M);
output_image=zeros(H,W,size(input_image,3));
for i=1:W
for j=1:H
x = [i ; j ; 1];
y = N * x;
a = y(1)/y(3);
b = y(2)/y(3);
x1 = floor(a);
y1 = floor(b);
%Bicubic interpolation (applies grayscale image)
if ((x1 >= 2) && (y1 >= 2) && (x1 <= W-2) && (y1 <= H-2))
%Load 4x4 pixels
P = input_image(y1-1:y1+2, x1-1:x1+2, :);
%Interpolation wieghts
dx = a - x1;
dy = b - y1;
%Bi-bicubic interpolation
output_image(j, i, :) = bicubicInterpolate(P, dx, dy);
end
end
end
imshow(output_image);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Verify implementation by comparing with Matalb build in function imwarp:
tform = affine2d(M');
ref_image = imwarp(input_image, tform, 'OutputView', imref2d(size(input_image)), 'Interp', 'cubic');
figure;imshow(ref_image)
figure;imshow(abs(output_image - ref_image), []);impixelinfo
max_diff = max(abs(output_image(:) - ref_image(:)));
disp(['Maximum difference from imwarp = ', num2str(max_diff)]);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [p0, p1, p2, p3] = list4(P)
P = squeeze(P);
p0 = P(1, :);
p1 = P(2, :);
p2 = P(3, :);
p3 = P(4, :);
%http://www.paulinternet.nl/?page=bicubic
% public void updateCoefficients (double[][] p) {
% a00 = p[1][1];
% a01 = -.5*p[1][0] + .5*p[1][2];
% a02 = p[1][0] - 2.5*p[1][1] + 2*p[1][2] - .5*p[1][3];
% a03 = -.5*p[1][0] + 1.5*p[1][1] - 1.5*p[1][2] + .5*p[1][3];
% a10 = -.5*p[0][1] + .5*p[2][1];
% a11 = .25*p[0][0] - .25*p[0][2] - .25*p[2][0] + .25*p[2][2];
% a12 = -.5*p[0][0] + 1.25*p[0][1] - p[0][2] + .25*p[0][3] + .5*p[2][0] - 1.25*p[2][1] + p[2][2] - .25*p[2][3];
% a13 = .25*p[0][0] - .75*p[0][1] + .75*p[0][2] - .25*p[0][3] - .25*p[2][0] + .75*p[2][1] - .75*p[2][2] + .25*p[2][3];
% a20 = p[0][1] - 2.5*p[1][1] + 2*p[2][1] - .5*p[3][1];
% a21 = -.5*p[0][0] + .5*p[0][2] + 1.25*p[1][0] - 1.25*p[1][2] - p[2][0] + p[2][2] + .25*p[3][0] - .25*p[3][2];
% a22 = p[0][0] - 2.5*p[0][1] + 2*p[0][2] - .5*p[0][3] - 2.5*p[1][0] + 6.25*p[1][1] - 5*p[1][2] + 1.25*p[1][3] + 2*p[2][0] - 5*p[2][1] + 4*p[2][2] - p[2][3] - .5*p[3][0] + 1.25*p[3][1] - p[3][2] + .25*p[3][3];
% a23 = -.5*p[0][0] + 1.5*p[0][1] - 1.5*p[0][2] + .5*p[0][3] + 1.25*p[1][0] - 3.75*p[1][1] + 3.75*p[1][2] - 1.25*p[1][3] - p[2][0] + 3*p[2][1] - 3*p[2][2] + p[2][3] + .25*p[3][0] - .75*p[3][1] + .75*p[3][2] - .25*p[3][3];
% a30 = -.5*p[0][1] + 1.5*p[1][1] - 1.5*p[2][1] + .5*p[3][1];
% a31 = .25*p[0][0] - .25*p[0][2] - .75*p[1][0] + .75*p[1][2] + .75*p[2][0] - .75*p[2][2] - .25*p[3][0] + .25*p[3][2];
% a32 = -.5*p[0][0] + 1.25*p[0][1] - p[0][2] + .25*p[0][3] + 1.5*p[1][0] - 3.75*p[1][1] + 3*p[1][2] - .75*p[1][3] - 1.5*p[2][0] + 3.75*p[2][1] - 3*p[2][2] + .75*p[2][3] + .5*p[3][0] - 1.25*p[3][1] + p[3][2] - .25*p[3][3];
% a33 = .25*p[0][0] - .75*p[0][1] + .75*p[0][2] - .25*p[0][3] - .75*p[1][0] + 2.25*p[1][1] - 2.25*p[1][2] + .75*p[1][3] + .75*p[2][0] - 2.25*p[2][1] + 2.25*p[2][2] - .75*p[2][3] - .25*p[3][0] + .75*p[3][1] - .75*p[3][2] + .25*p[3][3];
% }
% public double getValue (double x, double y) {
% double x2 = x * x;
% double x3 = x2 * x;
% double y2 = y * y;
% double y3 = y2 * y;
%
% return (a00 + a01 * y + a02 * y2 + a03 * y3) +
% (a10 + a11 * y + a12 * y2 + a13 * y3) * x +
% (a20 + a21 * y + a22 * y2 + a23 * y3) * x2 +
% (a30 + a31 * y + a32 * y2 + a33 * y3) * x3;
% }
function q = bicubicInterpolate(P, x, y)
[p00, p01, p02, p03] = list4(P(1, :, :));
[p10, p11, p12, p13] = list4(P(2, :, :));
[p20, p21, p22, p23] = list4(P(3, :, :));
[p30, p31, p32, p33] = list4(P(4, :, :));
a00 = p11;
a01 = -.5*p10 + .5*p12;
a02 = p10 - 2.5*p11 + 2*p12 - .5*p13;
a03 = -.5*p10 + 1.5*p11 - 1.5*p12 + .5*p13;
a10 = -.5*p01 + .5*p21;
a11 = .25*p00 - .25*p02 - .25*p20 + .25*p22;
a12 = -.5*p00 + 1.25*p01 - p02 + .25*p03 + .5*p20 - 1.25*p21 + p22 - .25*p23;
a13 = .25*p00 - .75*p01 + .75*p02 - .25*p03 - .25*p20 + .75*p21 - .75*p22 + .25*p23;
a20 = p01 - 2.5*p11 + 2*p21 - .5*p31;
a21 = -.5*p00 + .5*p02 + 1.25*p10 - 1.25*p12 - p20 + p22 + .25*p30 - .25*p32;
a22 = p00 - 2.5*p01 + 2*p02 - .5*p03 - 2.5*p10 + 6.25*p11 - 5*p12 + 1.25*p13 + 2*p20 - 5*p21 + 4*p22 - p23 - .5*p30 + 1.25*p31 - p32 + .25*p33;
a23 = -.5*p00 + 1.5*p01 - 1.5*p02 + .5*p03 + 1.25*p10 - 3.75*p11 + 3.75*p12 - 1.25*p13 - p20 + 3*p21 - 3*p22 + p23 + .25*p30 - .75*p31 + .75*p32 - .25*p33;
a30 = -.5*p01 + 1.5*p11 - 1.5*p21 + .5*p31;
a31 = .25*p00 - .25*p02 - .75*p10 + .75*p12 + .75*p20 - .75*p22 - .25*p30 + .25*p32;
a32 = -.5*p00 + 1.25*p01 - p02 + .25*p03 + 1.5*p10 - 3.75*p11 + 3*p12 - .75*p13 - 1.5*p20 + 3.75*p21 - 3*p22 + .75*p23 + .5*p30 - 1.25*p31 + p32 - .25*p33;
a33 = .25*p00 - .75*p01 + .75*p02 - .25*p03 - .75*p10 + 2.25*p11 - 2.25*p12 + .75*p13 + .75*p20 - 2.25*p21 + 2.25*p22 - .75*p23 - .25*p30 + .75*p31 - .75*p32 + .25*p33;
x2 = x * x;
x3 = x2 * x;
y2 = y * y;
y3 = y2 * y;
% q = (a00 + a01 * y + a02 * y2 + a03 * y3) +...
% (a10 + a11 * y + a12 * y2 + a13 * y3) * x +...
% (a20 + a21 * y + a22 * y2 + a23 * y3) * x2 +...
% (a30 + a31 * y + a32 * y2 + a33 * y3) * x3;
q = (a00 + a01 * x + a02 * x2 + a03 * x3) +...
(a10 + a11 * x + a12 * x2 + a13 * x3) * y +...
(a20 + a21 * x + a22 * x2 + a23 * x3) * y2 +...
(a30 + a31 * x + a32 * x2 + a33 * x3) * y3;
Result:

how to find this function complexity?

I got log n but it's not log n it is log(log n) but why?
int function(int n){
return aux(n , 2)
}
int aux(int n, int x){
while (n<x) {
x *= x;
}
return x;
}
what is the complexity of function ?
Pretty sure the loop condition is supposed to be n > x so I'll be assuming it in this answer.
First, observe the values of x:
x1 = x0 * x0
= 2 * 2
= 2^2
x2 = x1 * x1
= x0 * x0 * x0 * x0
= 2 * 2 * 2 * 2
= 2^4
x3 = x2 * x2
= x1 * x1 * x1 * x1
= x0 * x0 * x0 * x0 * x0 * x0 * x0 * x0
= 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2
= 2^8
We see that the exponent is growing as 2^t where t is the number of iterations in the loop so we can obtain the closed form equation for x:
x = 2^(2^t)
Then we can solve for the number of iterations t:
n > x
=> n > 2^(2^t)
=> log(n) > 2^t
=> log(log(n)) > t
as required.

splitting trapezoid in given proportion

I need to split trapezoid in 2 part of given size with line, parallel basement. I need to get new h1 of new trapezoid.
For example I have trapezoid of area S and I want to split it in 2 trapezoids of areas S1 and S2.
S1 = aS; S2 = (1-a)S;
S1 = (a+z)*(h1)/2;
S2 = (b+z)*(1-h1)/2;
S1/S2 = KS;
To get new h1 I compare a and b, if a != b, I solve square equation and if a == b I work like with square. But sometimes I get mistakes because of rounding (for example when I solve this analytically I get a = b and program thinks a > b). How can I handle this? Or maybe there is another better way to split trapezoid?
Here is simplifyed code:
if (base > base_prev) {
b_t = base; // base of trapezoid
h = H; //height of trapezoid
a_t = base_prev; //another base of trapezoid
KS = S1 / S2;
a_x = (a_t - b_t) * (1 + KS) / h;
b_x = 2 * KS * b_t + 2 * b_t;
c_x = -(a_t * h + b_t * h);
h_tmp = (-b_x + sqrt(b_x * b_x - 4 * a_x * c_x)) / (2 * a_x);
if (h_tmp > h || h_tmp < 0)
h_tmp = (-b_x - sqrt(b_x * b_x - 4 * a_x * c_x)) / (2 * a_x);
} else if (base < base_prev) {
b_t = base_prev;
a_t = base;
KS = S1 / S2;
a_x = (a_t - b_t) * (1 + KS) / h;
b_x = 2 * KS * b_t + 2 * b_t;
c_x = -(a_t * h + b_t * h);
h_tmp = (-b_x + sqrt(b_x * b_x - 4 * a_x * c_x)) / (2 * a_x);
if (h_tmp > h || h_tmp < 0)
h_tmp = (-b_x - sqrt(b_x * b_x - 4 * a_x * c_x)) / (2 * a_x);
}
else {
KS = S1 / S2;
h_tmp = h * KS;
}
If you're dealing with catastrophic cancellation, one approach, dating back to a classic article by Forsythe, is to use the alternative solution form x = 2c/(-b -+ sqrt(b^2 - 4ac)) for the quadratic equation ax^2 + bx + c = 0. One way to write the two roots, good for b < 0, is
x = (-b + sqrt(b^2 - 4ac))/(2a)
x = 2c/(-b + sqrt(b^2 - 4ac)),
and another, good for b >= 0, is
x = 2c/(-b - sqrt(b^2 - 4ac))
x = (-b - sqrt(b^2 - 4ac))/(2a).
Alternatively, you could use the bisection method to obtain a reasonably good guess and polish it with Newton's method.

Can someone explain the mat4.translate function from glMatrix?

Does anyone know why glmatrix ( 1.x ) defines mat4.translate like this:
/**
* Translates a matrix by the given vector
*
* #param {mat4} mat mat4 to translate
* #param {vec3} vec vec3 specifying the translation
* #param {mat4} [dest] mat4 receiving operation result. If not specified result is written to mat
*
* #returns {mat4} dest if specified, mat otherwise
*/
mat4.translate = function (mat, vec, dest) {
var x = vec[0], y = vec[1], z = vec[2],
a00, a01, a02, a03,
a10, a11, a12, a13,
a20, a21, a22, a23;
if (!dest || mat === dest) {
mat[12] = mat[0] * x + mat[4] * y + mat[8] * z + mat[12];
mat[13] = mat[1] * x + mat[5] * y + mat[9] * z + mat[13];
mat[14] = mat[2] * x + mat[6] * y + mat[10] * z + mat[14];
mat[15] = mat[3] * x + mat[7] * y + mat[11] * z + mat[15];
return mat;
}
a00 = mat[0]; a01 = mat[1]; a02 = mat[2]; a03 = mat[3];
a10 = mat[4]; a11 = mat[5]; a12 = mat[6]; a13 = mat[7];
a20 = mat[8]; a21 = mat[9]; a22 = mat[10]; a23 = mat[11];
dest[0] = a00; dest[1] = a01; dest[2] = a02; dest[3] = a03;
dest[4] = a10; dest[5] = a11; dest[6] = a12; dest[7] = a13;
dest[8] = a20; dest[9] = a21; dest[10] = a22; dest[11] = a23;
dest[12] = a00 * x + a10 * y + a20 * z + mat[12];
dest[13] = a01 * x + a11 * y + a21 * z + mat[13];
dest[14] = a02 * x + a12 * y + a22 * z + mat[14];
dest[15] = a03 * x + a13 * y + a23 * z + mat[15];
return dest;
};
It looks like the vector values are multiplied (scaled) by the directional vectors ( dir, left, up ) of the matrix. But I don't understand why. Also why is mat[15] assigned. I thought it should always be 1...
I am using this most of the time and I am quite happy:
mat4.translate_alt = function (mat, vec, factor) {
factor = factor || 1;
mat[12] += vec[0]*factor;
mat[13] += vec[1]*factor;
mat[14] += vec[2]*factor;
}
When should I use mat4.translate and when is my mat4.translate_alt enough ?
mat4.translate translates a matrix with a given vector (vec3), which is the same as multiplying with a translation matrix.
Another way to look at it is to say mat4.translate = mat4.multiply(someMatrix, mat4.create_translate_matrix(someVec3)) (pseudo-code).

Resources