You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
WebCAD/src/Common/Matrix4Utils.ts

158 lines
4.4 KiB

import { Matrix4, Vector2, Vector3 } from 'three';
import { CoordinateSystem } from '../Geometry/CoordinateSystem';
import { equaln, isParallelTo } from '../Geometry/GeUtils';
7 years ago
/**
*
* @param {Matrix4} mat
* @param {number} col ,0x 1y 2z 3org
* @param {Vector3} v
*/
export function matrixSetVector(mat: Matrix4, col: number, v: Vector3)
{
let index = col * 4;
mat.elements[index] = v.x;
mat.elements[index + 1] = v.y;
mat.elements[index + 2] = v.z;
}
/**
*
* X
* YZXAxisYAxisZAxis
* @returns {Matrix4}
*/
export function matrixAlignCoordSys(matrixFrom: Matrix4, matrixTo: Matrix4): Matrix4
{
return new Matrix4().getInverse(matrixTo).multiply(matrixFrom);
}
/**
* 2
* @param {Matrix4} matrixFrom
* @param {Matrix4} matrixTo
* @returns {boolean} 2
*/
export function matrixIsCoplane(matrixFrom: Matrix4, matrixTo: Matrix4, fuzz = 1e-5): boolean
{
let nor1 = new Vector3().setFromMatrixColumn(matrixFrom, 2);
let nor2 = new Vector3().setFromMatrixColumn(matrixTo, 2);
//法线共面
if (!isParallelTo(nor1, nor2))
return false;
//高共面
let pt = new Vector3().setFromMatrixPosition(matrixTo);
//变换到自身对象坐标系.
pt.applyMatrix4(new Matrix4().getInverse(matrixFrom));
return equaln(pt.z, 0, fuzz);
}
//构造缩放矩阵 等比例
export function matrixScale(scale: number, center?: Vector3)
{
let scaleMtx = new Matrix4().makeScale(scale, scale, scale);
if (center) scaleMtx.setPosition(center.clone().multiplyScalar(1 - scale));
return scaleMtx;
}
//缩放矩阵 不等比例
export function MakeScaleMatrix(scaleX: number, scaleY: number, scaleZ: number, center?: Vector3)
{
let scaleMtx = new Matrix4().makeScale(scaleX, scaleY, scaleZ);
if (center) scaleMtx.setPosition(center.clone().applyMatrix4(scaleMtx).sub(center).negate());
return scaleMtx;
}
/**
* ,
*/
export function setRotationOnAxis(mtx: Matrix4, axis: Vector3, ro: number)
{
let pos = new Vector3().setFromMatrixPosition(mtx);
mtx.makeRotationAxis(axis, ro);
mtx.setPosition(pos);
return mtx;
}
/**
*
*/
export function reviseMirrorMatrix(mtx: Matrix4, index = 1): Matrix4
{
let cs = new CoordinateSystem().applyMatrix4(mtx);
if (index === 0)
cs.XAxis.negate();
else if (index === 1)
cs.YAxis.negate();
else
cs.ZAxis.negate();
mtx.copy(cs.getMatrix4());
return mtx;
}
let cacheVec: Vector3;
export function Vector2ApplyMatrix4(mtx: Matrix4, vec: Vector2)
{
if (!cacheVec) cacheVec = new Vector3();
cacheVec.x = vec.x;
cacheVec.y = vec.y;
cacheVec.z = 0;
cacheVec.applyMatrix4(mtx);
vec.x = cacheVec.x;
vec.y = cacheVec.y;
}
export function GetMirrorMat(v: Vector3)
{
let mirrorMat = new Matrix4();
let xAxis = new Vector3(1 - 2 * v.x ** 2, -2 * v.x * v.y, -2 * v.x * v.z);
let yAxis = new Vector3(-2 * v.x * v.y, 1 - 2 * v.y ** 2, -2 * v.y * v.z);
let zAxis = new Vector3(-2 * v.x * v.z, -2 * v.y * v.z, 1 - 2 * v.z ** 2);
mirrorMat.makeBasis(xAxis, yAxis, zAxis);
return mirrorMat;
}
5 years ago
export function ApplyMatrix4IgnorePosition(vec: { x: number, y: number, z: number; }, m: Matrix4)
5 years ago
{
let { x, y, z } = vec;
let e = m.elements;
vec.x = e[0] * x + e[4] * y + e[8] * z;
vec.y = e[1] * x + e[5] * y + e[9] * z;
vec.z = e[2] * x + e[6] * y + e[10] * z;
return vec;
}
export function MakeRotateMatrix4(cen: Vector3, axis: Vector3, angle: number, roMtx: Matrix4 = new Matrix4)
{
roMtx.makeRotationAxis(axis, angle);
roMtx.setPosition(cen.clone().applyMatrix4(roMtx).negate().add(cen));
return roMtx;
}
/**
* 2d,.
*/
export function MatrixPlanarizere(mtx: Matrix4, z0 = true)
{
mtx.elements[2] = 0;
mtx.elements[6] = 0;
mtx.elements[8] = 0;
mtx.elements[9] = 0;
mtx.elements[10] = Math.sign(mtx.elements[10]);
if (z0)
mtx.elements[14] = 0;
return mtx;
}
export const tempMatrix1 = new Matrix4;
export const ZMirrorMatrix = GetMirrorMat(new Vector3(0, 0, 1));