猫史档案馆


[氵]食用的各种角度互转库 (方向向量,欧拉角,四元数,矩阵)

用户:伴只狗头伴只狗头查看: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


回复

上一页1 页 / 共 1下一页
晴天宝r晴天宝r

沙发)

点赞0


评论


mkonnzikmkonnzik

怎么弄代码排版

点赞0


评论


伴只狗头伴只狗头

ddd

点赞0


评论


七式草莓七式草莓

你这欧拉角是xyz还是xzy还是yxz还是……()()

点赞0


评论


小屑鹿小屑鹿

👀

点赞1


评论


全能代码师全能代码师

进收藏夹吃灰吧(

点赞1


评论


yee089yee089

很酷。

点赞0


评论


翎with珝翎with珝

我看了看满是灰尘的收藏夹(

于是我不收藏了()

点赞0


评论


橘生淮北则为枳橘生淮北则为枳

原理是什么?

点赞0


评论


LZ编编编编程猫LZ编编编编程猫

岛三的四元数是(x,y,z,w)吧,为啥api上写的是(w,x,y,z),代码里也是。。。害我困扰了好长时间

点赞2


评论


LZ编编编编程猫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


评论


拉文克劳的小鹰拉文克劳的小鹰

收藏)

点赞0


评论


sky-*^O^*sky-*^O^*

救人于水火!太感谢了

点赞1


评论


yh12i31yh12i31

收藏

 

点赞0


评论


𝙲ℴ𝗌𝔦𝒹ₑ𝑟𝙲ℴ𝗌𝔦𝒹ₑ𝑟

JSON.ObjToString是什么(

点赞0


评论


骑士之刃骑士之刃

收藏

点赞0


评论