大家好,我是考100分的小小码 ,祝大家学习进步,加薪顺利呀。今天说一说前端图形学(二十)——退后!!我要开始进入3D世界了[通俗易懂],希望您对编程的造诣更进一步.
欢迎来到【畅哥聊技术】前端图形学相关技术文章,更多精彩内容持续更新中,敬请关注。
写在前面
先说好,今天所说的3D并不是大家惯性思维说3D就想到了WebGL,那么接下来的文章都是基于Canvas2d来模拟3D空间~
那么要模拟3维世界,那么我们不得不提到一个新的名词:第三维度~
第三维度
这个不难理解,我们在Canvas2d中有两个坐标轴,X,Y,那么要模拟3D效果,那么我们就得抽象一个Z 轴出来 ,如上图,这个Z轴是垂直于我们的屏幕。
我们接下来规定,Z轴的正方向是向垂直屏幕向里为,相反则为负方向。
透视图
什么是透视图?一句话概括:近大远小!!!
物体远离视线,那么就会越来越小,直到消失在屏幕上,消失的时候的那一个点我们称之为 消失点
那么怎么在2维空间去模拟3D世界的呢?也就是说我们要把3空间的坐标转换到2d屏幕上来。
原理:
- 放大或缩小物体
- 让它靠近或者远离消失点
透视图公式如上图
scale = f1 / (f1 + z)
其中f1可以理解为我们的眼睛距离屏幕的距离
z为物体离屏幕的距离。
怎么理解这个公式呢?再来看张图:
假如我们的Z轴为0,小球此时应该在(400,300)的位置,这时候,我们刚好可以看到小球的全部。scale = 200 / (200+0) = 1;
此时,如果我们把小球向Z轴的正方向移动200的时候,那么此时的scale = 200 / (200 + 200) = 0.5; 也就是说,小球的scaleX和scaleY都将变成.5 ,还有小球的xy坐标也将是之前的一半~从图中可以看出来,移动后的小球的坐标是(200,150)
有了上面的基础,接下我们的示例就好展开了。请看~
效果分析:
- 默认情况下,小球Z轴为0,那么可正常随着鼠标移动
- 注册键盘事件,按下上方向键的时候,我们不断的放大Z值,那么小球对应的缩小,按方向下键的时候,Z值不断缩小 ,小球变大
- 当鼠标Z轴不断增大,再去移动鼠标,发现小球和鼠标之间就形成了视差的效果了。
实现过程:
- 定义x,yz,默认分别为0,f1 = 200以及消失点坐标(width>>1,height>>1)
- 实例化小球。
- 注册鼠标事件和键盘事件,并且在键盘事件中处理Z轴的大小来控制小球的位置。
核心代码:
let x =0,y = 0,z = 0;
var hideX = width >> 1,
hideY = height >> 1;
var f1 = 200;
var mouse = {x:0,y:0}
window.addEventListener(‘keydown’,e=>{
if(e.keyCode === 38){
z+=5;
}
if(e.keyCode === 40){
z -=5;
}
});
canvas.onmousemove = e =>{
mouse.x = e.pageX – canvas.offsetLeft;
mouse.y = e.pageY – canvas.offsetTop;
}
在事件循环函数中不停的去计算当前缩放比例scale,将三维坐标映射到二维画布上。
//因为f1+z作了除数,这里记得要作下判断 if(f1+z>0){ var scale = f1 / (f1 + z); ball.scaleX = ball.scaleY = scale; x = mouse.x - hideX; y = mouse.y - hideY; ball.x = hideX + x * scale; ball.y = hideY + y * scale; ball.render(context); } //将缩放比例分别作用在x.y和缩放小球的属性上~
完整代码:
应用
示例:
在实现这个示例之前,我们还需要对小球类进行一次改造才行。我们依次给小球添加3个属性
小球在3维空间的中xyz坐标 this.x3d = 0; this.y3d = 0; this.z3d = 0; //小球z轴的速度 this.vz = 0;
接下来我们依然采用了之前的老套路,随机生成200个小球,给他们随机的x和z的位置,y3d为同一值,因为这些小球在同一点落下。
为了更加符合视觉感观,小球的Z轴越大,我们应该要优先绘制,这时候,我们就要对小球依据z3d来进行排序了。
balls.sort((a,b)=>{//这 return b.z3d - a.z3d; })
循环函数中不断的计算scale值,这是核心;
var scale = f1 / (f1 + ball.z3d);
核心代码截图:
总结:
小球在三维空间的中缩放比例的计算公式为:
var scale = f1 / (f1 + z);
其中f1为景深,z为小球的z轴大小。
三维空间的坐标如何映射为2维平面上
ball.x = hideX + x * scale; ball.y = hideY + y * scale;
最后就是一些之前的物理公式的运用了。
以上是今天所有的分享内容。喜欢的请点赞关注,不喜欢的解散~~
这里是【畅哥聊技术】前端图形学相关技术文章,更多精彩内容持续更新中。。。
未完待续。。。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
转载请注明出处: https://daima100.com/12006.html