canvas曲线面片2

写前面

 

此篇的妹妹篇 是canvas曲面面片1 如果你没看 可以去了解下

在前面那篇 我们用了 双线性面片 还记得不?

这篇效果如下

 

 

 

这就是曲线面片的威力!  让这只萌萌の生物动起来了  视线跟随着小球 晃动着脑袋~

用到的是贝塞尔面片 准确的说是二次贝塞尔面片(下面说的都是二次) 当然有高次的 不过一般来说三次就够用了

先讲解下什么是贝塞尔面片 在这之前你得知道啥是贝塞尔曲线 (不懂的先自己找资料了解下)

上篇用到的是线性面片 只要4个控制点就够了 而贝塞尔面片 至少需要用到9个控制点   如图

但如何表示出曲面呢?这9个点 其实就可以表示出无线多个贝塞尔曲线了 也就形成了面片

跟上篇一样 可以先黄方向插值 随后蓝方向插值  当然反过处理也是ok的 然后拼接成三角图元就行了

现在是可以表示出曲面了 但是没有贴图 ! 还记得上篇我们是怎么处理贴图的不?

因为我们上次用的是canvas2d api  所以在处理的时候 对一个三角图元就一个drawImage 然后解线性方程组 算出transform中的矩阵

这篇我用的是webgl 不需要结出矩阵的值了 只要给出纹理坐标就行 但是要注意 webgl坐标系和图片坐标是相反的 !

 

直接看那部分关键代码吧 如下

可以看到 处理循环中的逻辑和上一篇是差不多的 只是把获取插值坐标函数分离了出来

这里有个maps数组 这个就是存储的纹理坐标了  因为坐标系的原因(相反的) 所以 1-

贝塞尔面片原理大致就是这样了~

 

但那个萌萌の生物是怎么形成的呢? 这个生物需要很多个面片  看我的img包你就能猜到大概了

我这里用了5张纹理  工厂生成了5个面片对象

光是这样萌萌の生物是不会动的!

还得根据某个坐标(这里是那个小球) 给那些需要偏移的控制点计算位置  如图

 

这里的微调工作繁琐到爆炸!如下 各种微调!

这里花费了我大量的精力 为了就是使面部动作生动 对各个控制点给参数。。各种微调

还有一开始把各个面片合成原始图像的位置 也是各种微调!

 

这玩意儿还是要有个编辑器才行  设定各种终止 初始值 做各种动画插值变换

再对人物细分 如 对眉毛 腮红也单独来个面片  一定会非常nice

不过 现阶段是不打算考虑做编辑器这种事的  这个优先级很后 。。

再说了 市面上应该有这种编辑器的吧(我也不清楚)

最重要的还是实现的思想

 

 

demo源码  用chrome打开  

 

转载于:https://www.cnblogs.com/daidaidai/p/5525582.html

import numpy as np import matplotlib.pyplot as plt from mpl_toolkits.mplot3d.art3d import Poly3DCollection # 生成数据 Round = np.array([0, 1, 2]) # 横轴 Round A1 = np.array([2, 4, 6, 8]) # 纵轴 A1 Z = np.array([ [17.1, 22.3, 23.8, 24.1], [14.5, 19.0,20.4, 20.9], [11.8, 15.1, 16.7, 17.3] ]) # 创建图形 X, Y = np.meshgrid(A1, Round) fig = plt.figure(figsize=(8, 6)) ax = fig.add_subplot(111, projection='3d') # 绘制3D曲面 for i in range(Z.shape[0]): # 绘制每个数据线条,并标注关键点 ax.plot(Y[i], X[i], Z[i], '-o') ax.plot(Y[i], X[i], np.zeros_like(Z[i]), color='gray', alpha=0.5) # 填充每个四边形面 for j in range(len(A1) - 1): verts = [ [Y[i, j], X[i, j], 0], [Y[i, j + 1], X[i, j + 1], 0], [Y[i, j + 1], X[i, j + 1], Z[i, j + 1]], [Y[i, j], X[i, j], Z[i, j]] ] ax.add_collection3d(Poly3DCollection([verts], color=plt.cm.viridis(i / len(Round)), alpha=0.4)) # 在每个关键点上添加注释 for j in range(Z.shape[1]): ax.text(Y[i, j], X[i, j], Z[i, j] + 0.03, f'{Z[i, j]:.2f}', color='black', ha='center') # 绘制每个点之间的连接线 for j in range(Z.shape[1]): ax.plot(Y[:, j], X[:, j], Z[:, j], '--', color='gray') # 设置标签 ax.set_xlabel('Round') ax.set_ylabel('A1') ax.set_zlabel('Cooperation Rate') # 显示图像 plt.show() # 绘制无直线3D瀑布图 import matplotlib.pyplot as plt import matplotlib.ticker as ticker from mpl_toolkits.mplot3d.art3d import Poly3DCollection import numpy as np def line_3d(x, y, z, x_label_indexs): """ 在y轴的每个点,向x轴的方向延伸出一个折线面:展示每个变量的时序变化。 x: x轴,时间维,右边。 y: y轴,变量维,左边。 z: z轴,数值维。二维矩阵,y列x行。每一行是对应变量的一个时间序列。 x_label_indexs: 需要标注的时间点。 """ x_num = len(x) y_num = len(y) if z.shape[0] != y_num or z.shape[1] != x_num: return -1 # 制作坐标格点(z中每个点对应的x、y坐标) X, Y = np.meshgrid(x, y) # 初始化 canvas = plt.figure() # 创建画布 axs = canvas.add_subplot(111, projection='3d') # 添加三维子图 # 若把111改成234,则意思是:创建一个2*3的网格,并在第4个格子中创建一个axes # 绘制折线面
最新发布
03-12
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值