3D:線分と無限平面

「3D:線分と無限平面」の編集履歴(バックアップ)一覧はこちら

3D:線分と無限平面」(2015/03/04 (水) 23:23:07) の最新版変更点

追加された行は緑色になります。

削除された行は赤色になります。

<p><strong>線分と無限平面の当たり判定です。<br /> 無限平面を表現するのは困難なので、今回は代わりに三角ポリゴンを表示しています。</strong></p> <p><img alt="" src="http://www21.atwiki.jp/opengl?cmd=upload&amp;act=open&amp;pageid=322&amp;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&amp;act=open&amp;pageid=322&amp;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&amp;act=open&amp;pageid=322&amp;file=main.cpp"> main.cpp</a></td> </tr><tr><td><a href="http://www21.atwiki.jp/opengl?cmd=upload&amp;act=open&amp;pageid=322&amp;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 &lt;GL/freeglut/freeglut.h&gt;<br /> #include &lt;math.h&gt;<br /> #include &lt;stdio.h&gt;<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&amp; v ) const { return Vector3f( x - v.x, y - v.y, z - v.z ); }<br />     <br />     //ベクトル外積( this × vr )<br />     Vector3f operator * ( const Vector3f&amp; 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 &amp; operator*(Vector3f &amp;v,float size){<br />  v.x *= size;<br />  v.y *= size;<br />  v.z *= size;<br />  return v;<br /> }<br /> Vector3f &amp; operator+(Vector3f &amp;a,Vector3f &amp;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&amp; src1,Vector3f&amp; src2,float&amp; 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&lt;=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&lt;=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)&lt;=0){<br />      glColor4f(1.0f, 0.0f, 0.0f, 1.0f);<br />      font-&gt;DrawStringW(-320,0,L"Hit!!");<br />  }else{<br />      glColor4f(1.0f, 1.0f, 1.0f, 1.0f);<br />      font-&gt;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&gt;200.0f){flag=true;}<br />  if(point_A.y&lt;-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(&amp;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>

表示オプション

横に並べて表示:
変化行の前後のみ表示: