「3D:線分と無限平面」の編集履歴(バックアップ)一覧はこちら
「3D:線分と無限平面」(2015/03/04 (水) 23:23:07) の最新版変更点
追加された行は緑色になります。
削除された行は赤色になります。
<p><strong>線分と無限平面の当たり判定です。<br />
無限平面を表現するのは困難なので、今回は代わりに三角ポリゴンを表示しています。</strong></p>
<p><img alt="" src="http://www21.atwiki.jp/opengl?cmd=upload&act=open&pageid=322&file=hit.png" /></p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p><strong>線分と無限平面の当たり判定です。<br />
無限平面を表現するのは困難なので、今回は代わりに三角ポリゴンを表示しています。</strong></p>
<p><img alt="" src="http://cdn21.atwikiimg.com/opengl?cmd=upload&act=open&pageid=322&file=hit.png" /></p>
<table border="1" cellpadding="1" cellspacing="1" style="width:100px;"><tbody><tr><td>ファイル</td>
</tr><tr><td><a href="http://www21.atwiki.jp/opengl?cmd=upload&act=open&pageid=322&file=main.cpp">
main.cpp</a></td>
</tr><tr><td><a href="http://www21.atwiki.jp/opengl?cmd=upload&act=open&pageid=322&file=font.h">
font.h</a></td>
</tr></tbody></table><p>main.cpp</p>
<table border="1" cellpadding="1" cellspacing="1" style="width:600px;"><tbody><tr><td>
<p>#pragma comment(linker, "/SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup")<br />
#include <GL/freeglut/freeglut.h><br />
#include <math.h><br />
#include <stdio.h><br />
#include "font.h"</p>
<p>#define PAI 3.14159</p>
<p>#define WIDTH 320<br />
#define HEIGHT 240</p>
<p>//3つのベクトル<br />
struct Vector3f{<br />
float x;<br />
float y;<br />
float z;<br />
Vector3f(){};<br />
Vector3f(float _x,float _y,float _z){<br />
x=_x;y=_y;z=_z;<br />
};<br />
//ベクトル引き算( this - v )<br />
Vector3f operator - ( const Vector3f& v ) const { return Vector3f( x -
v.x, y - v.y, z - v.z ); }<br />
<br />
//ベクトル外積( this × vr )<br />
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) ); }<br />
<br />
//自身を単位ベクトルにする<br />
void Normalize() {<br />
double length = pow( (double)( x * x ) + ( y * y ) + ( z * z ), 0.5
);//ベクトルの長さ<br />
x /= length;<br />
y /= length;<br />
z /= length;<br />
}<br />
}vec3d;<br />
Vector3f & operator*(Vector3f &v,float size){<br />
v.x *= size;<br />
v.y *= size;<br />
v.z *= size;<br />
return v;<br />
}<br />
Vector3f & operator+(Vector3f &a,Vector3f &b){<br />
a.x+=b.x;<br />
a.y+=b.y;<br />
a.z+=b.z;<br />
return a;<br />
}</p>
<p>//頂点ABCで作られたポリゴンから法線を計算する。<br />
Vector3f CreatePolygonNormal( Vector3f A, Vector3f B, Vector3f C ) {</p>
<p> Vector3f AB( B - A );<br />
Vector3f BC( C - B );</p>
<p> Vector3f normal = AB * BC; //AB BCの外積<br />
normal.Normalize();//単位ベクトルにする</p>
<p> return normal;<br />
}</p>
<p>//内積<br />
void dot(Vector3f& src1,Vector3f& src2,float& dst){<br />
dst= src1.x*src2.x+src1.y*src2.y+src1.z*src2.z;<br />
}</p>
<p>void Line3D(float x1,float y1,float z1,float x2,float y2,float z2){<br />
//線幅<br />
glLineWidth(1.0);<br />
//線<br />
glBegin(GL_LINES);<br />
glVertex3f(x1,y1,z1);<br />
glVertex3f(x2,y2,z2);<br />
glEnd();<br />
}</p>
<p>void LineSegment(Vector3f a,Vector3f b){<br />
Line3D(a.x,a.y,a.z,b.x,b.y,b.z);<br />
glPointSize(5.0f);<br />
glBegin(GL_POINTS);<br />
glVertex3f(a.x , a.y , a.z);<br />
glVertex3f(b.x , b.y , b.z);<br />
glEnd();<br />
}</p>
<p>void TriangleDraw(Vector3f a,Vector3f b,Vector3f c){<br />
glBegin(GL_POLYGON);<br />
glVertex3f(a.x , a.y , a.z);<br />
glVertex3f(b.x , b.y , b.z);<br />
glVertex3f(c.x , c.y , c.z);<br />
glEnd();<br />
}<br />
void DrawMeasure(int measure,float size){<br />
glDisable(GL_LIGHTING);<br />
glColor4f(0.5f, 0.5f, 0.5f, 0.5f);<br />
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));}<br />
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));}<br />
glDisable(GL_DEPTH_TEST);<br />
glColor4f(1.0f, 0.0f, 0.0f, 1.0f);<br />
Line3D(0,0,0,(measure/2+2)*size,0,0);<br />
glColor4f(0.0f, 1.0f, 0.0f, 1.0f);<br />
Line3D(0,0,0,0,(measure/2+2)*size,0);<br />
glColor4f(0.0f, 0.0f, 1.0f, 1.0f);<br />
Line3D(0,0,0,0,0,(measure/2+2)*size);<br />
glEnable(GL_LIGHTING);<br />
glEnable(GL_DEPTH_TEST);<br />
}</p>
<p>//黄色<br />
GLfloat yerrow[] = { 1.0f, 1.0f, 0.0f, 1.0f };<br />
//紫<br />
GLfloat purple[] = { 0.5f, 0.0f, 1.0f, 1.0f };<br />
//ライトの位置<br />
GLfloat lightpos[] = { 0.0, 0.0, 200.0, 1.0 };</p>
<p>GLFONT *font;</p>
<p>Vector3f point_A(100 , 50 , 50),point_B(100 ,-50 , 50);<br />
Vector3f Triangle_A(150,10,75),Triangle_B(0,10,75),Triangle_C(150,10,-75);</p>
<p>Vector3f normal(0,0,0);<br />
float vector_a,vector_b;</p>
<p>bool flag=false;<br />
void display( void ) {<br />
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);<br />
glViewport(0, 0, WIDTH, HEIGHT);<br />
glMatrixMode(GL_PROJECTION);<br />
glLoadIdentity();<br />
//視野角,アスペクト比(ウィンドウの幅/高さ),描画する範囲(最も近い距離,最も遠い距離)<br />
gluPerspective(30.0, (double)WIDTH / (double)HEIGHT, 1.0, 5000.0);<br />
glMatrixMode(GL_MODELVIEW);<br />
glLoadIdentity();<br />
//視点の設定<br />
gluLookAt(400.0,400.0,400.0,<br />
0.0,0.0,0.0,<br />
0.0,1.0,0.0);</p>
<p> //ライトの設定<br />
glLightfv(GL_LIGHT0, GL_POSITION, lightpos);<br />
glColor3f(1,1,1);<br />
DrawMeasure(8,40);<br />
//線分<br />
glMaterialfv(GL_FRONT, GL_DIFFUSE, yerrow);<br />
LineSegment(point_A,point_B);<br />
//三角形(平面)<br />
glMaterialfv(GL_FRONT, GL_DIFFUSE, purple);<br />
TriangleDraw(Triangle_A,Triangle_B,Triangle_C);</p>
<p> normal=CreatePolygonNormal(Triangle_A,Triangle_B,Triangle_C);<br />
dot(point_A,normal,vector_a);<br />
dot(point_B,normal,vector_b);<br />
if((vector_a * vector_b)<=0){<br />
glColor4f(1.0f, 0.0f, 0.0f, 1.0f);<br />
font->DrawStringW(-320,0,L"Hit!!");<br />
}else{<br />
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);<br />
font->DrawStringW(-320,0,L"NO Hit!!");<br />
}</p>
<p> glutSwapBuffers();</p>
<p>}<br />
void idle(void)<br />
{<br />
if(flag){<br />
point_A.y-=2.0f;<br />
point_B.y-=2.0f;<br />
}else{<br />
point_A.y+=2.0f;<br />
point_B.y+=2.0f;<br />
}<br />
if(point_A.y>200.0f){flag=true;}<br />
if(point_A.y<-100.0f){flag=false;}<br />
Sleep(1);<br />
glutPostRedisplay();<br />
}</p>
<p>void Init(){<br />
glClearColor(0.3f, 0.3f, 0.3f, 1.0f);<br />
glEnable(GL_DEPTH_TEST);<br />
glEnable(GL_LIGHTING);<br />
glEnable(GL_LIGHT0);</p>
<p> font = new GLFONT(L"MS明朝", 24);</p>
<p>}</p>
<p><br />
int main(int argc, char *argv[])<br />
{<br />
glutInitWindowPosition(100, 100);<br />
glutInitWindowSize(WIDTH, HEIGHT);<br />
glutInit(&argc, argv);<br />
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);<br />
glutCreateWindow("線分と無限平面の衝突判定");<br />
glutDisplayFunc(display);<br />
glutIdleFunc(idle);<br />
Init();<br />
glutMainLoop();<br />
return 0;<br />
}</p>
</td>
</tr></tbody></table><p> </p>
<p> </p>
<p> </p>