Files
rubic-cube/src/utils/cubeProjection.js

59 lines
1.7 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 3D geometry helpers for cube face/axis operations and screen projection
export const getFaceNormal = (face, FACES) => {
const map = {
[FACES.FRONT]: { x: 0, y: 0, z: 1 },
[FACES.BACK]: { x: 0, y: 0, z: -1 },
[FACES.RIGHT]: { x: 1, y: 0, z: 0 },
[FACES.LEFT]: { x: -1, y: 0, z: 0 },
[FACES.UP]: { x: 0, y: 1, z: 0 },
[FACES.DOWN]: { x: 0, y: -1, z: 0 },
};
return map[face] || { x: 0, y: 0, z: 1 };
};
// Which axes can this face physically rotate along?
export const getAllowedAxes = (face, FACES) => {
switch (face) {
case FACES.FRONT:
case FACES.BACK:
return ["x", "y"];
case FACES.RIGHT:
case FACES.LEFT:
return ["z", "y"];
case FACES.UP:
case FACES.DOWN:
return ["x", "z"];
}
return [];
};
export const getAxisVector = (axis) => {
if (axis === "x") return { x: 1, y: 0, z: 0 };
if (axis === "y") return { x: 0, y: 1, z: 0 };
if (axis === "z") return { x: 0, y: 0, z: 1 };
return { x: 0, y: 0, z: 0 };
};
// Cross product: a × b
export const cross = (a, b) => ({
x: a.y * b.z - a.z * b.y,
y: a.z * b.x - a.x * b.z,
z: a.x * b.y - a.y * b.x,
});
// Project 3D vector to 2D screen space using a viewMatrix (column-major 4x4).
// Input v is in Right-Handed Math Coordinates (Y up).
// viewMatrix operates in CSS Coordinates (Y down).
// Applies T⁻¹ * M * T to maintain correct projection chirality.
export const project = (v, viewMatrix) => {
const m = viewMatrix;
const cssY = -v.y;
const x = v.x * m[0] + cssY * m[4] + v.z * m[8];
const projY = v.x * m[1] + cssY * m[5] + v.z * m[9];
const mathY = -projY;
return { x, y: mathY };
};