We are about to switch to a new forum software. Until then we have removed the registration on this forum.
Hi: I wrote this experimental code to perform a visual simulation of an underdamped oscillatory response for swing doors. The purpose is just to obtain an acceptable visual simulation of that physical system with no fancy additions or great art. It's based on my interpretation of the physics and math from this Wikipedia article:http://en.wikipedia.org/wiki/Damping Please let me know if you have any suggestions or find any problems. Here is the video of how it looks: Here is a screen picture:
and here is the code:
Thanks
//Swing doors underdamped oscillatory response (visual simulation test code).
//Built with Processing 2.03 by Adrian Fernandez. Miami, FL. USA. (07-30-2014).
//Based on: http://en.wikipedia.org/wiki/Critically_damped#Critical_damping_.28.CE.B6_.3D_1.29
final float minDampingRatio=0.01;//this code does not work with dampingRatio=0;
final float maxDampingRatio=0.99;
float dampingRatio;//(0<=dampingRatio<1); for under-damping oscillatory response.
final float minFreq=0.25;//for acceptable visual effect on the screen.
final float maxFreq=2;//for acceptable visual effect on the screen.
float freq;// (Hz) (freq interval (0.5<freq<2.0); for acceptable visual effect.
float A;//equation coeficient
float w0;//angular freq.
float wd;//damped freq (ringing freq);
float B;//equation coeficient
float time=0;//oscillation time in seconds
float initialAngle;//To perform drawings
float angle;
float doorThickness;
float doorWidth;
float doorHingePositionX;
float doorHingePositionY;
boolean oscillate=false;
int startTime=0;
void setup()
{
size(1350, 690);
frameRate(60);
dampingRatio=0.1;// 0<=dampingRatio<1; for under-damping oscillatory response.
//this code does not work with dampingRatio=0;
final float minA=height/8;
final float maxA=height/3.2;
A=200;//initial position in pixels from hinges center.
float firstDerivativeOfA=0;// Since A is a constant, its first derivative=0
A=constrain(A, minA, maxA);// to constrain doors size within visual area.
dampingRatio=constrain(dampingRatio, minDampingRatio, maxDampingRatio);//For under-damping oscillatory response.
freq=0.7;// Hz (freq interval (0.5<freq<1.5) for acceptable visual effect on the screen.
freq=constrain(freq, minFreq, maxFreq);// Hz (freq interval (0.5<freq<1.5)for acceptable visual effect.
w0=TWO_PI*freq; //angular freq.
wd=w0*sqrt(1-sq(dampingRatio));// damped freq (ringing freq);
B=1/(wd*(dampingRatio*w0*A+firstDerivativeOfA));// coeficient
doorWidth=A;
doorThickness=doorWidth/20;
initialAngle=-HALF_PI;//To perform drawings
}
void draw()
{
background(0);
textAlign(CENTER);
fill(255);
textSize(18);
text("Swing Doors Underdamped Oscillatory Response. Visual Simulation (top view).", width/2, 50);
textSize(14);
text("Damping Ratio= "+dampingRatio+", Freq= "+freq+" Hz", width/2, 80);
textSize(16);
text("Click left mouse to swing doors, right to take screen picture.", width/2, height-70);
int angleSign=1;
drawDoor(angleSign);
angleSign=-1;// to reverse drawing and rotation
drawDoor(angleSign);
}
void drawDoor(int angleSign)
{
doorHingePositionX=width/2;
float doorsGap=doorThickness/4;
doorHingePositionY=height/2-angleSign*(doorWidth+doorsGap);
float value=exp(-dampingRatio*w0*time);
pushMatrix();
translate(doorHingePositionX, doorHingePositionY);
rotate(-initialAngle);
fill(0, 0, 250);
noStroke();
rectMode(CENTER);
float twiceDoorThickness=2*doorThickness;
rect(-angleSign*twiceDoorThickness, 0, twiceDoorThickness, twiceDoorThickness);
rect(-angleSign*3*doorThickness, 0, doorThickness, doorWidth/3);
if (angleSign==1)
{
rotate(initialAngle);// to place text horizontally
fill(255);
textAlign(LEFT);
textSize(18);
text("time= "+time, 3*doorWidth/2, 0);
text(" sec",2*doorWidth+twiceDoorThickness , 0);
rotate(-initialAngle);// to restore rotation
}
if (value>=0.005&&oscillate)//Stops oscillation when exponential value is 5/1000 from start point.
{
float positionY=value*A*cos(wd*time)+B*sin(wd*time);
time=(millis()-startTime)/1000.0;//seconds
angle=angleSign*acos(positionY/doorWidth);
}
else
{
angle=-angleSign*initialAngle;
oscillate=false;
}
rotate(angle+initialAngle);
rectMode(CORNER);
fill(0, 0, 250);
rect(doorThickness, doorThickness/2, doorWidth-doorThickness, -doorThickness);
stroke(255);
strokeWeight(doorThickness);
ellipse(0, 0, twiceDoorThickness, twiceDoorThickness);
popMatrix();
}
void mouseClicked()
{
if (mouseButton==LEFT)
{
oscillate=true;
startTime=millis();// resets timer
time=0;// resets time
}
if (mouseButton==RIGHT)
{
save("Underdamped Oscillatory_Response(Dratio= "+dampingRatio+",Freq= "+freq+"Hz, time= "+time+").png");// saves a screen picture in the sketch folder.
}
}
Comments
Hi:
I did a few modifications and added a simple graph to observe the response.
This is an experimental code to simulate a swing door under damped oscillatory response and a simple graph. Most of the variables are global and interrelated for easy substitution. Although, I have not tested all possible values for the variables they and the graph are custom made for this particular example. Please let me know if you find any problems. Based on my interpretation from this Wikipedia article: http://en.wikipedia.org/wiki/Damping Built with Processing 2.03.
here is the video: Thanks.
Hi:
Here is an update for this code. Added peaks calculation in real time, drawing the exponentials and continuous graph with lines instead of points. Due to the discrete nature of the computational process, which does not allow for infinitesimal sampling, there are intrinsic inaccuracies in the peaks detection process. They are dependent on the sampling freq, which is affected by the frameRate(), the slope of the graph and the graph speed. I haven't tested all the possibilities of the variables. Most of them are global and interrelated to facilitate substitution. Please let me know if you have suggestions or find problems.
The goal was to obtain an acceptable visual effect.
here is the code:
I think its better for calculating the peaks to find when the slope changes sign only and not also when it equals zero. The equal zero situation remained there from previous tests I was trying and forgot to remove as it is hard to differentiate the visual results, sorry. Please beware that this method to calculate the peaks, works for this particular mathematical function; but it may not be suited for others, like for example those having constant values for extended periods of time (where the slope is zero) or when the function has poles in the interval being analyzed.
Then the find and draw peaks function with the (=) removed from the if() should be:
Thanks.
here is the video of how it works:
And this is a screen picture of the end result: