センリュウのホームページへ ようこそ!
科学プログラム 1
ここでは、簡単な科学プログラムを作ってみます。TurboLinux7workstation用に作ってありますので、それ以外で使用する場合は、ソースファイルの#define FONT1, 2 ……の部分をシステムに合わせたものに変更してmakeし直して使用してください(Redhat7.2では大丈夫だった)。
放物線運動
これは、空気抵抗がない場合と速度の2乗に比例する空気抵抗がある場合の2つのシミュレーションをおこないます。
引数に初速度と打ち上げ角度を指定します。
プログラムのソース
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/keysym.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <math.h>
#define FONT1 "-Adobe-Courier-Bold-R-Normal--11-80-100-100-M-60-ISO8859-1"
#define FONT2 "-adobe-courier-bold-r-normal--75-721-75-75-m-450-iso8859-1"
#define G 9.8
#define PI 3.14159
#define DT 0.01 //近似計算の時間間隔
#define K 0.001 //空気抵抗係数(ものによって変わってくる) ←空気抵抗の大きさを変えたい場合はここを変更してください。
Display *d;
Window wr, w1, w2, wb;
GC gc, gc1, gc2, gcb;
Pixmap pr, p1, p2, pb;
Font f1,f2;
unsigned long black,white;
XColor col[8][8][8];
int bwidth, bheight;
int main(int argc, char *argv[])
{
pthread_t th1;
double v, q;
double vx0, vy0;
double t=0, x=0, y=0, xo, yo, vx, vy, vxo, vyo;
void th_func();
void color();
void draw_base();
void draw_w1base(unsigned long c);
void sig_fnc();
void draw_t(double t, int xo, int yo, int x, int y);
double rk_cal(double vy0, double t, double y);
system("clear");
if(argc < 3){
fputs("usage : program-name <speed> <angle>\n",stderr);
exit(1);
}
v=atof(argv[1]);
q=atof(argv[2]);
d=XOpenDisplay(NULL);
color();
draw_base();
draw_w1base(black);
XFlush(d);
signal(SIGINT,sig_fnc);
pthread_create(&th1, NULL, (void *)th_func, NULL);
vx0=v*cos(q*PI/180);
vy0=v*sin(q*PI/180);
XSetForeground(d,gc1,col[7][0][0].pixel);
while(1)
{
xo=x;
yo=y;
t=t+DT;
x=vx0*t;
y=vy0*t-G*t*t/2;
if(y<0)
{
x=vx0*2*vy0/G;
y=0;
t=2*vy0/G;
draw_t(t,(int)(xo),(int)(yo),(int)(x),(int)(y));
XFlush(d);
break;
}
draw_t(t,(int)(xo),(int)(yo),(int)(x),(int)(y));
XFlush(d);
usleep(1);
}
sleep(5);
XSetForeground(d,gc1,col[0][0][7].pixel);
t=0; x=0; y=0; vx=vx0; vy=vy0;
while(1)
{
xo=x;
yo=y;
vxo=vx;
vyo=vy;
vx=vxo-K*v*vxo*DT;
vy=vyo-(G+K*v*vyo)*DT;
x=xo+(vxo-K*v*vxo*DT/2)*DT;
y=yo+(vyo-(G+K*v*vyo)*DT/2)*DT;
v=sqrt(vx*vx+vy*vy);
t=t+DT;
if(y<0)
{
break;
}
draw_t(t,(int)(xo),(int)(yo),(int)(x),(int)(y));
XFlush(d);
usleep(1);
}
while(1)
{
}
return(0);
}
//////////////////////////////////////////////////////////////////////////////////////////////////
void sig_fnc()
{
exit(0);
}
//////////////////////////////////////////////////////////////////////////////////////////////////
void color()
{
Colormap cmap;
int l,m,n;
black=BlackPixel(d,0);
white=WhitePixel(d,0);
cmap=DefaultColormap(d,0);
for(l=0;l<8;l++)
{
for(m=0;m<8;m++)
{
for(n=0;n<8;n++)
{
col[l][m][n].red=65535-(7-l)*65535/7;
col[l][m][n].green=65535-(7-m)*65535/7;
col[l][m][n].blue=65535-(7-n)*65535/7;
XAllocColor(d,cmap,&col[l][m][n]);
}
}
}
}
//////////////////////////////////////////////////////////////////////////////////////////////////
void draw_base()
{
int x_hot, y_hot;
wr=XCreateSimpleWindow(d,RootWindow(d,0),100,50,800,530,1,black,white);
w1=XCreateSimpleWindow(d,wr,10,10,780,400,1,black,white);
w2=XCreateSimpleWindow(d,wr,10,410,780,80,1,black,black);
wb=XCreateSimpleWindow(d,wr,700,500,50,15,3,col[7][5][5].pixel,white);
XStoreName(d,wr,"parabola");
XSelectInput(d,wr,ExposureMask | KeyPressMask);
XSelectInput(d,wb,ButtonPressMask);
XMapWindow(d,wr);
XMapSubwindows(d,wr);
pr=XCreatePixmap(d,wr,800,530,DefaultDepth(d,0));
p1=XCreatePixmap(d,w1,780,400,DefaultDepth(d,0));
p2=XCreatePixmap(d,w2,780,80,DefaultDepth(d,0));
pb=XCreatePixmap(d,wb,50,15,DefaultDepth(d,0));
gc=XCreateGC(d,pr,0,0);
gc1=XCreateGC(d,p1,0,0);
gc2=XCreateGC(d,p2,0,0);
gcb=XCreateGC(d,pb,0,0);
f1=XLoadFont(d,FONT1);
f2=XLoadFont(d,FONT2);
XSetFont(d,gc,f1);
XSetFont(d,gc1,f1);
XSetFont(d,gc2,f2);
XSetForeground(d,gc,white);
XFillRectangle(d,pr,gc,0,0,800,530);
XSetForeground(d,gc,black);
XDrawString(d,pr,gc,570,513,"quit : press here =>",20);
XSetForeground(d,gcb,white);
XSetBackground(d,gcb,col[7][0][0].pixel);
XReadBitmapFile(d,wb,"./quit.bmp",&bwidth, &bheight, &pb, &x_hot, &y_hot);
}
//////////////////////////////////////////////////////////////////////////////////////////////////
void draw_w1base(unsigned long c)
{
XSetForeground(d,gc1,white);
XFillRectangle(d,p1,gc1,0,0,780,400);
XSetForeground(d,gc1,c);
XDrawString(d,p1,gc1,200,385,"200",3);
XDrawString(d,p1,gc1,400,385,"400",3);
XDrawString(d,p1,gc1,600,385,"600",3);
XDrawLine(d,p1,gc1,0,370,780,370);
XDrawLine(d,p1,gc1,0,170,780,170);
XDrawLine(d,p1,gc1,200,0,200,370);
XDrawLine(d,p1,gc1,400,0,400,370);
XDrawLine(d,p1,gc1,600,0,600,370);
XCopyArea(d,p1,w1,gc1,0,0,780,400,0,0);
}
////////////////////////////////////////////////////////////////////////////////////////////////
void th_func()
{
XEvent event;
char ch[8];
KeySym key;
while(1)
{
XNextEvent(d,&event);
switch(event.type)
{
case Expose:
XCopyArea(d,pr,wr,gc,0,0,800,530,0,0);
XCopyArea(d,p1,w1,gc1,0,0,780,400,0,0);
XCopyArea(d,p2,w2,gc2,0,0,780,80,0,0);
XCopyPlane(d,pb,wb,gcb,0,0,bwidth,bheight,0,0,1);
XFlush(d);
case ButtonPress:
if(event.xbutton.window == wb)
{
exit(EXIT_FAILURE);
}
case KeyPress:
if(XLookupString(&event,ch,8,&key,NULL) == 1);
switch(key)
{
case XK_F1:
exit(EXIT_FAILURE);
case XK_F2:
exit(EXIT_FAILURE);
}
}
}
}
////////////////////////////////////////////////////////////////////////////////////////////////
void draw_t(double t, int xo, int yo, int x, int y)
{
char s[16];
XDrawLine(d,p1,gc1,xo,370-yo,x,370-y);
XCopyArea(d,p1,w1,gc1,0,0,780,400,0,0);
sprintf(s,"%3dm %5.2fsec",x,t);
XSetForeground(d,gc2,black);
XFillRectangle(d,p2,gc2,0,0,780,80);
XSetForeground(d,gc2,col[0][7][0].pixel);
XDrawString(d,p2,gc2,100,60,s,strlen(s));
XCopyArea(d,p2,w2,gc2,0,0,780,80,0,0);
}