diff --git a/BivariateFunction/BivariateFunction.js b/BivariateFunction/BivariateFunction.js index f43f538..060ef1d 100644 --- a/BivariateFunction/BivariateFunction.js +++ b/BivariateFunction/BivariateFunction.js @@ -1,4 +1,17 @@ // PointLightedCube_perFragment.js (c) 2012 matsuda, 2022 Jonathon Doran +// BivariateFunction.js (c) 2022 John Breaux + +// k: number of subdivisions per edge +// On my machine, k = [1, 256) +// I prefer 96 +var k = 64 +// f(x, y): function to graph +function f(x, y) { + var u = 80 * x - 40, v = 90 * y - 45; + var norm = Math.sqrt(u * u + v * v); + return (1 / 2) * Math.pow(Math.E, -0.04 * norm) * Math.cos(0.15 * norm) +} + const vertex_shader = ` attribute vec4 a_Position; @@ -51,13 +64,6 @@ const fragment_shader = ` gl_FragColor = vec4(diffuse + ambient, v_Color.a); } `; -var scale = 192 -function f(x, y) { - var u = 80 * x - 40, v = 90 * y - 45; - var norm = Math.sqrt(u * u + v * v); - return (1 / 2) * Math.pow(Math.E, -0.04 * norm) * Math.cos(0.15 * norm) -} - function main() { // Retrieve element var canvas = document.getElementById('webgl'); @@ -113,16 +119,17 @@ function main() { var normalMatrix = new Matrix4(); // Transformation matrix for normals // Calculate the model matrix - modelMatrix.setRotate(-90, 1, 0, 0); // Rotate around the *X* axis + // Move center of model to center + modelMatrix.setTranslate(-0.5, 0, 0.5) + // Rotate the model upright, around X + modelMatrix.rotate(-90, 1, 0, 0); // Calculate the view projection matrix mvpMatrix.setPerspective(30, canvas.width / canvas.height, 1, 100); - mvpMatrix.translate(0, 0, -2) var theta = Math.PI / 3 - mvpMatrix.lookAt( - Math.tan(theta) / 4, Math.sin(theta) / 4, Math.cos(theta) / 4, - 0, 0, 0, - 0, 1, 0 + mvpMatrix.lookAt(Math.tan(theta), Math.sin(theta), Math.cos(theta), // Why fiddle with multiple constants when you can just fiddle with one? + 0.0, 0.0, 0.0, + 0.0, 1.0, 0.0 ); mvpMatrix.multiply(modelMatrix); @@ -147,49 +154,50 @@ function main() { } -//!!! RIGHT HERE - class BivariateFunction { vertices = []; vertex_colors = []; vertex_normals = []; indices = []; + resolution = 50 func = (x, y) => { return 0; } - constructor({ width = 50, height = 50, func = this.func } = {}) { - this.width = width; - this.height = height; + constructor({ resolution = 50, func } = { resolution: 50, func: this.func }) { + this.resolution = resolution; this.func = func; + this.construct_mesh(); } - generate_quad(width, _height, index) { + generate_quad(width, index) { var upper = [index + 1, index, index + width + 1] var lower = [index + 1, index + width + 1, index + width + 2] return [upper, lower] } - generate_plane() { - var width = this.width, height = this.height; - var vertices = [], vertex_colors = [], vertex_normals = []; - var triangles = []; - for (var i = 0, y = 0; y <= width; y++) { - for (var x = 0; x <= height; x++) { + construct_mesh() { + var vertices = [], vertex_colors = [], vertex_normals = [], triangles = []; + // Generate a + for (var i = 0, y = 0; y <= this.resolution; y++) { + for (var x = 0; x <= this.resolution; x++) { // Create a new vertex - vertices.push([x / width - 0.5, y / height - 0.5, this.func(x / width, y / width)]); + vertices.push([x / this.resolution, y / this.resolution, + this.func(x / this.resolution, y / this.resolution)]); + // Color this vertex a very pleasing shade of velvet-red vertex_colors.push([0.625, 0.025, 0.075]) //vertex_colors.push([x / width, y / width, 1]); + // Give it a normal vector vertex_normals.push([0, 0, 0]); // If this point is the top-left corner of a quad, // then create a new quad - if (x < width && y < height) { - triangles.push(...this.generate_quad(width, height, i)); + if (x < this.resolution && y < this.resolution) { + triangles.push(...this.generate_quad(this.resolution, i)); } i++ } } - + // Sum the normals around each vertex for (var triangle of triangles) { // Turn verts into vec3's var v = [new vec3(...vertices[triangle[0]]), new vec3(...vertices[triangle[1]]), new vec3(...vertices[triangle[2]])]; @@ -209,11 +217,11 @@ class BivariateFunction { // taking full advantage of the garbage collector here vertex_normals[i] = new vec3(...vertex_normals[i]).normalize().a(); } - // Save the vertices and indices - this.vertices = vertices; - this.vertex_colors = vertex_colors; - this.vertex_normals = vertex_normals; - this.indices = triangles; + // Save the vertices and indices as flat arrays + this.vertices = vertices.flat(); + this.vertex_colors = vertex_colors.flat(); + this.vertex_normals = vertex_normals.flat(); + this.indices = triangles.flat(); return } } @@ -222,15 +230,13 @@ class BivariateFunction { function initVertexBuffers(gl) { // Create a new BivariateFunction var bf = new BivariateFunction({ - width: scale, height: scale, func: f + resolution: k, func: f }); - bf.generate_plane(); - - var vertices = new Float32Array(bf.vertices.flat()); - var colors = new Float32Array(bf.vertex_colors.flat()); - var normals = new Float32Array(bf.vertex_normals.flat()); - var indices = new Uint16Array(bf.indices.flat()); + var vertices = new Float32Array(bf.vertices); + var colors = new Float32Array(bf.vertex_colors); + var normals = new Float32Array(bf.vertex_normals); + var indices = new Uint16Array(bf.indices); // Write the vertex property to buffers (coordinates, colors and normals) if (!initArrayBuffer(gl, 'a_Position', vertices, 3)) return -1; diff --git a/BivariateFunction/vec3.js b/BivariateFunction/vec3.js index 0a15673..e9febf9 100644 --- a/BivariateFunction/vec3.js +++ b/BivariateFunction/vec3.js @@ -1,6 +1,6 @@ // BetterVector3.js // John Breaux 2022-07-28 -// 3D Vector library +// Craptastic 3D Vector library "use strict"; @@ -35,7 +35,7 @@ class vec3 { normal() { var m = this.magnitude(); - if (m === 0) {return null}; + if (m === 0) { return null }; return new vec3( this.x / m, this.y / m,