// Pendulum // Daniel Shiffman // A Simple Pendulum Class // Includes functionality for user can click and drag the pendulum // Created 2 May 2005 class Pendulum { Vector3D loc; // Location of pendulum ball Vector3D origin; // Location of arm origin float r; // Length of arm float theta; // Pendulum arm angle float theta_vel; // Angle velocity float theta_acc; // Angle acceleration float ballr; // Ball radius float damping; // Arbitary damping amount boolean dragging = false; // This constructor could be improved to allow a greater variety of pendulums Pendulum(Vector3D origin_, float r_) { // Fill all variables origin = origin_.copy(); r = r_; theta = 0.0; //calculate the location of the ball using polar to cartesian conversion float x = r * sin(theta); float y = r * cos(theta); loc = new Vector3D(origin.x + x, origin.y + y); theta_vel = 0.0f; theta_acc = 0.0f; damping = 0.995f; // Arbitrary damping ballr = 50.0f; // Arbitrary ball radius } void go() { update(); drag(); //for user interaction render(); } // Function to update location void update() { // As long as we aren't dragging the pendulum, let it swing! if (!dragging) { float G = 0.2; // Arbitrary universal gravitational constant theta_acc = (-1 * G / r) * sin(theta); // Calculate acceleration (see: http://www.myphysicslab.com/pendulum1.html) theta_vel += theta_acc; // Increment velocity theta_vel *= damping; // Arbitrary damping theta += theta_vel; // Increment theta } loc.setXY(r*sin(theta),r*cos(theta)); // Polar to cartesian conversion loc.add(origin); // Make sure the location is relative to the pendulum's origin } void render() { stroke(255,200); noFill(); //fill(200,50); //stroke(noise(xoff)*255,noise(yoff)*255,0,50); // Draw the arm line(origin.x,origin.y,loc.x,loc.y); ellipseMode(CENTER); //fill(noise(xoff)*255,noise(yoff)*255,0,50); //if (dragging) fill(noise(xoff)*255,noise(yoff)*255,100,50); //noStroke(); // Draw the ball //ellipse(loc.x,loc.y,ballr,ballr); } // The methods below are for mouse interaction // This checks to see if we clicked on the pendulum ball void clicked(int mx, int my) { float d = dist(mx,my,loc.x,loc.y); if (d < ballr) { dragging = true; } } // This tells us we are not longer clicking on the ball void stopDragging() { dragging = false; } void drag() { // If we are draging the ball, we calculate the angle between the // pendulum origin and mouse location // we assign that angle to the pendulum if (dragging) { //loc = new Vector3D(mouseX,mouseY); Vector3D diff = Vector3D.sub(origin,new Vector3D(mouseX,mouseY)); // Difference between 2 points theta = atan2(-1*diff.y,diff.x) - radians(90); // Angle relative to vertical axis //r = Vector3D.distance(origin,loc); } } }