前端图形学(二十)——退后!!我要开始进入3D世界了[通俗易懂]

前端图形学(二十)——退后!!我要开始进入3D世界了[通俗易懂]写在前面先说好,今天所说的3D并不是大家惯性思维说3D就想到了WebGL,那么接下来的文章都是基于Canvas2d来模拟3D空间~那么要模拟3维

欢迎来到【畅哥聊技术】前端图形学相关技术文章,更多精彩内容持续更新中,敬请关注。

前端图形学(二十)——退后!!我要开始进入3D世界了[通俗易懂]

写在前面

先说好,今天所说的3D并不是大家惯性思维说3D就想到了WebGL,那么接下来的文章都是基于Canvas2d来模拟3D空间~

那么要模拟3维世界,那么我们不得不提到一个新的名词:第三维度~

第三维度

前端图形学(二十)——退后!!我要开始进入3D世界了[通俗易懂]

这个不难理解,我们在Canvas2d中有两个坐标轴,X,Y,那么要模拟3D效果,那么我们就得抽象一个Z 轴出来 ,如上图,这个Z轴是垂直于我们的屏幕。

我们接下来规定,Z轴的正方向是向垂直屏幕向里为,相反则为负方向。

透视图

什么是透视图?一句话概括:近大远小!!!

物体远离视线,那么就会越来越小,直到消失在屏幕上,消失的时候的那一个点我们称之为 消失点

那么怎么在2维空间去模拟3D世界的呢?也就是说我们要把3空间的坐标转换到2d屏幕上来。

原理:

  1. 放大或缩小物体
  2. 让它靠近或者远离消失点
前端图形学(二十)——退后!!我要开始进入3D世界了[通俗易懂]

透视图公式如上图

scale = f1 / (f1 + z)

其中f1可以理解为我们的眼睛距离屏幕的距离

z为物体离屏幕的距离。

怎么理解这个公式呢?再来看张图:

前端图形学(二十)——退后!!我要开始进入3D世界了[通俗易懂]

假如我们的Z轴为0,小球此时应该在(400,300)的位置,这时候,我们刚好可以看到小球的全部。scale = 200 / (200+0) = 1;

此时,如果我们把小球向Z轴的正方向移动200的时候,那么此时的scale = 200 / (200 + 200) = 0.5; 也就是说,小球的scaleX和scaleY都将变成.5 ,还有小球的xy坐标也将是之前的一半~从图中可以看出来,移动后的小球的坐标是(200,150)

有了上面的基础,接下我们的示例就好展开了。请看~

前端图形学(二十)——退后!!我要开始进入3D世界了[通俗易懂]

效果分析:

  • 默认情况下,小球Z轴为0,那么可正常随着鼠标移动
  • 注册键盘事件,按下上方向键的时候,我们不断的放大Z值,那么小球对应的缩小,按方向下键的时候,Z值不断缩小 ,小球变大
  • 当鼠标Z轴不断增大,再去移动鼠标,发现小球和鼠标之间就形成了视差的效果了。

实现过程:

  1. 定义x,yz,默认分别为0,f1 = 200以及消失点坐标(width>>1,height>>1)
  2. 实例化小球。
  3. 注册鼠标事件和键盘事件,并且在键盘事件中处理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和缩放小球的属性上~

完整代码:

前端图形学(二十)——退后!!我要开始进入3D世界了[通俗易懂]

应用

示例:

前端图形学(二十)——退后!!我要开始进入3D世界了[通俗易懂]

在实现这个示例之前,我们还需要对小球类进行一次改造才行。我们依次给小球添加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);

核心代码截图:

前端图形学(二十)——退后!!我要开始进入3D世界了[通俗易懂]

完整代码请私信我

总结:

小球在三维空间的中缩放比例的计算公式为:

var scale = f1 / (f1 + z);

其中f1为景深,z为小球的z轴大小。

三维空间的坐标如何映射为2维平面上

ball.x = hideX + x * scale;
ball.y = hideY + y * scale;

最后就是一些之前的物理公式的运用了。

以上是今天所有的分享内容。喜欢的请点赞关注,不喜欢的解散~~

这里是【畅哥聊技术】前端图形学相关技术文章,更多精彩内容持续更新中。。。

未完待续。。。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
转载请注明出处: https://daima100.com/12006.html

(0)

相关推荐

  • powerDisigner使用「建议收藏」

    powerDisigner使用「建议收藏」最近要忙期考,但还是决定每天抽点空来写CodeSmith的系列文章了,在此实在不敢用教程这个词语,毕竟自己对CodeSmith了解的也不是很多,有很多牛人都在博客园发布了不少关于CodeSmith的文

    2023-04-17
    118
  • navicat调节字体大小_页面字体大小怎么调

    navicat调节字体大小_页面字体大小怎么调Navicat是一套快速、可靠和全面的数据库管理工具,专门用于简化数据库管理和降低管理成本。Navicat图形界面直观,提供简便的管理方法,设计和操作MySQL、MariaDB、SQL Server、

    2023-06-10
    100
  • MySQL优化索引_mysql 索引优化

    MySQL优化索引_mysql 索引优化MySQL优化中,最重要的优化手段就是索引,也是最常用的优化手段 索引简介: 索引:关键字与数据位置之间的映射关系 关键字:从数据中提取,用于标识,检索数据的特定内容 目的:加快检索 索引检索为什么快

    2023-02-04
    108
  • Python字典:更高效、更便捷的数据存储方案

    Python字典:更高效、更便捷的数据存储方案Python中的字典是一种键-值对(key-value)存储的数据结构,其它编程语言中也有类似结构,比如JavaScript的对象,Java的HashMap。字典的特点在于通过一个唯一的键(key)来关联一个值(value),这与列表(list)、元组(tuple)等线性数据结构不同。

    2023-12-29
    55
  • 深入浅出eslint——关于我学习eslint的心得「终于解决」

    深入浅出eslint——关于我学习eslint的心得「终于解决」ESLint属于一种QA工具,是一个ECMAScript/JavaScript语法规则和代码风格的检查工具,可以用来保证写出语法正确、风格统一的代码。 ESLint旨在完全可配置,它的目标是提供一个插件化的javascript代码检测工具。这意味着您可以关闭每个规则,只能使用基…

    2023-08-18
    72
  • Mysql第8天_MySQL慢查询

    Mysql第8天_MySQL慢查询2022-09-10 MySQL中的自连接 何谓自连接? 自连接,即为自己查自己,本表查询本表。 自连接一般使用于何种地方? 例如:如果在设计一张表中,表中的字段名包含id(省份/市的邮政编码),ti

    2023-06-05
    108
  • apache 大数据_hadoop开发教程

    apache 大数据_hadoop开发教程一、Azkaban API概述 通常,企业里一般不用使用web UI去设置或者执行任务,只是单纯的在页面上查看任务或者排查问题,更多的是通过Azkaban API去提交执行任务计划。Azkaban提供

    2023-05-17
    94
  • c++选择排序算法代码_java排序代码

    c++选择排序算法代码_java排序代码前言:排序就是重新排列表中的元素,是表中的元素满足按关键字递增或递减的过程。为了查找方便,通常要求这些通常要求计算机中的,表示按关键字有序的算法

    2022-12-14
    105

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注