Repository navigation
Expand file tree
/
Copy path007_001_MidpointMethodSpring.pde
More file actions
139 lines (113 loc) · 3.56 KB
/
Copy path007_001_MidpointMethodSpring.pde
File metadata and controls
139 lines (113 loc) · 3.56 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
float Stiffness = 5.0;
float BobMass = 0.5;
int StateSize = 3;
float[] InitState = new float[StateSize];
float[] State = new float[StateSize];
int StateCurrentTime = 0;
int StatePositionX = 1;
int StateVelocityX = 2;
int WindowWidthHeight = 300;
float WorldSize = 2.0;
float PixelsPerMeter;
float OriginPixelsX;
float OriginPixelsY;
void setup()
{
// Create initial state.
InitState[StateCurrentTime] = 0.0;
InitState[StatePositionX] = 0.65;
InitState[StateVelocityX] = 0.0;
// Copy initial state to current state.
// notice that this does not need to know what the meaning of the
// state elements is, and would work regardless of the state's size.
for ( int i = 0; i < StateSize; ++i )
{
State[i] = InitState[i];
}
// Set up normalized colors.
colorMode( RGB, 1.0 );
// Set up the stroke color and width.
stroke( 0.0 );
//strokeWeight( 0.01 );
// Create the window size, set up the transformation variables.
size( WindowWidthHeight, WindowWidthHeight );
PixelsPerMeter = (( float )WindowWidthHeight ) / WorldSize;
OriginPixelsX = 0.5 * ( float )WindowWidthHeight;
OriginPixelsY = 0.5 * ( float )WindowWidthHeight;
textSize( 24 );
}
// Draw our State, with the unfortunate units conversion.
void DrawState()
{
// Compute end of arm.
float SpringEndX = PixelsPerMeter * State[StatePositionX];
// Compute the CORRECT position.
float sqrtKoverM = sqrt( Stiffness / BobMass );
float x0 = InitState[StatePositionX];
float v0 = InitState[StateVelocityX];
float t = State[StateCurrentTime];
float CorrectPositionX = ( x0 * cos( sqrtKoverM * t ) ) +
( ( v0 / sqrtKoverM ) * sin( sqrtKoverM + t ) );
// Compute draw pos for "correct"
float CorrectEndX = PixelsPerMeter * CorrectPositionX;
// Draw the spring.
strokeWeight( 1.0 );
line( 0.0, 0.0, SpringEndX, 0.0 );
// Draw the spring pivot
fill( 0.0 );
ellipse( 0.0, 0.0,
PixelsPerMeter * 0.03,
PixelsPerMeter * 0.03 );
// Draw the spring bob
fill( 1.0, 0.0, 0.0 );
ellipse( SpringEndX, 0.0,
PixelsPerMeter * 0.1,
PixelsPerMeter * 0.1 );
// Draw the correct bob in blue
fill( 0.0, 0.0, 1.0 );
ellipse( CorrectEndX, -PixelsPerMeter * 0.25,
PixelsPerMeter * 0.1,
PixelsPerMeter * 0.1 );
}
// Time Step function.
void TimeStep( float i_dt )
{
// Compute acceleration from current position.
float A = ( -Stiffness / BobMass ) * State[StatePositionX];
// Update position half-way.
State[StatePositionX] += ( i_dt/2.0 ) * State[StateVelocityX];
// Update velocity based on acceleration.
State[StateVelocityX] += i_dt * A;
// Update position half-way.
State[StatePositionX] += ( i_dt/2.0 ) * State[StateVelocityX];
// Update current time.
State[StateCurrentTime] += i_dt;
}
// Processing Draw function, called every time the screen refreshes.
void draw()
{
// Time Step.
TimeStep( 1.0/24.0 );
// Clear the display to a constant color.
background( 0.75 );
// Label.
fill( 1.0 );
text( "Midpoint Method", 10, 30 );
pushMatrix();
// Translate to the origin.
translate( OriginPixelsX, OriginPixelsY );
// Draw the simulation
DrawState();
}
// Reset function. If the key 'r' is released in the display,
// copy the initial state to the state.
void keyReleased()
{
if ( key == 114 )
{
for ( int i = 0; i < StateSize; ++i )
{
State[i] = InitState[i];
}
}
}