猫史档案馆


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

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


评论

吃()

认证( )

一口一个晴天宝

再吃个伴雪

()

时刻警惕 准备把540000号帖收入囊中)

吞掉())


mkonnzikmkonnzik

怎么弄代码排版

点赞0


评论

6()输入框顶端最右有个,它就是代码块

谢谢


伴只狗头伴只狗头

ddd

点赞0


评论


七式草莓七式草莓

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

点赞0


评论

x y z呀

这样很容易歧义的,虽然岛3的也是XYZ


小屑鹿小屑鹿

👀

点赞1


评论


全能代码师全能代码师

进收藏夹吃灰吧(

点赞1


评论


yee089yee089

很酷。

点赞0


评论

难道你对原理不敢兴趣吗?()

线性代数。

刚被高斯消元和线性基搞的喵活来的,现在搞不定了(恼)

比我好...我向量都不会

不过线性代数在数学竞赛的时候讨论的不算多。

我现在是打算专攻几何了。

是,我看了一下某本竞赛题集,别的一般都有十几页分几个专题,就向量只有3页一个专题(恼) 但是确实是不简单的

高中会多一些,初中在这方面比较少。

给初中生放线代的基本是初生。我是学OI才学的这些的(恼)ccf你食不食人啊(划)

物理竞赛还要学数分呢,就数学竞赛好点。

最卷啊(恼)

确实,学科竞赛最卷的就是数学了,物理都好一点。


翎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


评论

对象转字符串)因为有时候对象会引用自己导致报错()所以直接json.stringify不行


骑士之刃骑士之刃

收藏

点赞0


评论