96 :
ばねばね:
#include <GL/glut.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <math.h>
#define sub_timeval(tv1, tv2) (tv1.tv_sec - tv2.tv_sec)+ \
(tv1.tv_usec - tv2.tv_usec)/1000000.0
struct timeval g_old;
struct timeval g_now;
GLdouble g_x[2]; /* 各点のx座標(0番目が下部,1番目が上部 */
GLdouble g_vx[2]; /* 各点のx方向の速度 */
GLdouble g_ax[2]; /* a[0] を下部とする */
double k=200.0; /* ばね定数 */
double m=2.0; /* 重りの重さ */
double l=0.5; /* ばねの長さ */
double g=9.8; /* 重力加速度 */
void redisplay(int i);
void idle(void);
void display(void);
void keyboard(unsigned char key, int x, int y);
void InitCoordinate(void);
/* glutIdleFuncのコールバック */
void idle()
{
glutPostRedisplay();
}
97 :
ばねばね:02/07/10 18:25 ID:2/Fp5szV
/* glutDisplayFuncのコールバック,ディスプレイ(再表示時含む)関数 */
void display(void)
{
static double t; /* 時間 */
gettimeofday(&g_now, NULL);
t = sub_timeval(g_now, g_old);
g_old = g_now;
/* 位置を求める */
g_x[0] += g_vx[0] * t; g_x[1] += g_vx[1] * t;
/* 速度を求める */
g_vx[0] += g_ax[0] * t; g_vx[1] += g_ax[1] * t;
if (g_x[0] <= 0) {g_x[0] = 0.0; g_vx[0] = (g_vx[0]<0)?0:g_vx[0];}
if (g_x[1] <= 0) {g_x[1] = 0.0; g_vx[1] = (g_vx[1]<0)?0:g_vx[1];}
/* 加速度を求める */
g_ax[0] = -g;
if ((g_x[1] - g_x[0])-l >0) {
g_ax[1] = -g;
g_vx[0] = g_vx[1];
} else
g_ax[1] = -g+(k*(l - (g_x[1]-g_x[0])))/m;
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity(); /* モデルビュー変換行列の初期化 */
glColor3d(1.0, 0.0, 0.0);
glBegin(GL_LINES);
glVertex2d(0, g_x[0]);
glVertex2d(0, g_x[1]);
glEnd();
glutSwapBuffers();
}
98 :
ばねばね:02/07/10 18:26 ID:2/Fp5szV
void keyboard(unsigned char key, int x, int y)
{
switch (key) {
case 's':
gettimeofday(&g_old, NULL);
glutIdleFunc(idle);
break;
case 'q':
case 'Q':
case '\033': /* ESC */
exit(0);
default:
break;
}
}
/* 座標の初期化 */
void
InitCoordinate(void)
{
g_x[0] = 0.0;
g_x[1] = 0.5;
g_vx[0] = 0.0;
g_vx[1] = 0.0;
g_ax[0] = -g;
g_ax[1] = -g + (k*(l-(g_x[1]-g_x[0])))/m;
}
99 :
ばねばね:02/07/10 18:27 ID:2/Fp5szV
/* メインルーチン */
int main(int ac, char **av)
{
int i=0;
/* 初期設定 */
glutInitWindowPosition(100, 100);
glutInitWindowSize(320, 240);
glutInit(&ac, av);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
/* ディスプレイ関連 */
glutCreateWindow(*av);
glutDisplayFunc(display);
/* 入力関連 */
glutKeyboardFunc(keyboard);
glClearColor(1.0, 1.0, 1.0, 0.0); /* 背景を白に */
/* メインループ */
gettimeofday(&g_old, NULL);
InitCoordinate();
glutMainLoop();
return 0;
}
100 :
ばねばね:02/07/10 18:39 ID:2/Fp5szV
sodaplay作るにはまずバネだろと思ったんでバネ作ってみましたが、誤差があって
ちゃんと動きません。(なぜかエネルギーが増大していきます)
オイラー方で差分を取るだけでは駄目みたいです。
後sodaplayはやっぱり3次元を投影してるんじゃないか?
sodazoo見たら奥行きが無いと説明できない動きする奴がいくつかあったよ。
(ばねの両端に重りくっつけてそれを無重力空間で回転させるてるのを真横からみた
と覚しき物があった)
101 :
ばねばね:02/07/10 18:40 ID:2/Fp5szV
あ、sdlじゃないからsageた方が良かったね。
/* 一旦CM */
103 :
ばねばね:02/07/10 18:45 ID:2/Fp5szV
おそらくばねと棒と重りからsodaplayの生物はできてるんだと思うけど問題は
どうやってシミュレートしてるかかなぁ。
厳密に計算できるのかなあれは?
自分は「どう考えても近似だろ」と言う仮定の元にプログラム組んだら上の様な有様。
機械工学とかに詳しい人は教えて欲しいです。