Drawing a circle with triangles WebGL
Solution 1
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.
Solution 2
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.
Solution 3
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]
Comments
-
user3295674 almost 2 years
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.
-
gman over 8 yearsIn WebGL and ES2.0 you always have to use custom shaders. There is no way to draw anything in those APIs without custom shaders (except for clearing). On top of that (a)
gl.POINTS
draws squares not circles and (b) WebGL/ES2.0 only require MAX_POINT_SIZE to be 1.0 so there's no guarantee you'll be able to draw arbitrary sized points. -
Ramil Kudashev over 8 yearsThank you for clarification! Edited answer. By non-custom shaders i meant shaders which are generated for user by external libraries as parts of materials.
-
Thakur Karthik over 4 years@RamilKudashev hello,Correct me here...Since a complete circle spans from theta=0 - 2*PI and to generate multiple points we have to divide this interval so for example diving this interval into 200 points we are dividing 2*PI/200 and since range is from 0 to 2*PI ,i (counter variable) goes from 0 to 200 (total number of points) ?