总结的和到位的帖子奉上:我的原则就是实用,既然有帖子,那么大家来观摩一下吧
echarts-gl中3d曲面UV参数详解
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/harsima/article/details/96270406
文章目录
前言
什么是UV
echarts中的UV解析
利用UV创建模型
利用UV确定贴图位置
前言
在echart-gl中3D曲面的数据除曲面方程及普通数据[x,y,z]外,还有一个带有UV坐标系的数据,即[x, y, z, u, v]。这里将重点讲述u,v点在echart-gl中的应用及部分原理。因个人未读过计算机图形相关课程,一部分理论仅为个人理解,如有错误请指正。
什么是UV
与我们熟悉的三维坐标系不同,UV坐标类似于三维空间的投影,它用两个点去映射三维模型中的点。其中U代表水平方向,V代表垂直方向。UV坐标常用在材质贴图中。
上图为UV坐标系的说明,其中地图为简单的模型贴图,沿坐标轴方向为正。
echarts中的UV解析
在echarts中UV坐标不仅能够影响贴图顺序点,同时也会影响模型的创建。这里我们一步步讲解,先讲模型创建,再讲贴图。
利用UV创建模型
如果我们想要做下面这种类型的立方体侧面,通过简单的三维坐标系(xyz)很难实现,此时我们需要使用UV参数。
利用UV创建模型和利用笛卡尔坐标系创建模型有些许不同。
在正常三维坐标系中,创建自定义面,需要先创建X轴横向数据,然后逐行创建Y轴数据,这样在echarts中才会形成需要的自定义面。
下面的代码中创建的是一个覆盖于XY轴的平面,效果如图所示,需要特别注意数据点的顺序(先创建X轴横向数据,然后逐行创建Y轴数据)
code
data: [
[0,0,0],[1,0,0],
[0,1,0],[1,1,0]
]
1
2
3
4
效果预览
然而在使用UV创建时,其数据顺序则以UV顺序为准。这点在官方文档中有如下描述:
对于参数方程来说,每一项需要存储五个数据,分别是 x, y, z 和参数 u, v。而数据的索引按照u, v 的顺序。
以本节第一图为例,我们从要下往上创建一个侧面。分析图片可知,底面和顶面的四个点坐标如下:
// 这里是逆时针点的顺序,你也可以使用顺时针顺序,不会影响最终效果
// 底面坐标
[0,-1,-1],[1,0,-1],[0,1,-1],[-1,0,-1],
// 顶面坐标
[0,-1,1],[1,0,1],[0,1,1],[-1,0,1]
1
2
3
4
5
6
在不考虑贴图位置和展现方式时,底面的垂直方向值为0,顶面的垂直方向值为1。底面和顶面的水平方向值均为从0-1的变化值。同时需要注意的是,用UV创建模型时,必须使曲面闭合。故上面坐标在整理后如下所示:
// 底面和顶面都需要面闭合,所以将第一个坐标点复制一个到该组末尾
// [x,y,z,u,v]
[0,-1,-1,0,0],[1,0,-1,0.25,0],[0,1,-1,0.5,0],[-1,0,-1,0.75,0],[0,-1,-1,1,0],
[0,-1,1,0,1],[1,0,1,0.25,1],[0,1,1,0.5,1],[-1,0,1,0.75,1],[0,-1,1,1,1],
1
2
3
4
效果预览
至此,我们已经可以用UV来创建一个自定义面了。但需要注意的是,上面的模型数据在调转上下顺序后,增加贴图则会出现贴图显示错误的问题。这就是我们接下来要说的问题了。
利用UV确定贴图位置
echarts中的贴图原点坐标个人感觉很奇怪。
如上节所说,如果我们将数据按照从上到下的顺序重新排列,加上贴图,则会出现贴图顺序颠倒的情况。如下图所示:
经过分析,个人总结为:
如果模型是从上往下创建的,则贴图的原点坐标在图片的左上角;
如果模型是从下往上创建的,则贴图的原点坐标在图片的左下角;
这里从数学上我个人感觉难以理解,但为了防止在增加贴图时出现问题,个人非常建议按照贴图的顺序去创建模型,如果设计时,贴图的原点在左下角,那么创建模型时就从下往上创建,反之亦然。
如果在贴图时,我们需要对贴图进行偏移,比如立方体侧面开始点的贴图不想定位到原点,这样你可以在图片中测量你需要的偏移量,坐标系仍然以本章第一图为准,原点坐标以实际为准即可。
下面放出贴图后的完整代码
var option = {
backgroundColor: '#fff',
color: '#fff',
xAxis3D: {
type: 'value'
},
yAxis3D: {
type: 'value'
},
zAxis3D: {
type: 'value'
},
grid3D: {
viewControl: {
}
},
series: [{
type: 'surface',
shading: 'color',
parametric: true,
colorMaterial: {
detailTexture: 'map.jpg'
},
data: [
[0,-1,-1,0,0],[1,0,-1,0.25,0],[0,1,-1,0.5,0],[-1,0,-1,0.75,0],[0,-1,-1,1,0],
[0,-1,1,0,1],[1,0,1,0.25,1],[0,1,1,0.5,1],[-1,0,1,0.75,1],[0,-1,1,1,1],
]
}]
}
喜欢就关注我吧,我会努力更新的!