"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const THREE = require("three"); const three_1 = require("three"); const Matrix2_1 = require("./Matrix2"); exports.cZeroVec = new THREE.Vector3(); exports.cXAxis = new THREE.Vector3(1, 0, 0); exports.cYAxis = new THREE.Vector3(0, 1, 0); exports.cZAxis = new THREE.Vector3(0, 0, 1); /** * 旋转一个点,旋转中心在原点 * * @export * @param {Vector3} pt 点 * @param {number} ang 角度. * @returns {Vector3} 返回pt不拷贝. */ function rotatePoint(pt, ang) { new Matrix2_1.Matrix2().setRotate(ang).applyVector(pt); return pt; } exports.rotatePoint = rotatePoint; function equaln(v1, v2, fuzz = 1e-3) { return Math.abs(v1 - v2) < fuzz; } exports.equaln = equaln; function equal(v1, v2) { return v1.distanceToSquared(v2) < 1e-8; } exports.equal = equal; function fixAngle(an, fixAngle, fuzz = 0.1) { if (an < 0) an += Math.PI * 2; an += fuzz; let rem = an % fixAngle; if (rem < fuzz * 2) { an -= rem; } else { an -= fuzz; } return an; } exports.fixAngle = fixAngle; /** * 按照极坐标的方式移动一个点 * * @export * @template * @param {T} v 向量(2d,3d) * @param {number} an 角度 * @param {number} dis 距离 * @returns {T} */ function polar(v, an, dis) { v.x += Math.cos(an) * dis; v.y += Math.sin(an) * dis; return v; } exports.polar = polar; function angle(v) { if (equaln(v.y, 0) && v.x > 0) return 0; let angle = Math.atan2(v.y, v.x); if (angle < 0) angle += Math.PI * 2; return angle; } exports.angle = angle; /** * 求两个向量的夹角,顺时针为负,逆时针为正 * * @param {THREE.Vector3} v1 * @param {THREE.Vector3} v2 * @param {THREE.Vector3} [ref] 参考向量,如果为世界坐标系则为0,0,1 * @returns */ function angleTo(v1, v2, ref = new THREE.Vector3(0, 0, 1)) { if (!ref.equals(new three_1.Vector3(0, 0, 1))) { //任意轴坐标系. 使用相机的构造矩阵. ref.multiplyScalar(-1); let up = getLoocAtUpVec(ref); let refOcs = new THREE.Matrix4(); refOcs.lookAt(exports.cZeroVec, ref, up); let refOcsInv = new THREE.Matrix4().getInverse(refOcs); v1.applyMatrix4(refOcsInv); v2.applyMatrix4(refOcsInv); v1.z = 0; v2.z = 0; } if (v1.equals(exports.cZeroVec) || v2.equals(exports.cZeroVec)) return 0; let cv = new three_1.Vector3().crossVectors(v1, v2).normalize(); return cv.z === 0 ? v1.angleTo(v2) : v1.angleTo(v2) * cv.z; } exports.angleTo = angleTo; function getLoocAtUpVec(dir) { if (dir.equals(exports.cZeroVec)) { throw ("zero vector"); } let norm = dir.clone().normalize(); if (norm.equals(exports.cZAxis)) { return new THREE.Vector3(0, 1, 0); } else if (norm.equals(exports.cZAxis.clone().negate())) { return new THREE.Vector3(0, -1, 0); } else { let xv = new THREE.Vector3(); xv.crossVectors(exports.cZAxis, norm); let up = new THREE.Vector3(); up.crossVectors(norm, xv); return up; } } exports.getLoocAtUpVec = getLoocAtUpVec; function createLookAtMat4(dir) { let up = getLoocAtUpVec(dir); let mat = new THREE.Matrix4(); mat.lookAt(exports.cZeroVec, dir, up); return mat; } exports.createLookAtMat4 = createLookAtMat4; function isParallelTo(v1, v2) { return v1.clone().cross(v2).lengthSq() < 1e-9; } exports.isParallelTo = isParallelTo; function ptToString(v, fractionDigits = 3) { return v.toArray().map(o => { return o.toFixed(fractionDigits); }).join(","); } exports.ptToString = ptToString; function midPoint(v1, v2) { return v1.clone().add(v2).multiplyScalar(0.5); } exports.midPoint = midPoint; function midPoint2(v1, v2) { return v1.clone().add(v2).multiplyScalar(0.5); } exports.midPoint2 = midPoint2; function midPtCir(v1, v2) { let baseline = new three_1.Vector3(1, 0, 0); let outLine = v2.clone().sub(v1); let ang = angleTo(baseline, outLine) / 2; let midLine = rotatePoint(outLine, -ang); return v1.clone().add(midLine); } exports.midPtCir = midPtCir; function GetBox(obj, updateMatrix) { if (updateMatrix) obj.updateMatrixWorld(false); if (obj.hasOwnProperty("geometry")) { let geo = obj["geometry"]; if (geo instanceof THREE.Geometry || geo instanceof THREE.BufferGeometry) { if (!geo.boundingBox) geo.computeBoundingBox(); return geo.boundingBox.clone().applyMatrix4(obj.matrixWorld); } } else if (obj.children.length > 0) { let box = obj.children.reduce((sumBox, itemObj) => { let itemBox = GetBox(itemObj); if (itemBox) sumBox.union(itemBox); return sumBox; }, new THREE.Box3()); // if (box) box.applyMatrix4(obj.matrixWorld); return box; } else return null; } exports.GetBox = GetBox; function GetBoxArr(arr) { if (arr.length == 0) { return null; } return arr.map(o => { return GetBox(o); }).filter(o => { return o; }).reduce((sumBox, objBox) => { return sumBox.union(objBox); }, new THREE.Box3()); } exports.GetBoxArr = GetBoxArr; function MoveMatrix(v) { let mat = new THREE.Matrix4(); mat.makeTranslation(v.x, v.y, v.z); return mat; } exports.MoveMatrix = MoveMatrix; function getProjectDist(v1, v2) { let ang = v1.angleTo(v2); let dist = v1.length(); return { h: dist * Math.cos(ang), v: dist * Math.sin(ang) }; } exports.getProjectDist = getProjectDist; //获得输入点在2线组成的4个区间的位置 function getPtPostion(sp, ep, c, inPt) { let l1 = sp.clone().sub(c); let l2 = ep.clone().sub(c); let l3 = l1.clone().negate(); let l4 = l2.clone().negate(); let inputLine = inPt.clone().sub(c); let ang1 = angleTo(l1, l2); let ang2 = Math.PI; let ang3 = ang2 + Math.abs(ang1); let inputAng = angleTo(l1, inputLine); if (ang1 * inputAng < 0) { inputAng = (Math.PI * 2 - Math.abs(inputAng)); } ang1 = Math.abs(ang1); inputAng = Math.abs(inputAng); if (inputAng <= ang1) { return { sp, ep }; } else if (inputAng > ang1 && inputAng <= ang2) { return { sp: c.clone().add(l3), ep }; } else if (inputAng > ang2 && inputAng <= ang3) { return { sp: c.clone().add(l3), ep: c.clone().add(l4) }; } else { return { sp, ep: c.clone().add(l4) }; } } exports.getPtPostion = getPtPostion; function angleAndX(v) { return v.x ? Math.atan(v.y / v.x) : Math.PI / 2; } exports.angleAndX = angleAndX; /** * 将角度调整为0-2pi之间 * * @export * @param {number} an */ function angleTo2Pi(an) { an = an % (Math.PI * 2); if (an < 0) an += Math.PI * 2; return an; } exports.angleTo2Pi = angleTo2Pi; function updateGeometry(l, geometry) { let geo = l.geometry; geo.dispose(); l.geometry = geometry; geometry.verticesNeedUpdate = true; geometry.computeBoundingSphere(); } exports.updateGeometry = updateGeometry; //# sourceMappingURL=GeUtils.js.map