返信ありがとうございます。
>h2so5さん
今現在のソースを示していませんでした。申し訳ありません。
実は、ものすごく頭の悪い強引な実装で晒したくないのですがとりあえずそれらしい経路は辿れています。
分岐や進行角度の更新はプリズム内の反射はなく、完全に2回の屈折のみで終わると仮定して進めています。
「実装方法はともかく、画面でみれば光の経路らしい」を実現している程度ですので参考にならないかもしれません・・・。
具体的な角度の計算式はこちらを参考にしました。
http://www.cvimgkk.com/products/cvi/cvi ... guide.html
全ソースコードです。
コード:
#include <math.h>
#include <GL/glut.h>
#include <GL/gl.h>
//ウインドウサイズ
#define WIN_W 400
#define WIN_H 400
//三角形の三点の座標
#define TRI_TX 0.0
#define TRI_TY (-0.8 + sin(M_PI/3)*0.6)
#define TRI_LX -0.3
#define TRI_LY -0.8
#define TRI_RX 0.3
#define TRI_RY -0.8
//光源の初期位置
#define START_X -1.0
#define START_Y -0.5
//プリズムの絶対屈折率
#define N 1.5
//光のパラメータ
float ray_x = START_X;
float ray_y = START_Y;
float angle = 0.0;
int way = 0;
void DrawField(void){
glColor3f(0.7, 0.7, 0.7);
glPointSize(1.0);
glBegin(GL_LINES);
glVertex2f(-1.0, -0.8);
glVertex2f(1.0, -0.8);
glEnd();
glColor3f(0.5, 0.5, 0.5);
glBegin( GL_POLYGON );
glVertex3f(-1.0, -0.8, 0.0);
glVertex3f(-1.0,-1.0, 0.0);
glVertex3f( 1.0,-1.0, 0.0);
glVertex3f( 1.0, -0.8, 0.0);
glEnd();
glColor3f(1.0, 1.0, 1.0);
glBegin( GL_POLYGON );
glVertex2f(TRI_TX, TRI_TY);
glVertex2f(TRI_LX, TRI_LY);
glVertex2f(TRI_RX, TRI_RY);
glEnd();
}
void DrawPoint(void){
glColor3f(0.7, 0.7, 0.7);
glPointSize(4.0);
glBegin(GL_POINTS);
glVertex2f(ray_x, ray_y);
glEnd();
}
void Reshape(GLsizei w, GLsizei h){
// 画面の大きさを変更する
glutReshapeWindow(WIN_W,WIN_H);
}
void MyIdle(void){
//光が地面についたらそれ以上進まない
if(ray_y<=-0.8)
return;
//光のx,y座標。x座標は0.001ずつ増える。
ray_x += 0.001;
ray_y += tan(angle)*0.001;
//異なる媒質へ進むときの屈折 空気→プリズム
if(ray_y <= (float)(((TRI_TY-TRI_LY)/(TRI_TX-TRI_LX))*(ray_x-TRI_TX)+TRI_TY) && way == 0){
angle = -M_PI/6 + asin(sin(M_PI/6)/N);
way = 1;
}
//異なる媒質へ進むときの屈折 プリズム→空気
if(ray_y >= (float)(((TRI_TY-TRI_RY)/(TRI_TX-TRI_RX))*(ray_x-TRI_TX)+TRI_TY) && way == 1){
angle += N*sin(M_PI/3-asin(sin(M_PI/6)/N)) - asin(N*sin(M_PI/3-asin(sin(M_PI/6)/N)));
way = 2;
}
glutPostRedisplay();
}
void RenderScene(void){
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
DrawField();
DrawPoint();
glutSwapBuffers();
}
int main( int argc, char** argv ){
//初期化
glutInit( &argc, argv );
//ディスプレイの設定
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(WIN_W,WIN_H);
//ウインドウを開く
glutCreateWindow("Prism");
//描写に関する関数の定義
glutReshapeFunc(Reshape);
glutDisplayFunc(RenderScene);
glutIdleFunc(MyIdle);
glClearColor(0.0, 0.0, 0.0, 1.0);
glutMainLoop();
}
>softyaさん
ありがとうございます。
いい忘れていました。屈折の公式は把握できています。
しかしプリズムを含んだ屈折、反射に関する処理の一般化で苦戦しております。。
不明な点は
・光の現在の座標の更新方法は、いまのままでよいのか。
・光の進む角度の更新は、どのように行えばいいのか。何を基準(0度)にするとわかりやすいのか。
・軌跡の描きかた。(画面クリアをせず、描画された点を残しておく方法はありますか。)
不明な点ばかりですみません。厚かましいようですがお力を貸してください。