前面我们学习了复杂的物体都可以由多个三角形组成。所以可以用多个三角形去拟合一个圆形。
如图我们可以把圆等分成 N 份,用 N 个三角形去拟合圆。
设圆上任意一个点跟 y 轴的夹角为 θ, 可得到点的坐标为 (rsin(θ), rcos(θ)), 而 θ 的取值范围是 [0,2π]。
var N = 100;
var vertexData = [0.0, 0.0];
var r = 0.5;
for (var i = 0; i <= N; i++) {
var theta = i * 2 * Math.PI / N;
var x = r * Math.sin(theta);
var y = r * Math.cos(theta);
vertexData.push(x, y);
}
N = 100, 用 101 个点(第 1 个点和第 101 个点重合)把圆等分成 100 个三角形。加上原点用 gl.TRIANGLE_FAN 画扇形就可以了。
完整代码如下:
// vertex shader
var VERTEX_SHADER_SOURCE =
'attribute vec4 a_Position;\n' +
'void main() {\n' +
' gl_Position = a_Position;\n' +
'}\n';
// fragment shader
var FRAGMENT_SHADER_SOURCE =
'void main() {\n' +
' gl_FragColor = vec4(1.0,0.0,0.0,1.0);\n' +
'}\n';
var canvas = document.getElementById("canvas");
var gl = canvas.getContext('webgl');
if (!initShaders(gl, VERTEX_SHADER_SOURCE, FRAGMENT_SHADER_SOURCE)) {
alert('Failed to init shaders');
}
var N = 100;
var vertexData = [0.0, 0.0];
var r = 0.5;
for (var i = 0; i <= N; i++) {
var theta = i * 2 * Math.PI / N;
var x = r * Math.sin(theta);
var y = r * Math.cos(theta);
vertexData.push(x, y);
}
var vertices = new Float32Array(vertexData);
initVertexBuffers(gl, vertices);
gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.drawArrays(gl.TRIANGLE_FAN, 0, vertices.length / 2);
后面我们还会用同样的方法画一个球体。