Reputation: 913
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 :/
Upvotes: 3
Views: 20823
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
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
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