// ■多重振り子 #include "myWin.h" #include #include #define PI 3.14159265358979 #define XStart 35 #define YStart 5 // 図形の位置調整でここを変更している。 #define Num 50 typedef struct { //状態 double dAlf, Alf, dTheta, Theta, X, Y; } state; typedef struct{ double L, M, gByL; } parameter; double g, dt, t; int ID1,ID2; state a[Num][2]; double F[Num]; parameter Pa; double Myu;// 動粘性抵抗 double KFact;//伝達係数 int timerFlag; static HDC hBuff; static HBITMAP hBM; void genBitmap(HWND hw){ HDC hdc=GetDC(hw); hBM=CreateCompatibleBitmap(hdc,550,550); hBuff=CreateCompatibleDC(hdc); SelectObject(hBuff,hBM); ReleaseDC(hw,hdc); } void clearBitmap(){ SelectObject(hBuff,GetStockObject(NULL_PEN)); PatBlt(hBuff,0, 0,450,450,WHITENESS); } void drawBall(double X1, double Y1){ HPEN hpen=CreatePen(PS_SOLID,2,0x00); SelectObject(hBuff,hpen); HBRUSH hbrush=CreateSolidBrush(0xCCCCCC) ; SelectObject(hBuff,hbrush); int X=(int)(X1*6), Y=(int)(Y1*6); Ellipse(hBuff,X-3,Y-3,X+3,Y+3); DeleteObject(hbrush);DeleteObject(hpen); } void drawLine(double X1, double Y1,double X2, double Y2){ HPEN hpen=CreatePen(PS_SOLID,2,0x00); SelectObject(hBuff,hpen); int IX, IY; IX=(int)(X1*6);IY=(int)(Y1*6); MoveToEx(hBuff,IX,IY,NULL); IX=(int)(X2*6);IY=(int)(Y2*6); LineTo (hBuff,IX,IY); DeleteObject(hpen); } void draw(){ clearBitmap(); double X1 = XStart, Y1 = YStart, X2,Y2; for(int i=Num-1; i>=0;i--){ double cosTH = cos(a[i][ID1].Theta), sinTH = sin(a[i][ID1].Theta); X2 = Pa.L * sinTH + X1; Y2 = Pa.L * cosTH + Y1; drawLine(X1, Y1, X2, Y2); drawBall(X1,Y1); X1 = X2; Y1 = Y2; } drawBall(X2,Y2); } void initData(){ Pa.L = 1; Pa.M = 0.1; double TH = 30.0 * PI / 180; g = 9.8; dt = 0.05; Myu = 0.001; KFact = 0.8;//KFact/Myu(0〜1)を変更してみよう for(int i=0; i=0; i--){ TH += a[i][ID1].dTheta; a[i][ID2].dTheta *= (1 - Myu); a[i][ID2].Theta = a[i][ID1].Theta+ a[i][ID2].dTheta* dt; } ID1 = ID2; ID2 = 1-ID2;draw(); } void procPaint(HWND hw, WPARAM wp,LPARAM lp){ PAINTSTRUCT ps; HDC hdc=BeginPaint(hw, &ps); BitBlt(hdc, 0,0,450,450,hBuff,0,0,SRCCOPY); EndPaint(hw,&ps); } void procLButtonDown(HWND hw, WPARAM wp,LPARAM lp){ SetTimer(hw,1,10,NULL);timerFlag=true; initData(); InvalidateRect(hw,NULL,TRUE); } void procCreate(HWND hw, WPARAM wp,LPARAM lp){ SetWindowText(hw,TEXT("多重振り子")); MoveWindow(hw,0,0,450,450,TRUE); genBitmap(hw);clearBitmap(); SetTimer(hw,1,10,NULL);timerFlag=true; initData(); InvalidateRect(hw,NULL,TRUE); } void procRButtonDown(HWND hw, WPARAM wp,LPARAM lp){ if(timerFlag){ KillTimer(hw,1);initData();} else update(); timerFlag= false; InvalidateRect(hw,NULL,TRUE); } void procTimer(HWND hw, WPARAM wp,LPARAM lp){ update(); InvalidateRect(hw,NULL,TRUE); } LRESULT CALLBACK WndProc(HWND hw, UINT msg, WPARAM wp,LPARAM lp){ switch(msg){ case WM_DESTROY : PostQuitMessage(0) ; return 0; case WM_CREATE : procCreate(hw,wp,lp) ; return 0; case WM_PAINT : procPaint(hw,wp,lp) ; return 0; case WM_TIMER : procTimer(hw,wp,lp) ; return 0; case WM_LBUTTONDOWN : procLButtonDown(hw,wp,lp) ; return 0; case WM_RBUTTONDOWN : procRButtonDown(hw,wp,lp) ; return 0; } return DefWindowProc(hw,msg,wp,lp); }