Hatena::ブログ(Diary)

DenpaFreak このページをアンテナに追加 RSSフィード

2008-01-26

課題ソースコード

課題終了しました - DenpaFreak

ここで使ったソースコード公開しておきます。

ちなみに、中口先生の授業:情報画像工学実験3-5 画像処理応用の課題でこのコードをコピペした場合、最悪単位がこないことがあります。

あくまで、参考にしてください。

「続きを読む」をクリックするとコードが表示されます。





/***********************************************************
立方体の中で球体を動かしまくるだけのプログラム
Denpafreak
http://d.hatena.ne.jp/denpafreak/
***********************************************************/


/*for Win32*/
//#include <glut.h> 
//#define _USE_MATH_DEFINES

#include <stdlib.h>
#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <math.h>
#include <stdio.h>
#define KEY_ESC 27
#define X 0
#define Y 1
#define Z 2
#define N 13 /*must be bigger than 3*/
#define Nb 900/*number of the ball(s)*/

/* 関数のプロトタイプ宣言 */
void polarview( void );
void resetview( void );
unsigned char wireFlag = GL_TRUE;
unsigned char revolveFlag = GL_FALSE;
int xBegin, yBegin;


/* グローバル変数の宣言 */
int mButton;
float distance, twist, elevation, azimuth;
float theta = 15.0;
int width = 800,height = 700;
double timing = 60;
double cubesize= 0.5;
double color_step = 0.90;/*0< step<=1*/
double dN = N;
double effectiveradius = 3.0;


typedef struct _vector{
double x,y,z;
}vector;

typedef struct _object{
vector location;
vector velocity;
vector rotate;
double en;
}obj;

obj wall[6][N][N];
obj ball[Nb];

void makeobj(obj *object){
 double red,green,blue;	
	if(object->en < 0.005) object->en = 0.0;
	else if(object->en >1.0) object->en =1.0;
if(object->en < 0.25){
	red = 0.0;
	green = (object->en/0.25);
	blue = 1.0;
}else if(object->en < 0.5){
	red = 0.0;
	green = 1.0;
	blue = (1.0 - ((object->en-0.25)/0.25));
}else if(object->en < 0.75){
red = ((object->en-0.5)/0.25);
	green = 1.0;
	blue = 0.0;
}else{
red = 1.0;
green = (1.0 - ((object->en-0.75)/0.25));
	blue = 0.0;
}
glColor3f(red,green,blue);

glPushMatrix();
glTranslatef(object->location.x,object->location.y,object->location.z);
glutWireCube(cubesize);

glPopMatrix();
	object->en*=color_step;
	if(object->en < 0.005) object->en = 0.0;
	else if(object->en >1.0) object->en =1.0;
}



void setup(void){

int i, j , k;
double z,zz;
double intercept = -(dN-1)/2.0;
/* make walls */

for(i = 0 ; i < 2 ; i++){
	for(j = 0; j < N ; j++){
		for(k = 0 ; k < N ; k++){
			wall[i][j][k].location.x = j + intercept;
		wall[i][j][k].location.y = k + intercept;
			wall[i][j][k].location.z = (dN-1.0)*i + intercept;
		}
	}
}
	for(i = 0 ; i < 2 ; i++){
		for(j = 0; j < N ; j++){
			for(k = 0 ; k < N ; k++){
				wall[i+2][j][k].location.x = j + intercept;
				wall[i+2][j][k].location.y = (dN-1.0)* i + intercept;
				wall[i+2][j][k].location.z = k + intercept;
			}
		}
	}
	for(i = 0 ; i < 2 ; i++){
		for(j = 0; j < N ; j++){
			for(k = 0 ; k < N ; k++){
				wall[i+4][j][k].location.x = (dN-1.0) * i + intercept;
				wall[i+4][j][k].location.y = k + intercept;
				wall[i+4][j][k].location.z = j + intercept;
			}
		}
	}


for(i = 0 ; i < 6 ; i++){
for(j = 0 ; j < N ; j++){
for(k = 0; k < N ; k++){
	wall[i][j][k].en = 0.0;	
}
}
}



srand(time(NULL));

for(i = 0 ; i < Nb ; i++){
z = ((double)(rand() % 100) / 100.0); 
ball[i].location.x = (N/2 - z*N );
z = ((double)(rand() % 100) / 100.0); 
ball[i].location.y =(N/2 - z*N );
z = ((double)(rand() % 100) / 100.0);
ball[i].location.z =(N/2 - z*N);



z = ((double)(rand() % 100) / 100.0); 
zz = ((double)(rand() % 100) / 100.0); 

ball[i].velocity.x = cos(2*M_PI*zz)*cos(2*M_PI*z);
ball[i].velocity.y = cos(2*M_PI*zz)*sin(2*M_PI*z);
ball[i].velocity.z = sin(2*M_PI*zz);
}
}

void makewall(void){
int i,j,k;

for(i = 0 ; i < 6 ; i++)
for(j = 0 ; j < N ; j++)
for(k = 0 ; k < N ; k++)
		makeobj(&wall[i][j][k]);
 
}

void makeball(void){
int i;
for(i = 0 ; i <Nb ; i++){
glPushMatrix();
glColor3f(1.0-ball[i].en,1.0-ball[i].en,1.0-ball[i].en);
glTranslatef(ball[i].location.x,ball[i].location.y,ball[i].location.z);
glutWireSphere(.1,30,20);
glPopMatrix();
	ball[i].en*=color_step;
	if(ball[i].en < 0.005) ball[i].en = 0.0;
	else if(ball[i].en >1.0) ball[i].en =1.0;
 }
}
void ifcollision(void){
	int i,j,k;
double innerRange =(dN/2 - cubesize);
double temp_dist;
double t = 1.0 / timing;
	for(i = 0 ; i < Nb ; i++){
		ball[i].location.x += ((ball[i].velocity.x)*t);
		ball[i].location.y += ((ball[i].velocity.y)*t);
		ball[i].location.z += ((ball[i].velocity.z)*t);
	
		if(ball[i].location.x >innerRange){
			ball[i].location.x = innerRange;
			ball[i].velocity.x *=-1.0; 
	
			for(j = 0 ; j < N ; j++){
				for(k = 0 ; k < N ; k++){
					temp_dist =pow(ball[i].location.y-wall[5][j][k].location.y,2)+
						pow(ball[i].location.z-wall[5][j][k].location.z,2);
					if(temp_dist <= 3.0) wall[5][j][k].en += (3.0 - temp_dist)/3.0;
				}
			}
			ball[i].en = 1.0;
		}else if(ball[i].location.x < (-1)*innerRange){
			ball[i].location.x = (-1)*innerRange;
			ball[i].velocity.x *=-1.0; 

			for(j = 0 ; j < N ; j++){
				for(k = 0 ; k < N ; k++){
					temp_dist =pow(ball[i].location.y-wall[4][j][k].location.y,2)+
						pow(ball[i].location.z-wall[4][j][k].location.z,2);
					if(temp_dist <= 3.0) wall[4][j][k].en += (3.0 - temp_dist)/3.0;
				}
			}
			ball[i].en = 1.0;
		}

		if(ball[i].location.y >innerRange){
			ball[i].location.y = innerRange;
			ball[i].velocity.y *=-1.0; 
		for(j = 0 ; j < N ; j++){
				for(k = 0 ; k < N ; k++){
					temp_dist =pow(ball[i].location.x-wall[3][j][k].location.x,2)+
						pow(ball[i].location.z-wall[3][j][k].location.z,2);
					if(temp_dist <= 3.0) wall[3][j][k].en += (3.0 - temp_dist)/3.0;
				
				}
			
}
ball[i].en = 1.0;			
}else if(ball[i].location.y < (-1)*innerRange){
	ball[i].location.y = (-1)*innerRange;
	ball[i].velocity.y *=-1.0; 

		for(j = 0 ; j < N ; j++){
	for(k = 0 ; k < N ; k++){
			temp_dist =pow(ball[i].location.x-wall[2][j][k].location.x,2)+
				pow(ball[i].location.z-wall[2][j][k].location.z,2);
			if(temp_dist <= 3.0) wall[2][j][k].en += (3.0 - temp_dist)/3.0;
		}
		 
	}

ball[i].en = 1.0;
}
	if(ball[i].location.z >innerRange){
	ball[i].location.z = innerRange;
	ball[i].velocity.z *=-1.0; 
for(j = 0 ; j < N ; j++){
	for(k = 0 ; k < N ; k++){
			temp_dist =pow(ball[i].location.x-wall[1][j][k].location.x,2)+
				pow(ball[i].location.y-wall[1][j][k].location.y,2);
			if(temp_dist <= effectiveradius) wall[1][j][k].en += (effectiveradius - temp_dist)/effectiveradius;
		}
	}


	ball[i].en = 1.0;
}else if(ball[i].location.z < (-1)*innerRange){
	ball[i].location.z = -innerRange;
	ball[i].velocity.z *=-1.0; 
		for(j = 0 ; j < N ; j++){
	for(k = 0 ; k < N ; k++){
			temp_dist =pow(ball[i].location.x-wall[0][j][k].location.x,2)+
				pow(ball[i].location.y-wall[0][j][k].location.y,2);
			if(temp_dist <= effectiveradius) wall[0][j][k].en += (effectiveradius - temp_dist)/effectiveradius;
		}
	}



ball[i].en = 1.0;
}
}
}


/***********************************************************
|Function:	display()
|
|Desc:	グラフィックの描画
***********************************************************/
void display(void)
{

glClear(GL_COLOR_BUFFER_BIT);
glPushMatrix();
polarview();
glRotatef (theta, 0.0, 1.0, 0.0);
makeball();
makewall();
glPopMatrix ();
glutSwapBuffers(); 
}



/***********************************************************
|Function:	idle()
|
|Desc:	待機時のイベント処理(反応拡散の計算を行う)
***********************************************************/
void Idle ( void )
{
int i;

double t = 1.0 / timing;

	for(i = 0 ; i < Nb ; i++){
		ball[i].location.x += ((ball[i].velocity.x)*t);
		ball[i].location.y += ((ball[i].velocity.y)*t);
		ball[i].location.z += ((ball[i].velocity.z)*t);
	}

ifcollision();
 glutPostRedisplay();

}
void rotation( void )
{
	theta = fmod( theta + 3, 360.0 );

	glutPostRedisplay();
}

/***********************************************************
|Function:	myKbd()
|
|Desc:	キーボードイベントの処理(反応拡散パラメータ変更)
|Arg:		unsigned char key	
|Arg:		int x	
|Arg:		int y	
***********************************************************/
void myKbd( unsigned char key, int x, int y )
{
	switch( key ) {
	case 'w':
		wireFlag = !wireFlag;
		break;
	case 'R':
		resetview();
		break;
	case KEY_ESC:
		exit( 0 );
	}
	glutPostRedisplay();
	x = y = 0;	/* Warning 対策 */
} 


/***********************************************************
|Function:	myMouse()
|
|Desc:	マウス使用時の処理(マウス動作開始点の記録)
|Arg:		int button	
|Arg:		int state	
|Arg:		int x	
|Arg:		int y	
***********************************************************/
void myMouse( int button, int state, int x, int y )
{
	if (state == GLUT_DOWN) {
		switch(button) {
		case GLUT_LEFT_BUTTON:
			mButton = button;
			break;
		case GLUT_MIDDLE_BUTTON:
			revolveFlag = !revolveFlag;
			if( revolveFlag == GL_TRUE )
				glutIdleFunc( rotation );
			else
				glutIdleFunc(Idle);
			break;
		case GLUT_RIGHT_BUTTON:
			mButton = button;
			break;
		}
		xBegin = x;
		yBegin = y;
	}
}


/***********************************************************
|Function:	myMotion()
|
|Desc:	マウス移動イベントの処理(視点等の変更)
|Arg:		int x	
|Arg:		int y	
***********************************************************/
void myMotion( int x, int y )
{
	int xDisp, yDisp;
	
	xDisp = x - xBegin;
	yDisp = y - yBegin;

	switch (mButton) {
	case GLUT_LEFT_BUTTON:
		azimuth += (float) xDisp/2.0;
		elevation -= (float) yDisp/2.0;
		break;
	case GLUT_RIGHT_BUTTON:
		distance += (float) yDisp/50.0;
		break;
	}
	xBegin = x;
	yBegin = y;
	glutPostRedisplay();
}


/***********************************************************
|Function:	myInit()
|
|Desc:	OpenGLの初期化
|Arg:		char *progname	
***********************************************************/
void myInit (char *progname)
{

float aspect = (float) width / (float) height;


glutInitWindowPosition(0, 0);
glutInitWindowSize( width, height);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
glutCreateWindow(progname);

glClearColor (0.0, 0.0, 0.0, 1.0);

glutKeyboardFunc(myKbd);
glutMouseFunc(myMouse);
glutMotionFunc(myMotion);
resetview();

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0, aspect, 1.0, 30.0);
glMatrixMode(GL_MODELVIEW);

setup();
}


/***********************************************************
|Function:	resetview()
|
|Desc:	視点のリセット
***********************************************************/
void resetview( void )
{
	distance = dN+3.0;
	twist = 0.0;
	elevation = 0.0;
	azimuth = 0.0;
}


/***********************************************************
|Function:	polarview()
|
|Desc:	座標回転
***********************************************************/
void polarview( void )
{
	glTranslatef( 0.0, 0.0, -distance);
	glRotatef( -twist, 0.0, 0.0, 1.0);
	glRotatef( -elevation, 1.0, 0.0, 0.0);
	glRotatef( -azimuth, 0.0, 1.0, 0.0);
}


/***********************************************************
|Function:	main()
|
|Desc:	メイン関数
|Arg:		int argc	
|Arg:		char** argv	
|Return:	int	
***********************************************************/
int main(int argc, char** argv)
{
	glutInit(&argc, argv);
	myInit(argv[0]);
	glutDisplayFunc(display);
	glutIdleFunc(Idle);
	glutMainLoop(); 
	return( 0 );
}


スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証