Why Doesn't My Win32 Pendulum Simulation Oscillate?

Click For Summary
SUMMARY

The Win32 pendulum simulation fails to oscillate due to incorrect calculations in the physics update loop. The tension force is calculated using the sine and cosine of the angle, but the update logic for the ball's position and angle (theata) is flawed. Specifically, the current position updates do not properly reflect the physics of a pendulum, leading to erratic behavior. The simulation is written in C using the Win32 API, and the primary issue lies in the handling of the acceleration and velocity calculations.

PREREQUISITES
  • Understanding of basic physics principles, particularly forces and motion.
  • Familiarity with C programming language and Win32 API.
  • Knowledge of trigonometric functions (sine and cosine) and their application in simulations.
  • Experience with debugging techniques, such as using print statements to trace variable values.
NEXT STEPS
  • Investigate the correct implementation of pendulum physics, focusing on angular motion and restoring forces.
  • Learn about numerical integration methods for simulating motion, such as Euler's method.
  • Explore debugging techniques in C, specifically using printf for variable tracing.
  • Review the use of floating-point arithmetic in physics simulations to ensure precision in calculations.
USEFUL FOR

Software developers, physics students, and hobbyists interested in game development or simulations who want to understand and fix oscillation issues in pendulum simulations.

stringa
Messages
7
Reaction score
0

Homework Statement



Simple Pendulum using Forces (Computer Simulation)

Max theata = PI / 6

Force Of Gravity is { 0, 10 }

Force_Tension.x = - 10 * sin(balls.theata);
Force_Tension.y = - 10 * cos(balls.theata);

Homework Equations



accelleration = Force_Tension - Force_Gravity / mass


The Attempt at a Solution



Written in Win32 APi

All Physics is done in WM_CREATE and updatePhysics...the program does not oscillate !


/* animation_shell.c
** -- Bare bones windows animation program.
** cs230 2/07
*/

#include <stdlib.h>
#include <time.h>
#include <windows.h>
#include <math.h>

#define PI 3.14159f

struct _2Dfloat {

float x;
float y;

};

struct ball {

_2Dfloat current_position;
_2Dfloat current_velocity;
_2Dfloat current_accelleration;

int length_of_rope;
POINT rope_origin;

float theata;

};

float sqrt_g_over_r;

ball balls;

_2Dfloat Force_Gravity = {0, 10};
_2Dfloat Force_Tension;

void draw(HWND win);
void updatePhysics(void);

LRESULT CALLBACK WinProc(HWND win, UINT msg, WPARAM wp, LPARAM lp) {

switch (msg) {

case WM_CREATE:


balls.length_of_rope = 300;

sqrt_g_over_r = sqrt(10.0 / balls.length_of_rope);

balls.rope_origin.x = 300;
balls.rope_origin.y = 0;

balls.theata = - PI / 6;

Force_Tension.x = - 10 * sin(balls.theata);
Force_Tension.y = - 10 * cos(balls.theata);

balls.current_accelleration.x = 0;
balls.current_accelleration.y = 0;

balls.current_velocity.x = 0;
balls.current_velocity.y = 0;

balls.current_position.x = balls.rope_origin.x + balls.length_of_rope * sin(balls.theata);
balls.current_position.y = balls.length_of_rope * cos(balls.theata);

break;

case WM_CHAR:
if (wp == 0x1b)
DestroyWindow(win);
break;

case WM_DESTROY:
PostQuitMessage(0);
break;

default:
return DefWindowProc(win,msg,wp,lp);
}
return 0;
}


int WINAPI WinMain(HINSTANCE instance, HINSTANCE ignore,
LPSTR command_line, int show) {
char *window_title = "Put title here",
*class_name = "Give class name";
WNDCLASS wc;
HWND win;
MSG msg;

wc.style = 0;
wc.lpfnWndProc = WinProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = instance;
wc.hIcon = LoadIcon(NULL,IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL,IDC_ARROW);
wc.hbrBackground = NULL;
wc.lpszMenuName = NULL;
wc.lpszClassName = class_name;
RegisterClass(&wc);

win = CreateWindow(class_name,window_title,
WS_POPUP,CW_USEDEFAULT,CW_USEDEFAULT,
GetSystemMetrics(SM_CXSCREEN),GetSystemMetrics(SM_CYSCREEN),NULL,NULL,instance,NULL);
ShowWindow(win,show);

// Animation Styple "greedy" event loop
while (IsWindow(win)) {
if (PeekMessage(&msg,win,0,0,PM_REMOVE)) {

TranslateMessage(&msg);
DispatchMessage(&msg); }
else

updatePhysics();
draw(win);
// give some cycles back to the CPU
Sleep(50);
}

UnregisterClass(class_name,instance);

return msg.wParam;
}


void draw(HWND win) {
static COLORREF color = RGB(255,128,128);
HDC dc;
HBRUSH brush;
RECT rect;

dc = GetDC(win);
GetClientRect(win,&rect);
FillRect(dc,&rect,(HBRUSH) GetStockObject(WHITE_BRUSH));

const int scale = 50;
// Draw the Rope
MoveToEx(dc, balls.rope_origin.x, balls.rope_origin.y, NULL);

LineTo(dc, balls.current_position.x, balls.current_position.y);

// Draw the force of Tension

LineTo(dc, balls.current_position.x + scale * Force_Tension.x, balls.current_position.y + scale * Force_Tension.y);

MoveToEx(dc, balls.current_position.x, balls.current_position.y, NULL);


LineTo(dc, balls.current_position.x, balls.current_position.y + Force_Gravity.y);

ReleaseDC(win,dc);
}

void updatePhysics(void)
{

static float time = 0;

const float change_of_time = .9f;
// Update Theata

// Calculate Accelleration by old theata
Force_Tension.x = - 10 * sin(balls.theata);
Force_Tension.y = - 10 * cos(balls.theata);

// The mass has already been divided out of the system...thus subtracting the forces
// gives me the accelleration
balls.current_accelleration.x = Force_Gravity.x - Force_Tension.x;
balls.current_accelleration.y = Force_Gravity.y - Force_Tension.y;



if (balls.theata < 0)
{
balls.current_velocity.x = - balls.current_accelleration.x * (change_of_time);
}
else
{
balls.current_velocity.x = balls.current_accelleration.x * (change_of_time);
}

balls.current_velocity.y = balls.current_accelleration.y * (change_of_time);


// Update Ball Position

// I thin this is ****ing everything up
balls.current_position.x += balls.current_velocity.x * (change_of_time);
balls.current_position.y += balls.current_velocity.y * (change_of_time);

// Calculate my new theata with the dot product

// I will try and dot the current rope with the force of gravity


//balls.theata = I keep trying the dotProduct of gravity and current ball position
// and it never seems to work

// what am I doing wrong

}
 
Physics news on Phys.org
printf (or count) is your friend...see if the values are what you expect them to be.

u might want to clean up the code so its readable

also printout gravity

and it might help to explain what is the ball doing that's erroneous (besides sayign its not oscillating)...is it going to infinity.

from first look it might be sin/cos values...where your using floats.
 

Similar threads

  • · Replies 16 ·
Replies
16
Views
5K
  • · Replies 4 ·
Replies
4
Views
6K