📄 matrix.c
字号:
#include <stdlib.h>
#include <assert.h>
#include <math.h>
#include "matrix.h"
#define PI 3.141592
#define TO_RADIANS(angle) ((angle) * PI / 180)
/*
* Builds a translation Matrix
* It's like operator T (dX, dY, dZ)
*/
PMATRIX_4x4 MatrixTranslation (double deltaX, double deltaY, double deltaZ, MATRIX_4x4 pDest)
{
assert (pDest != NULL);
MatrixClear (pDest);
pDest [0][0] = 1;
pDest [0][3] = deltaX;
pDest [1][1] = 1;
pDest [1][3] = deltaY;
pDest [2][2] = 1;
pDest [2][3] = deltaZ;
pDest [3][3] = 1;
return &(pDest[0][0]);
}
/*
* Builds a scale Matrix
* It's like operator S (dX, dY, dZ)
*/
PMATRIX_4x4 MatrixScale (double deltaX, double deltaY, double deltaZ, MATRIX_4x4 pDest)
{
assert (pDest != NULL);
MatrixClear (pDest);
pDest [0][0] = deltaX;
pDest [1][1] = deltaY;
pDest [3][3] = deltaZ;
pDest [3][3] = 1;
return &(pDest[0][0]);
}
/*
* Builds a rotation matrix around XX axis.
* The angle is in degrees.
* It's like operator Rx (alfa)
*/
PMATRIX_4x4 MatrixRotateX (double dAngle, MATRIX_4x4 pDest)
{
assert (pDest != NULL);
MatrixClear (pDest);
pDest [0][0] = 1;
pDest [1][1] = cos (dAngle);
pDest [1][2] = -sin (dAngle);
pDest [2][1] = sin (dAngle);
pDest [2][2] = cos (dAngle);
pDest [3][3] = 1;
return &(pDest[0][0]);
}
/*
* Builds a rotation matrix around YY axis.
* The angle is in degrees.
* It's like operator Ry (alfa)
*/
PMATRIX_4x4 MatrixRotateY (double dAngle, MATRIX_4x4 pDest)
{
assert (pDest != NULL);
MatrixClear (pDest);
pDest [0][0] = cos (dAngle);
pDest [0][2] = sin (dAngle);
pDest [1][1] = 1;
pDest [2][0] = -sin (dAngle);
pDest [2][2] = cos (dAngle);
pDest [3][3] = 1;
return &(pDest[0][0]);
}
/*
* Builds a rotation matrix around ZZ axis.
* The angle is in degrees.
* It's like operator Rz (alfa)
*/
PMATRIX_4x4 MatrixRotateZ (double dAngle, MATRIX_4x4 pDest)
{
assert (pDest != NULL);
MatrixClear (pDest);
pDest [0][0] = cos (dAngle);
pDest [0][1] = -sin (dAngle);
pDest [1][0] = sin (dAngle);
pDest [1][1] = cos (dAngle);
pDest [2][2] = 1;
pDest [3][3] = 1;
return &(pDest[0][0]);
}
/*
* Builds a projection matrix for main view.
*/
PMATRIX_4x4 MatrixFront (MATRIX_4x4 pDest)
{
assert (pDest != NULL);
MatrixClear (pDest);
pDest [0][0] = 1;
pDest [1][1] = 1;
pDest [2][2] = 1;
pDest [3][3] = 1;
return &(pDest[0][0]);
}
/*
* Constroi uma matriz de proje玢o para o al鏰do lateral.
*/
PMATRIX_4x4 MatrixSide (MATRIX_4x4 pDest)
{
assert (pDest != NULL);
MatrixClear (pDest);
pDest [0][2] = 1;
pDest [1][1] = 1;
pDest [3][3] = 1;
return &(pDest[0][0]);
}
/*
* Builds a projection matrix for top view.
*/
PMATRIX_4x4 MatrixAbove (MATRIX_4x4 pDest)
{
assert (pDest != NULL);
MatrixClear (pDest);
pDest [0][0] = 1;
pDest [1][2] = 1;
pDest [3][3] = 1;
return &(pDest[0][0]);
}
/*
* Builds a projection matrix for oblique view.
*/
PMATRIX_4x4 MatrixOblique (MATRIX_4x4 pDest, double dFactor, double dAngle)
{
double dRadians;
assert (pDest != NULL);
MatrixClear (pDest);
dRadians = TO_RADIANS (dAngle);
pDest [0][0] = 1;
pDest [0][2] = - dFactor * cos (dAngle);
pDest [1][1] = 1;
pDest [1][2] = - dFactor * sin (dAngle);
pDest [3][3] = 1;
return &(pDest[0][0]);
}
/*
* Builds a projection matrix for perpective view.
*/
PMATRIX_4x4 MatrixPerspective (MATRIX_4x4 pDest, double dDistance)
{
assert (pDest != NULL && dDistance != 0.0);
MatrixClear (pDest);
pDest [0][0] = 1;
pDest [1][1] = 1;
pDest [3][2] = 1/dDistance;
pDest [3][3] = 1;
return &(pDest[0][0]);
}
/*
* Builds a projection matrix for axonometric view.
*/
PMATRIX_4x4 MatrixAxonometric (MATRIX_4x4 pDest, double dA, double dB)
{
double dGamma, dTeta;
double dARadians, dBRadians;
MATRIX_4x4 rotationY, rotationX, ortogonal, temp;
assert (pDest != NULL && dB != 0.0);
dARadians = TO_RADIANS (dA);
dBRadians = TO_RADIANS (dB);
dTeta = atan (sqrt (tan (dARadians) / tan (dBRadians))) - PI / 2;
dGamma = asin (sqrt (tan (dARadians) * tan (dBRadians)));
MatrixRotateY (dTeta, rotationY);
MatrixRotateX (dGamma, rotationX);
MatrixFront (ortogonal);
MatrixMultiply (ortogonal, rotationX, temp);
MatrixMultiply (temp, rotationY, pDest);
return &(pDest[0][0]);
}
/*
* Multiplies 2 matrixes.
*/
PMATRIX_4x4 MatrixMultiply (MATRIX_4x4 pLeft, MATRIX_4x4 pRight, MATRIX_4x4 pDest)
{
int nLine, nCol;
int k;
assert (pDest != NULL);
for (nLine = 0; nLine < 4; nLine++)
for (nCol = 0; nCol < 4; nCol++) {
double temp;
temp = 0;
for (k = 0; k < 4; k++)
temp += pLeft [nLine][k] * pRight [k][nCol];
pDest [nLine][nCol] = temp;
}
return &(pDest[0][0]);
}
/*
* Multiplies a matrix with a 3D point.
*/
PPOINT_3D MatrixMultiplyPoint (const MATRIX_4x4 pMatrix, const PPOINT_3D pPoint, PPOINT_3D pDest)
{
assert (pMatrix != NULL && pPoint != NULL && pDest != NULL);
pDest->x = pMatrix[0][0] * pPoint->x + pMatrix[0][1] * pPoint->y +
pMatrix[0][2] * pPoint->z + pMatrix[0][3] * pPoint->w;
pDest->y = pMatrix[1][0] * pPoint->x + pMatrix[1][1] * pPoint->y +
pMatrix[1][2] * pPoint->z + pMatrix[1][3] * pPoint->w;
pDest->z = pMatrix[2][0] * pPoint->x + pMatrix[2][1] * pPoint->y +
pMatrix[2][2] * pPoint->z + pMatrix[2][3] * pPoint->w;
pDest->w = pMatrix[3][0] * pPoint->x + pMatrix[3][1] * pPoint->y +
pMatrix[3][2] * pPoint->z + pMatrix[3][3] * pPoint->w;
return pDest;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -