Princípios de Transformações no Three.js: Rotação, Translação e Escala com Matrizes

No Three.js, transformar objetos como malhas envolve operações matriciais subjacentes. Métodos como translateX, rotateY e propriedades como scale são ipmlementados usando matrizes de modelo que combinam translação, rotação e escala. A essência é a multiplicação de matrizes: cada transformação é representada por uma matriz específica, e a matriz de modelo final é o produto dessas matrizes aplicadas sequencialmente.

Translação: Deslocamento via Matrizes

A translação move um objeto ao longo dos eixos. Matematicamente, é experssa por uma matriz 4x4 onde os elementos da quarta coluna representam os deslocamentos em x, y e z. Por exemplo, deslocar um ponto (x, y, z, 1) por (tx, ty, tz) corresponde a multiplicar por uma matriz de translação.

// Exemplo em GLSL para translação
attribute vec4 vertexPos;
mat4 translateMatrix = mat4(
    1.0, 0.0, 0.0, 0.0,
    0.0, 1.0, 0.0, 0.0,
    0.0, 0.0, 1.0, 0.0,
    0.5, 0.3, 0.2, 1.0  // Deslocamento em x, y, z
);
void main() {
    gl_Position = translateMatrix * vertexPos;
}

No Three.js, o método translate internamente constrói uma matriz de translação e a aplica à geometria. Vejamos um trecho simplificado da fonte:

// Fonte: Three.js BufferGeometry.js (simplificado)
const tempMatrix = new THREE.Matrix4();

function applyTranslation(geo, dx, dy, dz) {
    tempMatrix.makeTranslation(dx, dy, dz);
    applyMatrixToGeometry(geo, tempMatrix);
}

function applyMatrixToGeometry(geo, matrix) {
    const posAttr = geo.attributes.position;
    if (posAttr) {
        posAttr.applyMatrix4(matrix);
        posAttr.needsUpdate = true;
    }
}

A chave está em makeTranslation, que configura a matriz com os valores de deslocamento na quarta coluna, alinhando-se ao princípio matemático.

Rotação: Transformação Angular com Matrizes

A rotação gira um objeto ao redor de um eixo, utilizando uma matriz onde os elementos da submatriz 3x3 superior esquerda contêm senos e cosesnos do ângulo. Por exemplo, rotação ao redor do eixo Z por θ radianos usa uma matriz específica.

// Exemplo em GLSL para rotação no eixo Z
attribute vec4 vertexPos;
float theta = radians(45.0);
float cosTheta = cos(theta);
float sinTheta = sin(theta);
mat4 rotateZMatrix = mat4(
    cosTheta, -sinTheta, 0.0, 0.0,
    sinTheta,  cosTheta, 0.0, 0.0,
    0.0,       0.0,      1.0, 0.0,
    0.0,       0.0,      0.0, 1.0
);
void main() {
    gl_Position = rotateZMatrix * vertexPos;
}

No Three.js, o método rotateZ segue um processo similar, criando uma matriz de rotação e combinando-a com a matriz de modelo existente. Código adaptado:

// Fonte: Three.js Matrix4.js (simplificado)
THREE.Matrix4.prototype.setRotationZ = function(angle) {
    const c = Math.cos(angle), s = Math.sin(angle);
    this.set(
        c, -s, 0, 0,
        s,  c, 0, 0,
        0,  0, 1, 0,
        0,  0, 0, 1
    );
    return this;
};

// Em BufferGeometry.js (simplificado)
function rotateGeometryAroundZ(geo, angle) {
    tempMatrix.setRotationZ(angle);
    applyMatrixToGeometry(geo, tempMatrix);
}

Observe que no Three.js as matrizes são armazenadas em ordem colunar, o que difere da convensão usual em álgebra linear, onde as linhas e colunas podem ser transpostas na interpretação.

Escala: Redimensionamento via Diagonal Matricial

A escala altera o tamanho de um objeto ao multiplicar as coordenadas por fatores em cada eixo. Isso é representado por uma matriz diagonal, onde os elementos diagonais contêm os fatores de escala.

// Exemplo em GLSL para escala
attribute vec4 vertexPos;
mat4 scaleMatrix = mat4(
    1.5, 0.0, 0.0, 0.0,
    0.0, 2.0, 0.0, 0.0,
    0.0, 0.0, 0.8, 0.0,
    0.0, 0.0, 0.0, 1.0  // Fatores de escala em x, y, z
);
void main() {
    gl_Position = scaleMatrix * vertexPos;
}

No Three.js, a propriedade scale é atualizada internamente usando uma matriz de escala. Um exemplo simplificado:

// Fonte: Three.js Matrix4.js (simplificado)
THREE.Matrix4.prototype.makeScale = function(sx, sy, sz) {
    this.set(
        sx, 0,  0,  0,
        0,  sy, 0,  0,
        0,  0,  sz, 0,
        0,  0,  0,  1
    );
    return this;
};

// Em Object3D.js (simplificado)
function updateScale(obj, fx, fy, fz) {
    tempMatrix.makeScale(fx, fy, fz);
    applyMatrixToGeometry(obj.geometry, tempMatrix);
}

A aplicação combinada de translação, rotação e escala é eficiente através da composição matricial: multiplica-se as matrizes individuais em uma única matriz de modelo, que é então aplicada aos vértices. Isso permite transformações complexas em uma operação unificada.

Tags: three.js WebGL Matrizes 4x4 Transformações Geométricas GLSL

Publicado em 6-30 07:36