Pendulum: Create a class for regular polygon

This commit is contained in:
John 2022-06-30 16:10:19 -05:00
parent b1936bdcb0
commit 3b4b277871

View File

@ -1,26 +1,120 @@
// RotatingTranslatedTriangle.js (c) 2012 matsuda // RotatingTranslatedTriangle.js (c) 2012 matsuda
"use strict"
const vertex_shader = ` const vertex_shader = `
attribute vec4 a_Position; attribute vec4 a_Position;
uniform mat4 u_ModelMatrix; uniform mat4 u_ModelMatrix;
void main() void main()
{ {
gl_Position = u_ModelMatrix * a_Position; gl_Position = u_ModelMatrix * a_Position;
} `; } `;
const fragment_shader = ` const fragment_shader = `
void main() void main()
{ {
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
} `; } `;
// Point size of the anchor
var POINT_SIZE = 5;
// Radius of the bob
var BOB_RADIUS = 0.1;
// length of the wire
var PEN_LENGTH = 0.8;
// Rotation angle (degrees/second) // Rotation angle (degrees/second)
var ANGLE_STEP = 45.0; var A_VELOCITY = 45.0;
function main() // 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;
}
}
// 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);
}
}
function main() {
// Retrieve <canvas> element // Retrieve <canvas> element
var canvas = document.getElementById('webgl'); var canvas = document.getElementById('webgl');
@ -32,16 +126,17 @@ function main()
} }
// Initialize shaders // Initialize shaders
if (!initShaders(gl, vertex_shader, fragment_shader)) if (!initShaders(gl, vertex_shader, fragment_shader)) {
{
console.log('Failed to intialize shaders.'); console.log('Failed to intialize shaders.');
return; return;
} }
// create a pendulum object
var pendulum = new pendulum2({angle: 0, length: 0});
// Write the positions of vertices to a vertex shader // Write the positions of vertices to a vertex shader
var n = initVertexBuffers(gl); var n = initVertexBuffers(gl, pendulum);
if (n < 0) if (n < 0) {
{
console.log('Failed to set the positions of the vertices'); console.log('Failed to set the positions of the vertices');
return; return;
} }
@ -51,53 +146,50 @@ function main()
// Get storage location of u_ModelMatrix // Get storage location of u_ModelMatrix
var u_ModelMatrix = gl.getUniformLocation(gl.program, 'u_ModelMatrix'); var u_ModelMatrix = gl.getUniformLocation(gl.program, 'u_ModelMatrix');
if (!u_ModelMatrix) if (!u_ModelMatrix) {
{
console.log('Failed to get the storage location of u_ModelMatrix'); console.log('Failed to get the storage location of u_ModelMatrix');
return; return;
} }
// Current rotation angle // Current rotation angle
var currentAngle = 0.0; var currentAngle = 0.0;
// Model matrix // Model matrix
var modelMatrix = new Matrix4(); var modelMatrix = new Matrix4();
// Start drawing // Start drawing
var tick = function() var tick = function () {
{
currentAngle = animate(currentAngle); // Update the rotation angle currentAngle = animate(currentAngle); // Update the rotation angle
draw(gl, n, currentAngle, modelMatrix, u_ModelMatrix); // Draw the triangle pendulum.bob.draw(gl, n, currentAngle, modelMatrix, u_ModelMatrix); // Draw the triangle
requestAnimationFrame(tick, canvas); // Request that the browser ?calls tick requestAnimationFrame(tick, canvas); // Request that the browser ?calls tick
}; };
tick(); tick();
} }
function initVertexBuffers(gl) function initVertexBuffers(gl, pendulum) {
{ // var vertices = new Float32Array([
var vertices = new Float32Array ([ // 0, 0.5, -0.5, -0.5, 0.5, -0.5
0, 0.5, -0.5, -0.5, 0.5, -0.5 // ]);
]); // var n = 3; // The number of vertices
var n = 3; // The number of vertices var vertices = pendulum.bob.to_array();
var n = pendulum.bob.length;
// Create a buffer object // Create a buffer object
var vertexBuffer = gl.createBuffer(); var vertexBuffer = gl.createBuffer();
if (!vertexBuffer) if (!vertexBuffer) {
{
console.log('Failed to create the buffer object'); console.log('Failed to create the buffer object');
return -1; return -1;
} }
// Bind the buffer object to target // Bind the buffer object to target
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer); gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
// Write date into the buffer object // Write date into the buffer object
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW); gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
// Assign the buffer object to a_Position variable // Assign the buffer object to a_Position variable
var a_Position = gl.getAttribLocation(gl.program, 'a_Position'); var a_Position = gl.getAttribLocation(gl.program, 'a_Position');
if(a_Position < 0) if (a_Position < 0) {
{
console.log('Failed to get the storage location of a_Position'); console.log('Failed to get the storage location of a_Position');
return -1; return -1;
} }
@ -109,12 +201,11 @@ function initVertexBuffers(gl)
return n; return n;
} }
function draw(gl, n, currentAngle, modelMatrix, u_ModelMatrix) function draw(gl, n, currentAngle, modelMatrix, u_ModelMatrix) {
{
// Set the rotation matrix // Set the rotation matrix
modelMatrix.setRotate(currentAngle, 0, 0, 1); modelMatrix.setRotate(currentAngle, 0, 0, 1);
modelMatrix.translate(0.35, 0, 0); modelMatrix.translate(0.35, 0, 0);
// Pass the rotation matrix to the vertex shader // Pass the rotation matrix to the vertex shader
gl.uniformMatrix4fv(u_ModelMatrix, false, modelMatrix.elements); gl.uniformMatrix4fv(u_ModelMatrix, false, modelMatrix.elements);
@ -127,23 +218,20 @@ function draw(gl, n, currentAngle, modelMatrix, u_ModelMatrix)
// Last time that this function was called // Last time that this function was called
var g_last = Date.now(); var g_last = Date.now();
function animate(angle) function animate(angle) {
{
// Calculate the elapsed time // Calculate the elapsed time
var now = Date.now(); var now = Date.now();
var elapsed = now - g_last; var elapsed = now - g_last;
g_last = now; g_last = now;
// Update the current rotation angle (adjusted by the elapsed time) // Update the current rotation angle (adjusted by the elapsed time)
var newAngle = angle + (ANGLE_STEP * elapsed) / 1000.0; var newAngle = angle + (A_VELOCITY * elapsed) / 1000.0;
return newAngle %= 360; return newAngle %= 360;
} }
function up() function up() {
{ A_VELOCITY += 10;
ANGLE_STEP += 10;
} }
function down() function down() {
{ A_VELOCITY -= 10;
ANGLE_STEP -= 10;
} }