猫史档案馆


【教程】三角函数js的应用

用户:guxia666guxia666查看:19 回复:12 评论:19 创建时间:2022-12-15T21:03:00


听说,某呵不会三角函数(什

那么,今天三角函数的应用来了

先教大家三角函数

三角函数分为(初中知识):sin,cos,tan

高中的什么余弦定理啥的就不教了()与本贴无关(bushi

sin:表示在直角三角形中对边比斜边

cos:表示在直角三角形中邻边比斜边

tan:表示对边比邻边

现在将视角看到Math当中:

math类的Math.sin(),Math.cos(),Math.tan()

那么问题来了,那么,弧度是什么?

最直观地说,一个 60度 的角,可以用 60°来表示,也可以用 π / 3 (圆周率除以3)来表示;

同理,一个 90度 的角,可以用 90°来表示,也可以用 π / 2 (圆周率除以2)来表示;

还有,一个 180度 的角,可以用 180°来表示,也可以用 π 来表示。

那么,【60°=π / 3】,90°=π / 2180°=π】,等号的左边是度数,右边是弧度

是否回忆起来一个这么的例子,【 cos(60°) = cos(π/3 ) = 1/2 = 0.5 】

中学时期,我们知道,30、45、60、90、180 这些角度是特殊角,用弧度来表示相对容易,所以我们当时只背了这么特殊角度的弧度值,然后理所当然地,慢慢地遗忘了弧度的概念,本文也不阐述弧度的概念,而是直接上一条公式,怎么转换度数为弧度值:

弧度 = 角度 × π / 180

怎么应用到代码里面?

var angle = 60;    //假设角度为60度
 
var radian = angle * Math.PI / 180;    //计算出弧度
 
console.log( Math.cos(radian) );    //输出cos 60度的值

用法就这么简单!理论部分到此结束,接下来讲一点实战部分。

二、实战部分

做一个小游戏,有一把喵,一个靶子。喵头的角度可以旋转,靶子可以左右移动。现在要控制喵头对准移动的靶子射击,直到靶子射到烂为止。(下图为简单的图形界面,红点为锚点)

center_image

那么此时又有问题了,整个代码中最难的莫不就是碰撞,每次一喵,射出去的子弹一碰到靶子就视为打中靶子。

现在问题是,传统做法中的子弹如果速度太快的情况下,碰撞检测很大可能会失效(原理自己找())

center_image

有了这个思路,就可以扩展了,加上喵头的旋转,和靶子的移动需求后,实现这个碰撞就需要用到三角函数了!为了便于理解,画一下原理图:

center_image

center_image

根据原理图,我们可以细化代码实现的每一步的原理:

 

1、先计算出喵头跟靶子的垂直方向距离(dui_bian)。

2、将喵头的旋转的角度转化为弧度(radian)。

3、根据弧度(radian)和喵头跟靶子的垂直方向距离(dui_bian)两个已知量可以计算出武器真正射击的子弹到目标位置的水平距离(lin_bian)。

4、通过喵头跟靶子的垂直方向距离(dui_bian)和武器真正射击的子弹到目标位置的水平距离(lin_bian)与偏移值计算,可以得出一个坐标(x, y)。

5、判断坐标(x, y)是否在靶子内部,是则视为打中靶子,否则就是打偏了。

 

 

有人要问,本文的内容不是关于三角函数的应用吗?请注意第3步,确实是用到了三角函数的 Math.tan() 方法。

写一个伪代码吧:

var lin_bian = dui_bian / Math.tan( radian );      //计算出武器真正射击的子弹到目标位置的水平距离(lin_bian)

那么现在直接将旋转代码打出来:

const Quat = new Box3Quaternion(0, 0, 0, 1) //默认的旋转状态
function flyAround(plane) {
    plane.fixed = true//不受外力影响
    plane.gravity = false //取消重力对飞机的影响
    let speed = 0 //飞机的前进速度
    let rotation = 0 //飞机的旋转弧度
    let rotSpeed = 0.1 //飞机当前的旋转速度
    loop(plane, () => {
        const sdx = Math.cos(rotation) * speed //用余弦计算x轴上的速度
        const vz = Math.sin(rotation) * speed //用正弦计算z轴上的速度
        plane.velocity.set(sdx, 0, vz) //更新飞机当前的速度
        plane.meshOrientation = Quat.rotateY(rotation) //按当前旋转弧度更新飞机的朝向
        if (rotation > Math.PI || rotation < -Math.PI) {//当飞机旋转到达完全相反的方向(180度)
            rotSpeed *= 1 //飞机改变旋转方向
        }
        rotation += rotSpeed //更新飞机的旋转弧度
    })
}
const plane = world.querySelector('#实体1-2') //获取场景中的飞机实体
flyAround(plane) //让飞机动起来

async function loop(entity, fn) {
    while (!entity.destroyed) { //不断循环直到实体不在场景里
        fn()
        await sleep(60) //每60毫秒执行一次fn, 相当于一秒内能执行16.666次
    }
}
function flyAround(planea) {
    planea.fixed = true//不受外力影响
    planea.collides = false//允许碰撞\w
    planea.gravity = false //取消重力对飞机的影响
    let speed = 0 //飞机的前进速度
    let rotation = 0 //飞机的旋转弧度
    let rotSpeed = 0.1 //飞机当前的旋转速度
    loop(planea, () => {
        const sdx = Math.cos(rotation) * speed //用余弦计算x轴上的速度
        const vz = Math.sin(rotation) * speed //用正弦计算z轴上的速度
        planea.velocity.set(sdx, 0, vz) //更新飞机当前的速度
        planea.meshOrientation = Quat.rotateY(rotation) //按当前旋转弧度更新飞机的朝向
        rotation += rotSpeed //更新飞机的旋转弧度
    })
}
const planea = world.querySelector('#物品展示框架-1') //获取场景中的飞机实体
flyAround(planea)

正文结束!

本文有误之处,欢迎指点!

 

 


回复

上一页1 页 / 共 1下一页
guxia666guxia666

此贴肝了2个小时,所以打个广告不过分吧()

后室链接:

https://box3.codemao.cn/g/352066

神奇代码岛 (codemao.cn)

点赞0


评论


萌新大佬萌新大佬

《python》

点赞0


评论


萌新大佬萌新大佬

var lin_bian = dui_bian / Math.tan( radian );      //计算出武器真正射击的子弹到目标位置的水平距离(lin_bian)
c喵t Quat = new Box3Quaternion(0, 0, 0, 1) //默认的旋转状态
function flyAround(plane) {
    plane.fixed = true//不受外力影响
    plane.gravity = false //取消重力对飞机的影响
    let speed = 0 //飞机的前进速度
    let rotation = 0 //飞机的旋转弧度
    let rotSpeed = 0.1 //飞机当前的旋转速度
    loop(plane, () => {
        c喵t sdx = Math.cos(rotation) * speed //用余弦计算x轴上的速度
        c喵t vz = Math.sin(rotation) * speed //用正弦计算z轴上的速度
        plane.velocity.set(sdx, 0, vz) //更新飞机当前的速度
        plane.meshOrientation = Quat.rotateY(rotation) //按当前旋转弧度更新飞机的朝向
        if (rotation > Math.PI || rotation < -Math.PI) {//当飞机旋转到达完全相反的方向(180度)
            rotSpeed *= 1 //飞机改变旋转方向
        }
        rotation += rotSpeed //更新飞机的旋转弧度
    })
}
c喵t plane = world.querySelector('#实体1-2') //获取场景中的飞机实体
flyAround(plane) //让飞机动起来

async function loop(entity, fn) {
    while (!entity.destroyed) { //不断循环直到实体不在场景里
        fn()
        await sleep(60) //每60毫秒执行一次fn, 相当于一秒内能执行16.666次
    }
}
function flyAround(planea) {
    planea.fixed = true//不受外力影响
    planea.collides = false//允许碰撞\w
    planea.gravity = false //取消重力对飞机的影响
    let speed = 0 //飞机的前进速度
    let rotation = 0 //飞机的旋转弧度
    let rotSpeed = 0.1 //飞机当前的旋转速度
    loop(planea, () => {
        c喵t sdx = Math.cos(rotation) * speed //用余弦计算x轴上的速度
        c喵t vz = Math.sin(rotation) * speed //用正弦计算z轴上的速度
        planea.velocity.set(sdx, 0, vz) //更新飞机当前的速度
        planea.meshOrientation = Quat.rotateY(rotation) //按当前旋转弧度更新飞机的朝向
        rotation += rotSpeed //更新飞机的旋转弧度
    })
}
c喵t planea = world.querySelector('#物品展示框架-1') //获取场景中的飞机实体
flyAround(planea)

点赞0


评论


萌新大佬萌新大佬

飞机???

代码抄的吧。。。

点赞1


评论


来自远方的panda来自远方的panda

()

点赞0


评论


呵呵0486呵呵0486

栓Q歪瑞骂斥()

点赞2


评论


浮生awa浮生awa

真好(

点赞0


评论


红茶是只屑红茶是只屑

好耶前排

点赞0


评论


小树同学小树同学

收藏

点赞0


评论


Ezra__Ezra__

弧度制都没有讲单位圆是不是有点屑(()

点赞1


评论


黑客熊猫黑客熊猫

有时间的话就讲讲四元数呗,反正这个教程我是没听懂,涉及到了初中的知识,希望把初中知识讲的透彻一点

点赞0


评论


仙之鹤仙之鹤

emotion_编程猫_点赞

点赞0


评论