void gliSolidPipe(GLdouble length, GLdouble radius, GLint slices) /* length; 棒の長さ radius; 棒の半径 slices; 多角形近似の角数 */ { double dth, px0, px1, py0, py1; int i; glBoolean normal; normal = glIsEnabled(GL_NORMALIZE); glEnable(GL_NORMALIZE); dth = 2 * M_PI / slices; glBegin(GL_QUADS); px0 = radius; py0 = 0.0; for(i = 1;i <= slices;i++) { px1 = radius * cos(dth * i); py1 = radius * sin(dth * i); glVertex3d(px0, py0, length); glVertex3d(px0, py0, 0.0); glVertex3d(px1, py1, 0.0); glVertex3d(px1, py1, length); glNormal3d(px0 + px1, py0 + py1, 0.0); px0 = px1; py0 = py1; } glEnd(); if(!normal) glDisable(GL_NORMALIZE); }
[目次に戻る]
2. 矢印を描く
矢印を描くプログラムです。
原点からz軸の正の方向に全体の長さがlength、尾の半径がtradius、
頭の半径がhradius、頭の長さがhlengthの矢印を描きます
尾の長さはlength-hlengthになります)。
頭はslices角錐と近似され、尾はslices角柱と近似されます。
void gliSolidArrow(GLdouble length, GLdouble tradius, GLdouble hradius, GLdouble hlength, GLdouble slices) /* length; 矢全体の長さ tradius; 尾の半径 hradius; 頭の半径 hlength; 頭の長さ slices; 多角形近似の角数 */ { double dth, cs0, cs1, sn0, sn1; double tx0, tx1, ty0, ty1; double hx0, hx1, hy0, hy1; int i; GLboolean normal; normal = glIsEnabled(GL_NORMALIZE); glEnable(GL_NORMALIZE); dth = 2 * M_PI / slices; cs0 = 1.0; sn0 = 0.0; for(i = 1;i <= slices;i++) { cs1 = cos(dth * i); sn1 = sin(dth * i); tx0 = tradius * cs0; ty0 = tradius * sn0; tx1 = tradius * cs1; ty1 = tradius * sn1; hx0 = hradius * cs0; hy0 = hradius * sn0; hx1 = hradius * cs1; hy1 = hradius * sn1; glBegin(GL_QUADS); glNormal3d(cs0 + cs1, sn0 + sn1, 0.0); glVertex3d(tx0, ty0, length - hlength); glVertex3d(tx0, ty0, 0.0); glVertex3d(tx1, ty1, 0.0); glVertex3d(tx1, ty1, length - hlength); glEnd(); glBegin(GL_TRIANGLES); glVertex3d(hx0, hy0, length - hlength); glVertex3d(hx1, hy1, length - hlength); glVertex3d(0.0, 0.0, length); glNormal3d(hlength * (hy1 - hy0) , hlength * (hx0 - hx1) , hx0 * hy1 - hx1 * hy0); glEnd(); glBegin(GL_TRIANGLES); glNormal3d(0.0, 0.0, -1.0); glVertex3d(tx0, ty0, 0.0); glVertex3d(tx1, ty1, 0.0); glVertex3d(0.0, 0.0, 0.0); glEnd(); glBegin(GL_QUADS); glNormal3d(0.0, 0.0, -1.0); glVertex3d(tx0, ty0, length - hlength); glVertex3d(hx0, hy0, length - hlength); glVertex3d(hx1, hy1, length - hlength); glVertex3d(tx1, ty1, length - hlength); glEnd(); cs0 = cs1; sn0 = sn1; } if(!normal) glDisable(GL_NORMALIZE); }[目次に戻る]
3. 棒を描く(2)
gliSolidPipe()の拡張版で、2点間を結ぶ棒を描きます。void gliSolidPipe2(GLdouble length, GLdouble radius, GLint slices, GLdouble x0, GLdouble y0, GLdouble z0, GLdouble x1, GLdouble y1, GLdouble z1) /* length; 棒の長さ radius; 棒の半径 slices; 多角形近似の角数 x0, y0, z0; 棒の始点 x1, y1, z1; 棒の終点 */ { GLdouble m[16]; GLdouble xx, yy, zz, a, b; xx=x1-x0; yy=y1-y0; zz=z1-z0; a=sqrt(xx*xx+yy*yy+zz*zz); if(z1>z0) b=sqrt(xx*xx+zz*zz); else b=-sqrt(xx*xx+zz*zz); m[0]=zz*a/b; m[1]=0.0; m[2]=-xx*a/b; m[3]=0.0; m[4]=-xx*yy/b; m[5]=b; m[6]=-yy*zz/b; m[7]=0.0; m[8]=xx; m[9]=yy; m[10]=zz; m[11]=0.0; m[12]=x0; m[13]=y0; m[14]=z0; m[15]=1.0; glPushMatrix(); glLoadMatrixd(m); gliSolidPipe(length, radius, slices); glPopMatrix(); }[目次に戻る]
岩瀬康行(iwase@sci.hiroshima-u.ac.jp)