#pragma comment(linker, "/SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup")
#include <GL/freeglut/freeglut.h>
#include <math.h>
#include <stdio.h>
#include "font.h"
#define PAI 3.14159
#define WIDTH 320
#define HEIGHT 240
//3つのベクトル
struct Vector3f{
float x;
float y;
float z;
Vector3f(){};
Vector3f(float _x,float _y,float _z){
x=_x;y=_y;z=_z;
};
//ベクトル引き算( this - v )
Vector3f operator - ( const Vector3f& v ) const { return Vector3f( x -
v.x, y - v.y, z - v.z ); }
//ベクトル外積( this × vr )
Vector3f operator * ( const Vector3f& vr ) const { return Vector3f( (y
* vr.z) - (z * vr.y), (z * vr.x) - (x * vr.z), (x * vr.y) - (y * vr.x) ); }
//自身を単位ベクトルにする
void Normalize() {
double length = pow( (double)( x * x ) + ( y * y ) + ( z * z ), 0.5
);//ベクトルの長さ
x /= length;
y /= length;
z /= length;
}
}vec3d;
Vector3f & operator*(Vector3f &v,float size){
v.x *= size;
v.y *= size;
v.z *= size;
return v;
}
Vector3f & operator+(Vector3f &a,Vector3f &b){
a.x+=b.x;
a.y+=b.y;
a.z+=b.z;
return a;
}
//頂点ABCで作られたポリゴンから法線を計算する。
Vector3f CreatePolygonNormal( Vector3f A, Vector3f B, Vector3f C ) {
Vector3f AB( B - A );
Vector3f BC( C - B );
Vector3f normal = AB * BC; //AB BCの外積
normal.Normalize();//単位ベクトルにする
return normal;
}
//内積
void dot(Vector3f& src1,Vector3f& src2,float& dst){
dst= src1.x*src2.x+src1.y*src2.y+src1.z*src2.z;
}
void Line3D(float x1,float y1,float z1,float x2,float y2,float z2){
//線幅
glLineWidth(1.0);
//線
glBegin(GL_LINES);
glVertex3f(x1,y1,z1);
glVertex3f(x2,y2,z2);
glEnd();
}
void LineSegment(Vector3f a,Vector3f b){
Line3D(a.x,a.y,a.z,b.x,b.y,b.z);
glPointSize(5.0f);
glBegin(GL_POINTS);
glVertex3f(a.x , a.y , a.z);
glVertex3f(b.x , b.y , b.z);
glEnd();
}
void TriangleDraw(Vector3f a,Vector3f b,Vector3f c){
glBegin(GL_POLYGON);
glVertex3f(a.x , a.y , a.z);
glVertex3f(b.x , b.y , b.z);
glVertex3f(c.x , c.y , c.z);
glEnd();
}
void DrawMeasure(int measure,float size){
glDisable(GL_LIGHTING);
glColor4f(0.5f, 0.5f, 0.5f, 0.5f);
for(int
x=0;x<=measure;x++){Line3D(x*size-(size*measure/2),0,-(size*measure/2),x*size-(size*measure/2),0,measure*size-(size*measure/2));}
for(int
y=0;y<=measure;y++){Line3D(-(size*measure/2),0,y*size-(size*measure/2),measure*size-(size*measure/2),0,y*size-(size*measure/2));}
glDisable(GL_DEPTH_TEST);
glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
Line3D(0,0,0,(measure/2+2)*size,0,0);
glColor4f(0.0f, 1.0f, 0.0f, 1.0f);
Line3D(0,0,0,0,(measure/2+2)*size,0);
glColor4f(0.0f, 0.0f, 1.0f, 1.0f);
Line3D(0,0,0,0,0,(measure/2+2)*size);
glEnable(GL_LIGHTING);
glEnable(GL_DEPTH_TEST);
}
//黄色
GLfloat yerrow[] = { 1.0f, 1.0f, 0.0f, 1.0f };
//紫
GLfloat purple[] = { 0.5f, 0.0f, 1.0f, 1.0f };
//ライトの位置
GLfloat lightpos[] = { 0.0, 0.0, 200.0, 1.0 };
GLFONT *font;
Vector3f point_A(100 , 50 , 50),point_B(100 ,-50 , 50);
Vector3f Triangle_A(150,10,75),Triangle_B(0,10,75),Triangle_C(150,10,-75);
Vector3f normal(0,0,0);
float vector_a,vector_b;
bool flag=false;
void display( void ) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glViewport(0, 0, WIDTH, HEIGHT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//視野角,アスペクト比(ウィンドウの幅/高さ),描画する範囲(最も近い距離,最も遠い距離)
gluPerspective(30.0, (double)WIDTH / (double)HEIGHT, 1.0, 5000.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
//視点の設定
gluLookAt(400.0,400.0,400.0,
0.0,0.0,0.0,
0.0,1.0,0.0);
//ライトの設定
glLightfv(GL_LIGHT0, GL_POSITION, lightpos);
glColor3f(1,1,1);
DrawMeasure(8,40);
//線分
glMaterialfv(GL_FRONT, GL_DIFFUSE, yerrow);
LineSegment(point_A,point_B);
//三角形(平面)
glMaterialfv(GL_FRONT, GL_DIFFUSE, purple);
TriangleDraw(Triangle_A,Triangle_B,Triangle_C);
normal=CreatePolygonNormal(Triangle_A,Triangle_B,Triangle_C);
dot(point_A,normal,vector_a);
dot(point_B,normal,vector_b);
if((vector_a * vector_b)<=0){
glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
font->DrawStringW(-320,0,L"Hit!!");
}else{
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
font->DrawStringW(-320,0,L"NO Hit!!");
}
glutSwapBuffers();
}
void idle(void)
{
if(flag){
point_A.y-=2.0f;
point_B.y-=2.0f;
}else{
point_A.y+=2.0f;
point_B.y+=2.0f;
}
if(point_A.y>200.0f){flag=true;}
if(point_A.y<-100.0f){flag=false;}
Sleep(1);
glutPostRedisplay();
}
void Init(){
glClearColor(0.3f, 0.3f, 0.3f, 1.0f);
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
font = new GLFONT(L"MS明朝", 24);
}
int main(int argc, char *argv[])
{
glutInitWindowPosition(100, 100);
glutInitWindowSize(WIDTH, HEIGHT);
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
glutCreateWindow("線分と無限平面の衝突判定");
glutDisplayFunc(display);
glutIdleFunc(idle);
Init();
glutMainLoop();
return 0;
}
|