【问题标题】:Drawing a circle with triangles WebGL用三角形 WebGL 画一个圆
【发布时间】:2015-09-25 11:16:01
【问题描述】:

我是 WebGL 的新手,正在尝试使用 triangle_fan 绘制一个圆圈。

我设置了变量

var pi = 3.14159;
var x = 2*pi/100;
var y = 2*pi/100;
var r = 0.05;

points = [ vec2(0.4, 0.8) ]; //establish origin

然后用这个for循环画圆。

for(var i = 0.4; i < 100; i++){
    points.push(vec2(r*Math.cos(x*i), r*Math.sin(y*i)));
    points.push(vec2(r*Math.cos(x*(i+1)), r*Math.sin(y*(i+1))));
}

问题是当我增加时,我实际上又在推动第二点,这是我不想做的。

另外,下图是绘制的:/

【问题讨论】:

    标签: javascript for-loop geometry webgl draw


    【解决方案1】:

    我没有足够的声誉来评论 mlkn 的回答,但我认为他缺少一件。这是我最终使用他的示例的方式

    vec2 center = vec2(cX, cY); 
    
    points.push(center);
    for (i = 0; i <= 200; i++){
        points.push(center + vec2(
            r*Math.cos(i*2*Math.PI/200),
            r*Math.sin(i*2*Math.PI/200) 
        ));
    }
    

    否则,如果循环开始时提供的200 是计算中给定的200 (r*Math.cos(i*2*Math.PI/200)) 的一部分,则只会绘制圆的一部分。另外,没有在循环计算中添加i,点都是相同的值,形成一条线。

    【讨论】:

      【解决方案2】:

      使用三角扇,您不需要复制顶点。 WebGL 将从 [A,B,C,D,E] 数组以 TRIANGLE_FAN 模式形成 ABC、ACDADE 三角形。

      另外,您没有考虑球体的中心。我不明白为什么i = 0.4

      这是您的代码的更正版本:

      vec2 center = vec2(cX, cY); 
         
      points.push(center);
      for (i = 0; i <= 100; i++){
          points.push(center + vec2(
              r*Math.cos(i * 2 * Math.PI / 200),
              r*Math.sin(i * 2 * Math.PI / 200) 
          ));
      }
      

      此外,如果您想绘制一个球体,您通常可以绘制一个三角形或 gl.point 并丢弃片段着色器中的圆外像素。

      【讨论】:

      • 在 WebGL 和 ES2.0 中,您总是必须使用自定义着色器。如果没有自定义着色器(清除除外),就无法在这些 API 中绘制任何内容。最重要的是(a)gl.POINTS 绘制正方形而不是圆形,并且(b)WebGL/ES2.0 只要求 MAX_POINT_SIZE 为 1.0,因此不能保证您能够绘制任意大小的点。
      • 感谢您的澄清!编辑答案。非自定义着色器是指由外部库为用户生成的着色器,作为材质的一部分。
      • @RamilKudashev 你好,在这里更正我......因为一个完整的圆从 theta=0 - 2*PI 跨越并生成多个点,我们必须划分这个间隔,例如将这个间隔分成 200点我们除以 2*PI/200 并且由于范围是从 0 到 2*PI ,i(计数器变量)从 0 到 200(点总数)?
      【解决方案3】:

      Ramil 和 Nicks 的回答对我帮助很大,我想在这里补充一点。

      对于一些可能会感到困惑的人,为什么几乎每一代圈子都会处理这一步

      i*2*Math.PI/200 --->(i*2*Math.PI/someNumber)
      

      并且循环从0 to 200---&gt; again 0 to someNumber 开始,这是它的工作原理,因为一个完整的圆从0 to 2*Math.PI 跨越并按点绘制一个圆,我们可能需要更多点,否则圆点之间会有一些间隙沿着边缘,我们将其划分为一些区间,有效地给出更多的点来绘制。假设我们需要将区间从 0 到 2*PI 划分为 800 个点,我们这样做是通过

      const totalPoints=800;
      
      for (let i = 0; i <= totalPoints; i++) {
         const angle= 2 * Math.PI * i / totalPoints;
         const x = startX + radius * Math.cos(angle);
         const y = startY + radius * Math.sin(angle);
         vertices.push(x, y);
      }
      

      由于循环从 0 变为 800,因此最后一个值将等于 2*Math.PI*800/800,给出区间的最后一个值 [0,2*PI]

      【讨论】:

        猜你喜欢
        • 2015-08-12
        • 2023-03-19
        • 2014-05-20
        • 1970-01-01
        • 1970-01-01
        • 2017-12-04
        • 1970-01-01
        • 1970-01-01
        • 2012-10-20
        相关资源
        最近更新 更多