javascript 用三角形画一个圆 WebGL

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/32780958/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 15:45:10  来源:igfitidea点击:

Drawing a circle with triangles WebGL

javascriptfor-loopgeometrywebgldraw

提问by user3295674

I'm new to WebGL and was trying to draw a circle with triangle_fan.

我是 WebGL 的新手,试图用triangle_fan 画一个圆圈。

I set up the variables

我设置了变量

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

And then drew the circle using this for loop.

然后使用这个 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))));
}

The issue is that I am actually pushing in the second point again when i increaseswhich I don't want to do.

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

Also, the image below is that is drawn :/ Circle? drawn

此外,下图是绘制的:/ 圆圈? 画

采纳答案by Ramil Kudashev

Using triangle fan you don't need to duplicate vertices. WebGL will form ABC, ACDand ADEtriangles from [A,B,C,D,E]array with TRIANGLE_FAN mode.

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

Also, you don't take into account center of your sphere. And i can't get why i = 0.4.

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

Here is corrected version of your code:

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

vec2 center = vec2(cX, cY); 

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

Also if you want to draw a sphere you could often draw one triangle or gl.point and discard pixels which are out of circle in fragment shader.

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

回答by Nick Beukema

I don't have enough reputation to comment on mlkn's answer, but I think there was one piece he was missing. Here's how I ended up using his example

我没有足够的声誉来评论 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) 
    ));
}

Otherwise, if the 200supplied in the start of the loop is a fraction of the 200given in the calculation (r*Math.cos(i*2*Math.PI/200)), then only a fraction of the circle will be drawn. Also, without adding in the ito the calculation in the loop, the points are all the same value, resulting in a line.

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

回答by Thakur Karthik

Both the Ramil and Nicks answer helped me lot, i would like to add a point here.

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

For some one who might be confused why almost every circle generation deals with this step

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

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

and the loop goes from 0 to 200---> again 0 to someNumber,Here is how it works,since a complete circle spans from 0 to 2*Math.PIand to draw a circle by points we might want more points or the circle points will be having some gaps between them along the edge,We divide this into intervals by some number effectively giving more points to plot.Say we need to divide the interval from 0 to 2*PI into 800 points we do this by

循环从 开始0 to 200---> 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);
}

Since the loop goes from 0 to 800 the last value will be equal to 2*Math.PI*800/800giving the last value of the interval [0,2*PI]

由于循环从 0 到 800,最后一个值将等于2*Math.PI*800/800给出间隔的最后一个值[0,2*PI]

回答by Andrew Luca

const canvas = document.getElementById("myCanvas");
const ctx = canvas.getContext("2d");
const circle = { x: 100, y: 100, r: 75 }

ctx.moveTo(circle.x, circle.y + circle.r)

for (let i = 0; i <= circle.r; i++) {
  ctx.lineTo(
    circle.x + circle.r * Math.sin(i * 2 * Math.PI / circle.r),
    circle.y + circle.r * Math.cos(i * 2 * Math.PI / circle.r)
  )
}

ctx.stroke()
<canvas id="myCanvas" width="200" height="200"
style="border:1px solid #d3d3d3;">
Your browser does not support the canvas element.
</canvas>