From cd059c967bb2242f435b976982b44fef0895841b Mon Sep 17 00:00:00 2001 From: John Breaux Date: Thu, 23 Jun 2022 15:50:00 -0500 Subject: [PATCH] Solve Program 2: Chaos Game --- .vscode/launch.json | 17 ++++- ChaosGame/ChaosGame.html | 18 ++++++ ChaosGame/ChaosGame.js | 130 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 164 insertions(+), 1 deletion(-) create mode 100644 ChaosGame/ChaosGame.html create mode 100644 ChaosGame/ChaosGame.js diff --git a/.vscode/launch.json b/.vscode/launch.json index 67d4647..3e95856 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -1,12 +1,27 @@ { "version": "0.2.0", "configurations": [ + { - "name": "Launch ClickedPoints", + "name": "ClickedPoints", "type": "firefox", "request": "launch", "reAttach": true, "file": "${workspaceFolder}/ClickedPoints/ClickedPoints.html" + }, + { + "name": "ChaosGame", + "type": "firefox", + "request": "launch", + "reAttach": true, + "file": "${workspaceFolder}/ChaosGame/ChaosGame.html" + }, + { + "name": "Pendulum", + "type": "firefox", + "request": "launch", + "reAttach": true, + "file": "${workspaceFolder}/Pendulum/Pendulum.html" } ] } \ No newline at end of file diff --git a/ChaosGame/ChaosGame.html b/ChaosGame/ChaosGame.html new file mode 100644 index 0000000..d806955 --- /dev/null +++ b/ChaosGame/ChaosGame.html @@ -0,0 +1,18 @@ + + + + + Chaos Game + + + + + Please use a browser that supports "canvas" + + + + + + + + diff --git a/ChaosGame/ChaosGame.js b/ChaosGame/ChaosGame.js new file mode 100644 index 0000000..2083c00 --- /dev/null +++ b/ChaosGame/ChaosGame.js @@ -0,0 +1,130 @@ +// HelloPoint2.js (c) 2012 matsuda, 2022 Jonathon Doran +"use strict"; + +// Vertex shader program +const vertex_shader = ` + attribute vec4 a_Position; // attribute variables are assigned by the main program + + void main() + { + gl_Position = a_Position; + gl_PointSize = 1.0; + } `; + +// Fragment shader program +const fragment_shader = ` + void main() + { + gl_FragColor = vec4(0.2, 0.8, 1.0, 1.0); // Set the point color to a nice cyan + } `; + +// +// Chaos Game +// + +// Classes +// vec2: 2D vectors +class vec2 { + constructor(x = 0, y = 0) { + this.x = x; + this.y = y; + } + add(rhs) { + if (rhs) + return new vec2(this.x + rhs.x, this.y + rhs.y); + return null; + } + sub(rhs) { + if (rhs) + return new vec2(this.x - rhs.x, this.y - rhs.y); + return null; + } + copy() { + return new vec2(this.x, this.y); + } + move_halfway(rhs) { + // Calculate the vector direction to move in, and change in that direction. + this.x += (rhs.x - this.x) / 2; + this.y += (rhs.y - this.y) / 2; + } +} + +// triangle2 class: Holds 3 vertices, represented as vectors from the origin +class triangle2 { + // constructor: Make a new triangle + constructor({ v0 = null, v1 = null, v2 = null, type = "scalene", radius = 0, center = {x: 0, y: 0}} = {}) { + this.v = [, ,] + this.v[0] = v0; + this.v[1] = v1; + this.v[2] = v2; + if (type === "equilateral") { + this.make_equilateral(radius, center); + } + } + // make_equilateral: construct an equilateral triangle + // @param radius: Distance from center of triangle to vertices + make_equilateral(radius, center = {x: 0, y: 0}) { + // compute the math constants + const r_sin_120 = Math.sin(Math.PI / 3) * radius; + const r_cos_120 = 0.5 * radius; + + // Equilateral triangle centered on origin + this.v[0] = new vec2(-r_sin_120, -r_cos_120).add(center); + this.v[1] = new vec2(0, radius).add(center); + this.v[2] = new vec2(r_sin_120, -r_cos_120).add(center); + } + get_vertex(index) { return this.v[index]; } + get_rand_vertex() { return this.v[Math.floor(Math.random() * 3)]; } +} + +// function draw_point: draw a point +function draw_point(gl, a_Position, p) { + // Pass vertex position to attribute variable + gl.vertexAttrib3f(a_Position, p.x, p.y, 0.0); + // Draw + gl.drawArrays(gl.POINTS, 0, 1); +} + +function main() { + // Retrieve element + var canvas = document.getElementById('webgl'); + + // Get the rendering context for WebGL + var gl = getWebGLContext(canvas); + if (!gl) { + console.log('Failed to get the rendering context for WebGL'); + return; + } + + // Initialize shaders + if (!initShaders(gl, vertex_shader, fragment_shader)) { + console.log('Failed to intialize shaders.'); + return; + } + + // Get the storage location of a_Position + var a_Position = gl.getAttribLocation(gl.program, 'a_Position'); + + if (a_Position < 0) { + console.log('Failed to get the storage location of a_Position'); + return; + } + + // Specify the color for clearing canvas as black, and clear canvas + gl.clearColor(0.0, 0.0, 0.0, 1.0); + gl.clear(gl.COLOR_BUFFER_BIT); + + // make an equilateral triangle of radius 0.8 + var triangle = new triangle2({type: "equilateral", radius: 0.8}); + // initialize point p to a copy of one of the vectors + var i, p = triangle.get_vertex(0)?.copy(); + // loop for ten thousand years + for (i = 0; i < 50000; i++) { + // get a random vertex + var random_vertex = triangle.get_rand_vertex(); + // move to the midpoint + p.move_halfway(random_vertex); + // draw point + draw_point(gl, a_Position, p); + } +}