Pendulum: Shit's fucked
This commit is contained in:
		@@ -17,6 +17,7 @@
 | 
				
			|||||||
    <script src="../lib/webgl-debug.js"></script>
 | 
					    <script src="../lib/webgl-debug.js"></script>
 | 
				
			||||||
    <script src="../lib/cuon-utils.js"></script>
 | 
					    <script src="../lib/cuon-utils.js"></script>
 | 
				
			||||||
    <script src="../lib/cuon-matrix.js"></script>
 | 
					    <script src="../lib/cuon-matrix.js"></script>
 | 
				
			||||||
 | 
					    <script src="PendulumComponents.js"></script>
 | 
				
			||||||
    <script src="Pendulum.js"></script>
 | 
					    <script src="Pendulum.js"></script>
 | 
				
			||||||
  </body>
 | 
					  </body>
 | 
				
			||||||
</html>
 | 
					</html>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,9 @@
 | 
				
			|||||||
// RotatingTranslatedTriangle.js (c) 2012 matsuda
 | 
					// RotatingTranslatedTriangle.js (c) 2012 matsuda
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Pendulum.js
 | 
				
			||||||
 | 
					// John Breaux  2022-06-30
 | 
				
			||||||
 | 
					// Simulates a pendulum in a frictionless vacuum with no gravity
 | 
				
			||||||
 | 
					
 | 
				
			||||||
"use strict"
 | 
					"use strict"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const vertex_shader = `
 | 
					const vertex_shader = `
 | 
				
			||||||
@@ -8,6 +13,7 @@ const vertex_shader = `
 | 
				
			|||||||
  void main()
 | 
					  void main()
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    gl_Position = u_ModelMatrix * a_Position;
 | 
					    gl_Position = u_ModelMatrix * a_Position;
 | 
				
			||||||
 | 
					    gl_PointSize = 5.0;
 | 
				
			||||||
  }	`;
 | 
					  }	`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -26,92 +32,16 @@ var PEN_LENGTH = 0.8;
 | 
				
			|||||||
// Rotation angle (degrees/second)
 | 
					// Rotation angle (degrees/second)
 | 
				
			||||||
var A_VELOCITY = 45.0;
 | 
					var A_VELOCITY = 45.0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Classes
 | 
					// Common functions:
 | 
				
			||||||
//   homo2: Stores a 2d vector or point in homog. coords
 | 
					//  acquire_buffer: Get a vertex buffer object from gl
 | 
				
			||||||
class homog2 {
 | 
					function acquire_buffer(gl) {
 | 
				
			||||||
  constructor(x = 0, y = 0, w = 0) {
 | 
					  // Create a buffer object
 | 
				
			||||||
    this.x = x;
 | 
					  var vertexBuffer = gl.createBuffer();
 | 
				
			||||||
    this.y = y;
 | 
					  if (!vertexBuffer) {
 | 
				
			||||||
    this.w = w;
 | 
					    console.log('Failed to create the buffer object');
 | 
				
			||||||
  }
 | 
					    return -1;
 | 
				
			||||||
  // Add with modify
 | 
					 | 
				
			||||||
  add_m(rhs) {
 | 
					 | 
				
			||||||
    if (rhs) {
 | 
					 | 
				
			||||||
      this.x += rhs.x;
 | 
					 | 
				
			||||||
      this.y += rhs.y;
 | 
					 | 
				
			||||||
      this.w += rhs.w;
 | 
					 | 
				
			||||||
      return this;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    else return null;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  // scalar multiply with modify
 | 
					 | 
				
			||||||
  smul_m(scalar) {
 | 
					 | 
				
			||||||
    if (typeof(rhs) === "number") {
 | 
					 | 
				
			||||||
      this.x *= rhs;
 | 
					 | 
				
			||||||
      this.y *= rhs;
 | 
					 | 
				
			||||||
      this.w *= rhs;
 | 
					 | 
				
			||||||
      return this;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    else return null;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  // copy
 | 
					 | 
				
			||||||
  copy() {
 | 
					 | 
				
			||||||
    return new homog2(this.x, this.y, this.w);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  // create vector/point from 2d polar coordinates
 | 
					 | 
				
			||||||
  from_polar(r = 0, theta = 0, w = 0) {
 | 
					 | 
				
			||||||
    this.x = r * Math.cos(theta);
 | 
					 | 
				
			||||||
    this.y = r * Math.sin(theta);
 | 
					 | 
				
			||||||
    this.w = w;
 | 
					 | 
				
			||||||
    return this;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// hexagon2 class: Holds 6 vertices and a center point. Only constructs perfect hexagons.
 | 
					 | 
				
			||||||
class hexagon2 {
 | 
					 | 
				
			||||||
  // constructor: Make a new regular polygon
 | 
					 | 
				
			||||||
  constructor({sides = 6, radius = 0, rotation = 0, center = { x: 0, y: 0 } } = {}) {
 | 
					 | 
				
			||||||
    // lenth is center + sides
 | 
					 | 
				
			||||||
    this.length = 1;
 | 
					 | 
				
			||||||
    this.center = new homog2(center.x, center.y, 1);
 | 
					 | 
				
			||||||
    this.v = [];
 | 
					 | 
				
			||||||
    for (var i = 0; i <= sides; i++) {
 | 
					 | 
				
			||||||
      this.v[i] = new homog2().from_polar(radius, rotation + (i*2*Math.PI / sides)).add_m(this.center);
 | 
					 | 
				
			||||||
      this.length++;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  // Convert to Float32Array [center, v0, v1, ...]
 | 
					 | 
				
			||||||
  to_array() {
 | 
					 | 
				
			||||||
    // allocate space for center.xy + vertices.xy
 | 
					 | 
				
			||||||
    var ret = new Float32Array((1 + this.v.length) * 2);
 | 
					 | 
				
			||||||
    // save the center
 | 
					 | 
				
			||||||
    ret[0] = this.center.x;
 | 
					 | 
				
			||||||
    ret[1] = this.center.y;
 | 
					 | 
				
			||||||
    // save the vertices
 | 
					 | 
				
			||||||
    for (var i = 0; i < this.v.length; i++) {
 | 
					 | 
				
			||||||
      var j = 2 * (i + 1);
 | 
					 | 
				
			||||||
      ret[j]   = this.v[i].x;
 | 
					 | 
				
			||||||
      ret[j+1] = this.v[i].y;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    return ret;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  draw(gl, n, currentAngle, modelMatrix, u_ModelMatrix) {
 | 
					 | 
				
			||||||
    // Set the rotation matrix
 | 
					 | 
				
			||||||
    modelMatrix.setRotate(currentAngle, 0, 0, 1);
 | 
					 | 
				
			||||||
    // Pass the rotation matrix to the vertex shader
 | 
					 | 
				
			||||||
    gl.uniformMatrix4fv(u_ModelMatrix, false, modelMatrix.elements);
 | 
					 | 
				
			||||||
    // Clear <canvas>
 | 
					 | 
				
			||||||
    gl.clear(gl.COLOR_BUFFER_BIT);
 | 
					 | 
				
			||||||
    // Draw the pendulum
 | 
					 | 
				
			||||||
    gl.drawArrays(gl.TRIANGLE_FAN, 0, n);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class pendulum2 {
 | 
					 | 
				
			||||||
  constructor({angle = 0, length = PEN_LENGTH, radius = BOB_RADIUS} = {}) {
 | 
					 | 
				
			||||||
    this.bob = new hexagon2({radius: radius, center: {x: 0, y: -length}});
 | 
					 | 
				
			||||||
    console.log(this);
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					  return vertexBuffer;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function main() {
 | 
					function main() {
 | 
				
			||||||
@@ -132,14 +62,8 @@ function main() {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // create a pendulum object
 | 
					  // create a pendulum object
 | 
				
			||||||
  var pendulum = new pendulum2({angle: 0, length: 0});
 | 
					  var pendulum = new Pendulum({ angle: 0, length: PEN_LENGTH, radius: BOB_RADIUS });
 | 
				
			||||||
 | 
					  init(gl, pendulum);
 | 
				
			||||||
  // Write the positions of vertices to a vertex shader
 | 
					 | 
				
			||||||
  var n = initVertexBuffers(gl, pendulum);
 | 
					 | 
				
			||||||
  if (n < 0) {
 | 
					 | 
				
			||||||
    console.log('Failed to set the positions of the vertices');
 | 
					 | 
				
			||||||
    return;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Specify the color for clearing <canvas>
 | 
					  // Specify the color for clearing <canvas>
 | 
				
			||||||
  gl.clearColor(0, 0, 0, 1);
 | 
					  gl.clearColor(0, 0, 0, 1);
 | 
				
			||||||
@@ -151,81 +75,32 @@ function main() {
 | 
				
			|||||||
    return;
 | 
					    return;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Current rotation angle
 | 
					 | 
				
			||||||
  var currentAngle = 0.0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // Model matrix
 | 
					  // Model matrix
 | 
				
			||||||
  var modelMatrix = new Matrix4();
 | 
					  var modelMatrix = new Matrix4();
 | 
				
			||||||
 | 
					  // Set it to the I matrix
 | 
				
			||||||
 | 
					  modelMatrix.setIdentity();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Start drawing
 | 
					  // Start drawing
 | 
				
			||||||
  var tick = function () {
 | 
					  var tick = function () {
 | 
				
			||||||
    currentAngle = animate(currentAngle);  // Update the rotation angle
 | 
					    // Tick the pendulum
 | 
				
			||||||
    pendulum.bob.draw(gl, n, currentAngle, modelMatrix, u_ModelMatrix);   // Draw the triangle
 | 
					    pendulum.tick();
 | 
				
			||||||
    requestAnimationFrame(tick, canvas);   // Request that the browser ?calls tick
 | 
					    // Draw the pendulum
 | 
				
			||||||
 | 
					    draw(gl, pendulum, modelMatrix, u_ModelMatrix);
 | 
				
			||||||
 | 
					    // Request that the browser ?calls tick
 | 
				
			||||||
 | 
					    requestAnimationFrame(tick, canvas);
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
  tick();
 | 
					  tick();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function initVertexBuffers(gl, pendulum) {
 | 
					function init(gl, pendulum) {
 | 
				
			||||||
  // var vertices = new Float32Array([
 | 
					  pendulum.init(gl);
 | 
				
			||||||
  //   0, 0.5, -0.5, -0.5, 0.5, -0.5
 | 
					 | 
				
			||||||
  // ]);
 | 
					 | 
				
			||||||
  // var n = 3;   // The number of vertices
 | 
					 | 
				
			||||||
  var vertices = pendulum.bob.to_array();
 | 
					 | 
				
			||||||
  var n = pendulum.bob.length;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // Create a buffer object
 | 
					 | 
				
			||||||
  var vertexBuffer = gl.createBuffer();
 | 
					 | 
				
			||||||
  if (!vertexBuffer) {
 | 
					 | 
				
			||||||
    console.log('Failed to create the buffer object');
 | 
					 | 
				
			||||||
    return -1;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // Bind the buffer object to target
 | 
					 | 
				
			||||||
  gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // Write date into the buffer object
 | 
					 | 
				
			||||||
  gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // Assign the buffer object to a_Position variable
 | 
					 | 
				
			||||||
  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 -1;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // Enable the assignment to a_Position variable
 | 
					 | 
				
			||||||
  gl.enableVertexAttribArray(a_Position);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  return n;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function draw(gl, n, currentAngle, modelMatrix, u_ModelMatrix) {
 | 
					function draw(gl, pendulum, modelMatrix, u_ModelMatrix) {
 | 
				
			||||||
  // Set the rotation matrix
 | 
					 | 
				
			||||||
  modelMatrix.setRotate(currentAngle, 0, 0, 1);
 | 
					 | 
				
			||||||
  modelMatrix.translate(0.35, 0, 0);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // Pass the rotation matrix to the vertex shader
 | 
					 | 
				
			||||||
  gl.uniformMatrix4fv(u_ModelMatrix, false, modelMatrix.elements);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // Clear <canvas>
 | 
					  // Clear <canvas>
 | 
				
			||||||
  gl.clear(gl.COLOR_BUFFER_BIT);
 | 
					  gl.clear(gl.COLOR_BUFFER_BIT);
 | 
				
			||||||
 | 
					  // Draw the pendulum
 | 
				
			||||||
  // Draw the rectangle
 | 
					  pendulum.draw(gl, modelMatrix, u_ModelMatrix);
 | 
				
			||||||
  gl.drawArrays(gl.TRIANGLES, 0, n);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Last time that this function was called
 | 
					 | 
				
			||||||
var g_last = Date.now();
 | 
					 | 
				
			||||||
function animate(angle) {
 | 
					 | 
				
			||||||
  // Calculate the elapsed time
 | 
					 | 
				
			||||||
  var now = Date.now();
 | 
					 | 
				
			||||||
  var elapsed = now - g_last;
 | 
					 | 
				
			||||||
  g_last = now;
 | 
					 | 
				
			||||||
  // Update the current rotation angle (adjusted by the elapsed time)
 | 
					 | 
				
			||||||
  var newAngle = angle + (A_VELOCITY * elapsed) / 1000.0;
 | 
					 | 
				
			||||||
  return newAngle %= 360;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function up() {
 | 
					function up() {
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										210
									
								
								Pendulum/PendulumComponents.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										210
									
								
								Pendulum/PendulumComponents.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,210 @@
 | 
				
			|||||||
 | 
					// PendulumComponents.js
 | 
				
			||||||
 | 
					// John Breaux  2022-06-30
 | 
				
			||||||
 | 
					// Classes and data structures for Pendulum.js
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					"use strict"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Classes
 | 
				
			||||||
 | 
					//   homo2: Stores a 2d vector or point in homog. coords
 | 
				
			||||||
 | 
					class homog2 {
 | 
				
			||||||
 | 
					   constructor(x = 0, y = 0, w = 0) {
 | 
				
			||||||
 | 
					      this.x = x;
 | 
				
			||||||
 | 
					      this.y = y;
 | 
				
			||||||
 | 
					      this.w = w;
 | 
				
			||||||
 | 
					   }
 | 
				
			||||||
 | 
					   // Add with modify
 | 
				
			||||||
 | 
					   add_m(rhs) {
 | 
				
			||||||
 | 
					      if (rhs) {
 | 
				
			||||||
 | 
					         this.x += rhs.x;
 | 
				
			||||||
 | 
					         this.y += rhs.y;
 | 
				
			||||||
 | 
					         this.w += rhs.w;
 | 
				
			||||||
 | 
					         return this;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      else return null;
 | 
				
			||||||
 | 
					   }
 | 
				
			||||||
 | 
					   // scalar multiply with modify
 | 
				
			||||||
 | 
					   smul_m(scalar) {
 | 
				
			||||||
 | 
					      if (typeof (rhs) === "number") {
 | 
				
			||||||
 | 
					         this.x *= rhs;
 | 
				
			||||||
 | 
					         this.y *= rhs;
 | 
				
			||||||
 | 
					         this.w *= rhs;
 | 
				
			||||||
 | 
					         return this;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      else return null;
 | 
				
			||||||
 | 
					   }
 | 
				
			||||||
 | 
					   // copy
 | 
				
			||||||
 | 
					   copy() {
 | 
				
			||||||
 | 
					      return new homog2(this.x, this.y, this.w);
 | 
				
			||||||
 | 
					   }
 | 
				
			||||||
 | 
					   // create vector/point from 2d polar coordinates
 | 
				
			||||||
 | 
					   from_polar(r = 0, theta = 0, w = 0) {
 | 
				
			||||||
 | 
					      this.x = r * Math.cos(theta);
 | 
				
			||||||
 | 
					      this.y = r * Math.sin(theta);
 | 
				
			||||||
 | 
					      this.w = w;
 | 
				
			||||||
 | 
					      return this;
 | 
				
			||||||
 | 
					   }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Anchor {
 | 
				
			||||||
 | 
					   constructor({ center = { x: 0, y: 0 } } = {}) {
 | 
				
			||||||
 | 
					      this.position = new homog2(center.x, center.y, 1);
 | 
				
			||||||
 | 
					   }
 | 
				
			||||||
 | 
					   // Convert to Float32Array [center, v0, v1, ...]
 | 
				
			||||||
 | 
					   vertex_array() {
 | 
				
			||||||
 | 
					      // allocate space for center.xy + vertices.xy
 | 
				
			||||||
 | 
					      var ret = new Float32Array(2);
 | 
				
			||||||
 | 
					      // save the vertices
 | 
				
			||||||
 | 
					      ret[0] = this.position.x, ret[1] = this.position.y;
 | 
				
			||||||
 | 
					      console.log(ret);
 | 
				
			||||||
 | 
					      return ret;
 | 
				
			||||||
 | 
					   }
 | 
				
			||||||
 | 
					   // Generate the index_array for the shape
 | 
				
			||||||
 | 
					   index_array() {
 | 
				
			||||||
 | 
					      var ret = new Uint8Array(1);
 | 
				
			||||||
 | 
					      ret[0] = 0;
 | 
				
			||||||
 | 
					      console.log(ret);
 | 
				
			||||||
 | 
					      return ret;
 | 
				
			||||||
 | 
					   }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   init(gl) {
 | 
				
			||||||
 | 
					      // Make the buffers
 | 
				
			||||||
 | 
					      this.vertexBuffer = acquire_buffer(gl);
 | 
				
			||||||
 | 
					      this.indexBuffer = acquire_buffer(gl);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Bind the buffers
 | 
				
			||||||
 | 
					      gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
 | 
				
			||||||
 | 
					      gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Acquire a reference to 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 -1;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Enable the assignment to a_Position variable
 | 
				
			||||||
 | 
					      gl.enableVertexAttribArray(a_Position);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Write date into the buffers
 | 
				
			||||||
 | 
					      gl.bufferData(gl.ARRAY_BUFFER, this.vertex_array(), gl.STATIC_DRAW);
 | 
				
			||||||
 | 
					      gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.index_array(), gl.STATIC_DRAW);
 | 
				
			||||||
 | 
					   }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   draw(gl, modelMatrix, u_ModelMatrix) {
 | 
				
			||||||
 | 
					      // Bind the buffers
 | 
				
			||||||
 | 
					      gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
 | 
				
			||||||
 | 
					      gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);
 | 
				
			||||||
 | 
					      // Pass the rotation matrix to the vertex shader
 | 
				
			||||||
 | 
					      gl.uniformMatrix4fv(u_ModelMatrix, false, modelMatrix.elements);
 | 
				
			||||||
 | 
					      // Draw the Anchor
 | 
				
			||||||
 | 
					      gl.drawElements(gl.POINTS, 1, gl.UNSIGNED_BYTE, 0);
 | 
				
			||||||
 | 
					   }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// hexagon2 class: Holds vertices and a center point. Only constructs regular polygons
 | 
				
			||||||
 | 
					class Polygon {
 | 
				
			||||||
 | 
					   // constructor: Make a new regular polygon
 | 
				
			||||||
 | 
					   constructor({ sides = 6, radius = 1, rotation = 0, center = { x: 0, y: 0 }, color = { r: 0, g: 0, b: 1 } } = {}) {
 | 
				
			||||||
 | 
					      this.length = 0;
 | 
				
			||||||
 | 
					      // vertices
 | 
				
			||||||
 | 
					      this.vertices = [];
 | 
				
			||||||
 | 
					      this.center = new homog2(center.x, center.y, 1);
 | 
				
			||||||
 | 
					      for (var i = 0; i <= sides; i++) {
 | 
				
			||||||
 | 
					         this.vertices[i] = new homog2().from_polar(radius, rotation + (i * 2 * Math.PI / sides)).add_m(this.center);
 | 
				
			||||||
 | 
					            this.length++;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					   }
 | 
				
			||||||
 | 
					   // Convert to Float32Array [center, v0, v1, ...]
 | 
				
			||||||
 | 
					   vertex_array() {
 | 
				
			||||||
 | 
					      // allocate space for center.xy + vertices.xy
 | 
				
			||||||
 | 
					      var ret = new Float32Array((this.vertices.length) * 2);
 | 
				
			||||||
 | 
					      // save the vertices
 | 
				
			||||||
 | 
					      for (var i = 0; i < this.vertices.length; i++) {
 | 
				
			||||||
 | 
					         var j = 2 * i;
 | 
				
			||||||
 | 
					         ret[j] = this.vertices[i].x;
 | 
				
			||||||
 | 
					         ret[j + 1] = this.vertices[i].y;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      return ret;
 | 
				
			||||||
 | 
					   }
 | 
				
			||||||
 | 
					   // Generate the index_array for the shape
 | 
				
			||||||
 | 
					   index_array() {
 | 
				
			||||||
 | 
					      var ret = new Uint8Array(this.vertices.length + 1);
 | 
				
			||||||
 | 
					      for (var i = 0; i < this.vertices.length; i++) {
 | 
				
			||||||
 | 
					         ret[i] = i
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      ret[this.vertices.length] = 0;
 | 
				
			||||||
 | 
					      return ret;
 | 
				
			||||||
 | 
					   }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   init(gl) {
 | 
				
			||||||
 | 
					      // Make the buffers
 | 
				
			||||||
 | 
					      this.vertexBuffer = acquire_buffer(gl);
 | 
				
			||||||
 | 
					      this.indexBuffer = acquire_buffer(gl);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Bind the buffers
 | 
				
			||||||
 | 
					      gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
 | 
				
			||||||
 | 
					      gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Acquire a reference to 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 -1;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Enable the assignment to a_Position variable
 | 
				
			||||||
 | 
					      gl.enableVertexAttribArray(a_Position);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Write date into the buffers
 | 
				
			||||||
 | 
					      gl.bufferData(gl.ARRAY_BUFFER, this.vertex_array(), gl.STATIC_DRAW);
 | 
				
			||||||
 | 
					      gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.index_array(), gl.STATIC_DRAW);
 | 
				
			||||||
 | 
					   }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   draw(gl, modelMatrix, u_ModelMatrix) {
 | 
				
			||||||
 | 
					      gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
 | 
				
			||||||
 | 
					      gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);
 | 
				
			||||||
 | 
					      // Pass the rotation matrix to the vertex shader
 | 
				
			||||||
 | 
					      gl.uniformMatrix4fv(u_ModelMatrix, false, modelMatrix.elements);
 | 
				
			||||||
 | 
					      // Draw the shape
 | 
				
			||||||
 | 
					      gl.drawElements(gl.TRIANGLE_FAN, this.length, gl.UNSIGNED_BYTE, 0);
 | 
				
			||||||
 | 
					   }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Pendulum {
 | 
				
			||||||
 | 
					   constructor({ angle = 0, length = PEN_LENGTH, radius = BOB_RADIUS, anchor = { x: 0, y: 0 } } = {}) {
 | 
				
			||||||
 | 
					      this.angle = angle;
 | 
				
			||||||
 | 
					      this.components = [
 | 
				
			||||||
 | 
					         new Anchor({ center: anchor }),
 | 
				
			||||||
 | 
					         new Polygon({ radius: radius, center: { x: 0, y: -length } })
 | 
				
			||||||
 | 
					      ];
 | 
				
			||||||
 | 
					   }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   // Tick the pendulum (update and perform movement)
 | 
				
			||||||
 | 
					   tick() {
 | 
				
			||||||
 | 
					      var now = Date.now(), elapsed = now - this.t_prev;
 | 
				
			||||||
 | 
					      this.t_prev = now;
 | 
				
			||||||
 | 
					      this.angle = (this.angle + (A_VELOCITY * elapsed / 1000)) % 360;
 | 
				
			||||||
 | 
					   }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   // Initialize the pendulum
 | 
				
			||||||
 | 
					   init(gl) {
 | 
				
			||||||
 | 
					      // initialize the components
 | 
				
			||||||
 | 
					      for(var component of this.components) {
 | 
				
			||||||
 | 
					         component?.init(gl);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      // start the clock
 | 
				
			||||||
 | 
					      this.t_prev = Date.now();
 | 
				
			||||||
 | 
					   }
 | 
				
			||||||
 | 
					   // Draw the pendulum
 | 
				
			||||||
 | 
					   draw(gl, modelMatrix, u_ModelMatrix) {
 | 
				
			||||||
 | 
					      // Rotate the pendulum
 | 
				
			||||||
 | 
					      modelMatrix.setRotate(this.angle, 0, 0, 1);
 | 
				
			||||||
 | 
					      // Draw each component
 | 
				
			||||||
 | 
					      for (var component of this.components) {
 | 
				
			||||||
 | 
					         component?.draw(gl, modelMatrix, u_ModelMatrix);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					   }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user