数学思维+C语言画小猪佩奇,来试试?
用C语言画小猪佩奇,
你能想到什么实现方式?
No, no, no~
让我们玩点生猛的。
直接编辑代码,
用命令行(CMD)编译及运行!
(此处安利Sublime,瞬间提升逼格的神器)
然而,
CMD只能显示字符
(不依赖第三方软件的话)
难道……
对
没错
你没有想错
让我们来用ASCII码画图!
以下是步骤:
当然不是了!!
要学会魔法,
我们还要了解一些基础知识。
(突然正经分割线)
GIF
显示图案
没有颜色的地方,输出空格,
有颜色的地方,输出“.+!=#@”等符号。
(这里不是乱码)
眯上眼睛看符号矩阵
是不是能分出不同的灰度?
GIF
计算图形
字符输出的行和列,
我们可以看成是坐标轴。
很自然的,
我们引入平面几何。
由一条直线分割开的平面
说明:
为了让输出的图形符合我们对象限的认知,y从1到-1,而x从-1到1;
由于每一个所占的空间不是正方形,而是矩形,因此行和列(x轴和y轴)的步长不同
GIF
由多条相交直线分割开的平面:
GIF
由两条平行直线构成粗线
GIF
理论上,
这样的操作能把所有图形画出来,
即使是曲线也可以通过化曲为直绘制
(毕竟都是像素点了-_-||)
虽然这种方法可以表示曲线,
但为免太过繁琐。
既然我们把行列看作坐标,
那就用平面几何的方式来解决吧!
(椭)圆
GIF
(效果差,看不出来)
(椭)圆面:
GIF
(椭)圆环
GIF
双曲线的内部
GIF
爱心曲线
GIF
我再略施魔法
GIF
拿去表白吧~
形体组合
GIF
这个时候,
我们就可以为小猪佩奇
拟合一些基本平面几何元素,
经过一系列的组合,
就可以勾勒出小猪佩奇的形状了。
先试试简单形体的组合
两个(椭)圆形的组合
GIF
如果有n个(椭)圆组合的话,
岂不是要写n个这样的语句……
No,no,no~
当然是再写一个函数了
我们引入符号距离函数
(SDF,SignedDistance Function)。
说明:
x表示一个点,Ω表示某个形状,∂Ω表示这个这个形状的边界。d(i,j)是距离函数。
也就是说,如果某个点在形状外,则返回该点和边界的距离(d),反之,则返回距离的相反数(-d)。
这样一来,
我们不但能够判断点是否在形状里,
还能额外获得该点与边界的位置关系。
你知道这意味着什么吗?
我们可以直接画描边的形状!!!
好的,来实践一下。
先来绘制一个描边的圆形。
(因为圆形的边界距离函数最好表示)
描边的圆
GIF
图形的补集
GIF
多个描边图形的并
(即多个SDF值取最小)
GIF
用这种方式可以拼出佩奇的吹风机头
多个描边图形的交
(即多个SDF值取最大)
GIF
GIF
用这种方式可以拼出佩奇微笑的嘴
到这里就够了吗?
追求完美的我们,
怎么可能止步于此呢!
描边的优化
GIF
可以看到,
不同方向的边线,
如果能够用“|/=\”表示,
就会好看很多。
比如,这样:
===
//................\\
\\................//
===
我们再引入SDF函数的梯度,
用atan2求出梯度的角度
来表示边线法线的方向。
我们用差分来求近似值。
GIF
发挥想象力,
组合形状,比如福禄
用各种圆形
交、并、求补、挤压、旋转,
锵锵锵锵!~
GIF
完整代码:
编译运行时
更改a的大小
可实现更改精致程度。
GIF
每天改变一点点,
做精致的猪猪女孩。