球体的顶点与索引创建方法----以WebGL为例

上图,左图为一个球体的三维图,其中一个圆面以θ角(范围为[0,PI])的方式确定,该圆面在x-z坐标平面投影如右图,其中圆面上任意一点又由α确定(范围为[0,2PI])。

假定该球体半径为r,那么球面任意一点均可以用r,θ,α唯一确定,确定关系如下:

x=rsinθcosα;y=rcosθ;z=rsinθsinα

那么,可以将θ,α,均分为S+1份(也可以分别是不同的份数),然后可以得到(S+1)×(S+1)个点的坐标。

var SPHERE_DIV = 13;

  var i, ai, si, ci;
  var j, aj, sj, cj;
  var p1, p2;

  var positions = [];
  var indices = [];

  // Generate coordinates
  for (j = 0; j <= SPHERE_DIV; j++) {
    aj = j * Math.PI / SPHERE_DIV;
    sj = Math.sin(aj);
    cj = Math.cos(aj);
    for (i = 0; i <= SPHERE_DIV; i++) {
      ai = i * 2 * Math.PI / SPHERE_DIV;
      si = Math.sin(ai);
      ci = Math.cos(ai);

      positions.push(si * sj);  // X
      positions.push(cj);       // Y
      positions.push(ci * sj);  // Z
    }
  }

右边是从左边网格抽象出来的单个网格单元,记左上角P1的位置为(i,j),那么P1的值为jX(S+1)+i,而P2的值为P1+(S+1),注意该单个网格由于在(i,j)的位置,都可以确定P2以及P1+1,P2+1,剩余三个点,而这三个点都是i,j的下一轮,所以在取得索引值时候,上界均为S-1,而非S,绘制时候,选择gl.TRIANGLE,所以每次取到的索引号是(p1,p2,p1+1,p1+1,p2,p2+1)。

for (j = 0; j < SPHERE_DIV; j++) {
    for (i = 0; i < SPHERE_DIV; i++) {
      p1 = j * (SPHERE_DIV+1) + i;
      p2 = p1 + (SPHERE_DIV+1);

      indices.push(p1);
      indices.push(p2);
      indices.push(p1 + 1);

      indices.push(p1 + 1);
      indices.push(p2);
      indices.push(p2 + 1);
    }

posted @ 2022-07-09 11:23  JohnYang819  阅读(428)  评论(0编辑  收藏  举报