用户:伴只狗头查看:26 回复:17 评论:26 创建时间:2023-05-12T19:46:37
rt
包含(方向向量,欧拉角,四元数,矩阵)的互相转换
使用方法:
JSON.ObjToString,//返回非嵌套循环的数组
Box3Quaternion.toEuler,//四元数转欧拉角 返回Box3Vector3
Box3Quaternion.toDirectionVector,//四元数转方向向量* 返回Box3Vector3
Box3Vector3.toQuaternion,//方向向量转四元数* 返回Box3Quaternion
Box3Vector3.toQuaternion$E,//欧拉角转四元数 返回Box3Quaternion
Box3Quaternion.toMatrix,//四元数转方向矩阵 返回Array[Array,Array,Array] 可以直接调用 如:
console.log(new Box3Vector3(-1,0,0).toQuaternion())
调用方法:
1.在创作端创建一个新的文件叫expand.js
2.在index.js输入 引入文件
require('./expand.js')
3.在expand.js输入下段代码
/*
@伴雪纷飞
@github:ibxff
@name :expand.js
__all__=[
JSON.ObjToString,//返回非嵌套循环的数组
Box3Quaternion.toEuler,//四元数转欧拉角
Box3Quaternion.toDirectionVector,//四元数转方向向量*
Box3Vector3.toQuaternion,//方向向量转四元数*
Box3Vector3.toQuaternion$E,//欧拉角转四元数
Box3Quaternion.toMatrix,//四元数转方向矩阵
]
*/
/*
ex:
require('./expand.js')
console.log(new Box3Vector3(-1,0,0).toQuaternion())
*/
//将四元数转换成欧拉角
//输入:new Box3Quaternion(0,0,0,1).toBox3Vector3()
//输出:{x:180,y:180,z:0}
Box3Quaternion.prototype.toEuler=function(){
//console.log(JSON.ObjToString(this))
const { w, x, y, z } = this;
const siny = 2 * (w * y - x * z);
const cosy = 1 - 2 * (y * y + z * z);
const sinx = 2 * (w * x - y * z);
const cosx = 1 - 2 * (x * x + y * y);
const sinz = 2 * (w * z - x * y);
const cosz = 1 - 2 * (z * z + x * x);
const euler = new Box3Vector3(
Math.atan2(sinx, cosx) * 180 / Math.PI,
Math.atan2(siny, cosy) * 180 / Math.PI,
Math.atan2(sinz, cosz) * 180 / Math.PI
)
return euler;
}
//转方向向量 这个是最常用的,如facingDirction和velocity等
//输入:new Box3Quaternion(0,0,0,1).toDirectionVector()
//输出:{x:-1,y:0,z:0}
Box3Quaternion.prototype.toDirectionVector=function () {
// 计算方向向量
const x = 1 - 2 * (this.y * this.y + this.z * this.z);
const y = 2 * (this.x * this.y + this.z * this.w);
const z = 2 * (this.x * this.z - this.y * this.w);
// 返回方向向量
return new Box3Vector3(x,y,z);
}
//方向向量转四元数 常用 比如说要将facingDirction转成实体方向四元数(比如让实体和玩家面向同一个方向)
//输入:new Box3Vector3(-1,0,0).toQuaternion()
//输出:{ w:0.7071067811865476, x:0, y:-0.7071067811865475, z:0 }
Box3Vector3.prototype.toQuaternion=function() {
const { x, y, z } = this;
const len = Math.sqrt(x * x + y * y + z * z);
const angle = Math.acos(z / len);
const sinHalfAngle = Math.sin(angle / 2);
const cosHalfAngle = Math.cos(angle / 2);
return new Box3Quaternion(
cosHalfAngle,
-y * sinHalfAngle / len,
x * sinHalfAngle / len,
0,
);
}
//欧拉角转四元数(不常用)
Box3Vector3.prototype.toQuaternion$E=function () {
const {x, y, z} = this
const c1 = Math.cos(x/2), s1 = Math.sin(x/2);
const c2 = Math.cos(y/2), s2 = Math.sin(y/2);
const c3 = Math.cos(z/2), s3 = Math.sin(z/2);
return new Box3Quaternion(
c1*c2*c3 + s1*s2*s3,
s1*c2*c3 - c1*s2*s3,
c1*s2*c3 + s1*c2*s3,
c1*c2*s3 - s1*s2*c3,
)
}
//四元数转矩阵(不常用)
//输入 new Box3Quaternion(0.7071067811865476, 0, -0.7071067811865475, 0 ).toMatrix
//输出:[[ 1, 0, 0 ],[ 0, 0, -1 ],[ 0, 1, 0 ]]
Box3Quaternion.prototype.toMatrix=function() {
const [x, y, z, w] = this;
const xx = x * x;
const xy = x * y, xz = x * z, xw = x * w;
const yy = y * y;
const yz = y * z, yw = y * w;
const zz = z * z;
const zw = z * w;
const m11 = 1-2*(yy+zz), m12 = 2*(xy-zw), m13 = 2*(xz+yw);
const m21 = 2*(xy+zw), m22 = 1-2*(xx+zz), m23 = 2*(yz-xw);
const m31 = 2*(xz-yw), m32 = 2*(yz+xw), m33 = 1-2*(xx+yy);
return [[m11, m12, m13], [m21, m22, m23], [m31, m32, m33]];
}
//输出测试
//解决json无法输出循环数组的bug
//更加彻底的解决可以看github的某个项目circle.js
JSON.ObjToString=(obj)=> {
const cache = new Set();
return JSON.stringify(obj, function (key, value) {
if (typeof value === 'object' && value !== null) {
if (cache.has(value)) {
// 循环引用
cache.clear();
return '[Circular Reference]';
}
// 非循环引用
cache.add(value);
}
return value;
});
}
ps:小号发的,大号被封了(伴雪纷飞 包括box3) 似乎永封QAQ
LZ编编编编程猫为啥四元数(0,0,0,1)转向量是(-1,0,0),向量(-1,0,0)转四元数变成了{ w:0.7071067811865476, x:0, y:-0.7071067811865475, z:0 }???这不对吧((
点赞1
评论
感谢lzzz编程猫的反馈
将
Box3Quaternion.prototype.toDirectionVector
函数公式的计算改成
const x = 2 * (this.x * this.z - this.y * this.w);
const y = 2 * (this.y * this.z + this.x * this.w);
const z = 1 - 2 * (this.x * this.x + this.y * this.y);
这样就可以得到正确结果了
点赞3
评论