和大家谈谈我为什么选择图形这条路(二)

简介: 数学基础img1.1 坐标系与向量之以canvas为例实现坐标系的转换这里首先我要先从对坐标系进行转换进行讲起,那为什么我要先讲坐标系的转换问题:因为转换坐标系对于图形学绘制而言,实在太重要了,后续所有图形的绘制都要用到这个思想,具体为什么我们先从一个之前前面看到的图形讲起:首先经过一顿坐标点换算,我们得出每个点具体的坐标(这里我用了一个Rough.js的库,绘制一个手绘风格的图像),最终算出山顶的坐标就是 (-80, 100) 和 (80, 100),山脚的坐标就是 (-180, 0)、(20, 0)、(-20, 0)、(180, 0),太阳的中心点的坐标就是 (0, 150)。i

数学基础

image.png


1.1 坐标系与向量之以canvas为例实现坐标系的转换


这里首先我要先从对坐标系进行转换进行讲起,那为什么我要先讲坐标系的转换问题:因为转换坐标系对于图形学绘制而言,实在太重要了,后续所有图形的绘制都要用到这个思想,具体为什么我们先从一个之前前面看到的图形讲起:

首先经过一顿坐标点换算,我们得出每个点具体的坐标(这里我用了一个Rough.js的库,绘制一个手绘风格的图像),最终算出山顶的坐标就是 (-80, 100) 和 (80, 100),山脚的坐标就是 (-180, 0)、(20, 0)、(-20, 0)、(180, 0),太阳的中心点的坐标就是 (0, 150)。

image.png


坐标系变化的方案如下:


1:首先,我们通过 translate 变换将 Canvas 画布的坐标原点,从左上角 (0, 0) 点移动至 (256, 256) 位置,即画布的底边上的中点位置。接着,以移动了原点后新的坐标为参照,通过 scale(1, -1) 将 y 轴向下的部分,即 y>0 的部分沿 x 轴翻转 180 度,这样坐标系就变成以画布底边中点为原点,x 轴向右,y 轴向上的坐标系了。


2:山顶的坐标就是 (-80, 100) 和 (80, 100),山脚的坐标就是 (-180, 0)、(20, 0)、(-20, 0)、(180, 0),太阳的中心点的坐标就是 (0, 150)。


3:其实这个思路是非常重要的,因为这个例子要绘制的图形很少,所以还不太能体现使用坐标系变换的好处。不过,可以想一下,在许多应用场景中,我们都要处理成百上千的图形。如果这个时候,我们在原始坐标下通过计算顶点来绘制图形,计算量会非常大,很麻烦。那采用坐标变换的方式就是一个很好的优化思路,它能够简化计算量,这不仅让代码更容易理解,也可以节省 CPU 运算的时间。


image.pngimg


1.2 坐标系与向量描述点和线段(基础)


不管我们用什么绘图系统绘制图形,一般的几何图形都是由点、线段和面构成。其中,点和线段是基础的图元信息,因此,如何描述它们是绘图的关键。在讲解完转换坐标系后,那么接下来带大家真正开启数学知识中的向量基础

这里我先用一些代码来表示一些向量的基础知识:

image.png


接下来我们进行实战部分,用刚才介绍的向量知识来绘制一个随机的小树,这里的枝干方向是随机的。


1:第一步还是非常重要的一个坐标变换,这里,我们要做的变换是将坐标原点从左上角移动到左下角,并且让 y 轴翻转为向上。


2:我们定义一个画树枝的函数 drawBranch。


3:创建一个单位向量 (1, 0),它是一个朝向 x 轴,长度为 1 的向量。然后我们旋转 dir 弧度,再乘以树枝长度 length。这样,我们就能计算出树枝的终点坐标了。(这里我封装了一个class Vector2D里面定义了一一些方法,包括向量的旋转)


4:我们可以从一个起始角度开始递归地旋转树枝,每次将树枝分叉成左右两个分枝。这样,我们得到的就是一棵形状规律的树。


5:我们修改代码,加入随机因子,让迭代生成的新树枝有一个随机的偏转角度。这样,我们就可以得到一棵随机的树。


image.png


1.3 向量和参数方程描述曲线


接下来会从向量过渡到参数方程的阶段:


1:向量绘制折线的方法来绘制正多边形,当多边形的边数非常多的时候,这个图形就会接近圆,将多边形的边数设置得很大,我们就可以绘制出圆形。


2:由于很难精确到图形的位置和大小,并且换算的过程比较繁琐会很容易出错,但是为了画出更多样的以及更多的曲线样式,我们需要选择更好的模型,接下来自然会引出参数方程。


image.png

img


1.3.1 参数方程之基础图形


接下来还是先带大家熟悉一下参数方程的基础概念,首先以圆形与椭圆形进行举例,他们的参数方程比较相似,这里我把公式给大家展示出来。


在代码实现参数方程的过程中呢,这里我通过设置TAU_SEGMENTS的点的数量为60平均分摊到2π(360度)上,它们可以理解成这个圆或者这个椭圆由多少个坐标点来绘制而成,然后将一个个坐标点加入到数组中。然后将包含有60个点的数组坐标返回,传入我接下来封装的draw函数中。


image.png

image.png


这里再说一下抛物线的参数方程,当x0,y0为0时,经推导 t = x/ y,这里t的含义可以x除以y的值


image.png


接下来会通过一个小demo将我们的代码整合起来,这里的图片在分享的开始也和大家介绍过,通过抛物线,阿基米德螺旋线和星形线组成。


image.png


如果我们为每一种曲线都分别对应实现一个函数,就会非常笨拙和繁琐。那为了方便,这里我们采用函数式编程思想,封装一个更简单的javascript参数方程绘图模块,以此来绘制出不同的曲线。


那么封装的这个绘图模块的使用过程主要分为三步:


第一步,我们实现一个叫做 parametric 的高阶函数,它的参数分别是 x坐标的参数方程和y坐标的参数方程。


第二步,parametric 会返回一个函数,这个函数会接受几个参数,比如,start、end 这样表示参数方程中关键参数范围的参数,以及 seg 这样表示采样点个数的参数等等。在下面的代码中,当 seg 默认 100 时,就表示在 start、end 范围内采样 101(seg+1)个点,后续其他参数是作为常数传给参数方程的数据。


第三步,我们调用 parametric 返回的函数之后,它会返回一个对象。这个对象有两个属性:一个是 points,也就是它生成的顶点数据;另一个是 draw 方法,我们可以利用这个 draw 方法完成绘图

image.png


这里我们就不需要像之前一样,每一个图形线都实现其对应的一个函数,只需要统一调用我们封装好的高阶函数,传入我们的参数方程即可,最后统一调用draw函数进行绘制。


这样的话,通过这个封装好的javascript参数方程绘图模块,就可以绘制出很多有意思的图形。


1.4:仿射变换--拓展了解


接下来呢,仿射变换其实也是图形学需要了解的一个数学基础,但是由于时间关系,我会带大家简单了解一下其基本的概念。


这里先关注一下应用场景,痛点,解决方式和仿射变换。


前面我们学习了用向量表示的顶点,来描述曲线和多边形的方法。但是在实际绘制的时候,我们经常需要在画布上绘制许多轮廓相同的图形,难道这也需要我们重复地去计算每个图形的顶点吗?当然不需要。我们只需要创建一个基本的几何轮廓,然后通过仿射变换来改变几何图形的位置、形状、大小和角度。


仿射变换是拓扑学和图形学中一个非常重要的基础概念。利用它,我们才能在可视化应用中快速绘制出形态、位置、大小各异的众多几何图形。所以接下来我们就来说一说仿射变换的数学基础和基本操作,在以后的后续篇中在所有视觉呈现的案例中,是非常重要的。

image.png


仿射变换最基本的概念,大家可以记住就是 线性变换 + 平移 线性变换又分为(旋转和缩放) ,总结起来就是平移,旋转加缩放。


image.png


总结下来,合到一起就是左图的表达式,经过公示优化后为右面的矩阵形式,在改写的公式里,我们实际上是给线性空间增加了一个维度。换句话说,我们用高维度的线性变换表示了低维度的仿射变换!


以粒子动画应用场景举例,这个公式是非常重要的,它能在一定时间内生成许多随机运动的小图形,这类动画通常是通过给人以视觉上的震撼,来达到获取用户关注的效果。image.png

结束语

在前端整体迅猛发展的大环境下,因为产品需求的驱动,图形学方向技术发展也非常迅速,前端图形学属于一个比较小众的领域,甚至延伸到可视化方向依然属于一比较小众的领域,那么真正阻挡的技术门槛是什么呢?

其实就是对使用者的数学基础比较高,但当我们真正突破了这个技术门槛,甚至可视化方向上突破了WebGL这种更偏底层的门槛,在行业里我们会是特别非常有竞争力的。

那么本次文章还是先带大家来认识一下图形学,后续系列篇中会再延伸到动画、滤镜等其他视觉基础上。这里分享给大家一句话,学习技术的过程,是从接纳和记忆知识开始的,但绝不仅仅是接纳和记忆知识,而是需要深入思考,并自己总结和沉淀的。


image.png

相关文章
|
3月前
|
数据可视化 搜索推荐 Python
如何用mplfinance打造与众不同的K线图?红涨绿跌背后的实现原理!
【8月更文挑战第21天】在金融市场分析中,K线图是洞察市场动态的关键工具。Python的mplfinance库专为金融数据可视化设计,能高效绘制K线图。针对中国交易者习惯,需将上涨设为红色,下跌为绿色。首先安装mplfinance库,然后准备股票数据。使用自定义颜色函数配合`make_marketcolors`方法实现红涨绿跌效果。此设置让图表更直观,有助于快速把握市场趋势,同时mplfinance的强大功能支持进一步个性化图表。
91 0
|
5月前
技术经验分享:1.1显函数的图形
技术经验分享:1.1显函数的图形
16 0
|
5月前
|
数据可视化 测试技术 uml
如果更好的绘制UML图
如果更好的绘制UML图
40 0
|
JSON 前端开发 数据可视化
【图形基础篇】02 # 指令式绘图系统:如何用Canvas绘制层次关系图?
【图形基础篇】02 # 指令式绘图系统:如何用Canvas绘制层次关系图?
184 0
【图形基础篇】02 # 指令式绘图系统:如何用Canvas绘制层次关系图?
|
开发者 Python
绘图细节设置2|学习笔记
快速学习绘图细节设置2
131 0
绘图细节设置2|学习笔记
|
开发者 Python
绘图细节设置1|学习笔记
快速学习绘图细节设置1
110 0
绘图细节设置1|学习笔记
|
编解码 数据可视化 API
Qt开发技术:图形视图框架(一)基本介绍
Qt开发技术:图形视图框架(一)基本介绍
Qt开发技术:图形视图框架(一)基本介绍
|
数据可视化 数据挖掘 图形学
|
XML 缓存 前端开发
和大家谈谈我为什么选择图形这条路(一)
前端图形 从图形的角度带你领略前端的美 59篇原创内容 公众号 图形学这个领域目前来看是很好玩也很有前景的一个方向,当我们了解它的基础知识,get到它好玩地方的时候,我们可以很轻松延伸到可视化这一领域进行拓展。本文会尽量以很通俗很详细的方式来向大家介绍,希望读者有所收获。
和大家谈谈我为什么选择图形这条路(一)