user3295674
user3295674

Reputation: 913

Drawing a circle with triangles WebGL

I'm new to WebGL and was trying to draw a circle with 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(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 increases which I don't want to do.

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

Upvotes: 3

Views: 20823

Answers (3)

Ramil Kudashev
Ramil Kudashev

Reputation: 1175

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

Also, you don't take into account center of your sphere. And i can't get why 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(i * 2 * Math.PI / 200),
        r*Math.sin(i * 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.

Upvotes: 2

Thakur Karthik
Thakur Karthik

Reputation: 3538

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

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.PI and 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

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/800 giving the last value of the interval [0,2*PI]

Upvotes: 1

Nick Beukema
Nick Beukema

Reputation: 111

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

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 200 supplied in the start of the loop is a fraction of the 200 given 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 i to the calculation in the loop, the points are all the same value, resulting in a line.

Upvotes: 5

Related Questions