用户:
guxia666查看: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°=π / 2】,【180°=π】,等号的左边是度数,右边是弧度。
是否回忆起来一个这么的例子,【 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度的值
用法就这么简单!理论部分到此结束,接下来讲一点实战部分。
二、实战部分做一个小游戏,有一把喵,一个靶子。喵头的角度可以旋转,靶子可以左右移动。现在要控制喵头对准移动的靶子射击,直到靶子射到烂为止。(下图为简单的图形界面,红点为锚点)

那么此时又有问题了,整个代码中最难的莫不就是碰撞,每次一喵,射出去的子弹一碰到靶子就视为打中靶子。
现在问题是,传统做法中的子弹如果速度太快的情况下,碰撞检测很大可能会失效(原理自己找())

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


根据原理图,我们可以细化代码实现的每一步的原理:
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)
正文结束!
本文有误之处,欢迎指点!
萌新大佬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
评论