これは三角形に法線ベクトルをせっていするプログラムですが
この三角刑をたくさん描画する、STLのポリゴンを表示するときに
法線ベクトルが重なることがあります
その法線ベクトルを平均化するにはどうしたらいいのでしょうか?
C++
1#include <iostream> 2#include <vector> 3#include <numeric> 4#include <algorithm> 5#include <functional> 6#include <cmath> 7#include <GL/glut.h> 8 9 10//--------- 各種データ構造 -----------// 11float a[3]={0,0,3.5}; 12float b[3]={3.5,0,0}; 13float c[3]={0,3.5,0}; 14float v1[3];// b - a を格納 15float v2[3];// c - a を格納 16 17std::vector<float> FaceNormal(3);//外せき格納用+後で正規化して法線にする 18 19 20//--------- プロトタイプ宣言 -----------// 21void display(); 22void reshape(int w, int h); 23void timer(int value); 24 25void DRAW_XYZ(); 26void DrawPolygon(); 27void CalcNormal(); 28 29 30//------------- OpenGLの初期化 -------------// 31void GLUT_CALL_FUNCs() 32{ 33 glutDisplayFunc(display); 34 glutReshapeFunc(reshape); 35 glutTimerFunc(0,timer,17); 36} 37 38 39void OtherMyInit() 40{ 41 glClearColor(1.0, 1.0, 1.0, 1.0); 42 glEnable(GL_DEPTH_TEST); 43 glEnable(GL_LIGHTING);//光源の有効化 44 glEnable(GL_LIGHT0); 45 46 glColorMaterial(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE);//glColorにより材質設定 47 glEnable(GL_COLOR_MATERIAL); 48 49 glEnable(GL_NORMALIZE); 50} 51 52void GLUT_INITs(int *argcp, char **argv) 53{ 54 glutInit(argcp,argv); 55 glutInitDisplayMode(GLUT_RGBA| GLUT_DOUBLE | GLUT_DEPTH); 56 glutInitWindowSize(640,480); 57 glutCreateWindow("Basic Normal"); 58 GLUT_CALL_FUNCs(); 59 OtherMyInit(); 60 61} 62 63 64 65//------------- メイン関数 ----------------// 66int main(int argc , char **argv) 67{ 68 GLUT_INITs(&argc,argv); 69 70 CalcNormal(); //法線を計算 71 glutMainLoop(); 72 73 return 0; 74} 75 76 77//------------- ここから各種コールバック -----------------// 78void display() 79{ 80 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 81 glLoadIdentity(); 82 83 gluLookAt(-5.0, 20.0, 20.0, 0,0,0, 0.0, 1.0, 0.0); 84 85 86 static float Light0Pos[]={-5.0, 5.0, 5.0,0}; //光源の位置 87 static int r=0; 88 glPushMatrix(); 89 glRotatef(static_cast<float>(r),0,1,0); 90 glLightfv(GL_LIGHT0, GL_POSITION, Light0Pos);//位置だけ設定(あとはデフォルト) 91 glPopMatrix(); 92 93 DRAW_XYZ(); 94 95 96 glColor3f(0,1,1); 97 glutSolidSphere(1,60,60); 98 DrawPolygon(); 99 100 glutSwapBuffers(); 101 if(++r > 360) r = 0; 102 103} 104 105void reshape(int w, int h) 106{ 107 glViewport(0, 0, w, h); 108 glMatrixMode(GL_PROJECTION); 109 glLoadIdentity(); 110 gluPerspective(30.0, (double)w / (double)h, 1.0, 100.0); 111 glMatrixMode(GL_MODELVIEW); 112} 113 114 115 116void timer(int t) 117{ 118 glutPostRedisplay(); 119 glutTimerFunc(t,timer,17); //タイマー関数 120} 121 122 123//-------------- ここから各種関数 ------------------// 124void DRAW_XYZ() 125{ 126 glDisable(GL_LIGHTING);//光源の無効化 127 glDisable(GL_LIGHT0); 128 129 glBegin(GL_LINES); 130 glColor3f(0,1,0);//x 131 glVertex2f(-100,0); 132 glVertex2f(100, 0); 133 134 glColor3f(1,0,0);//y 135 glVertex2f(0,0); 136 glVertex2f(0,100); 137 138 glColor3f(0,0,1);//z 139 glVertex3f(0,0,-100); 140 glVertex3f(0,0, 100); 141 glEnd(); 142 143 glEnable(GL_LIGHTING);//光源の有効化 144 glEnable(GL_LIGHT0); 145 146} 147 148void DrawPolygon() 149{ 150 151 glNormal3fv(&FaceNormal[0]); 152 glBegin(GL_TRIANGLES); 153 glVertex3fv(a); 154 glVertex3fv(b); 155 glVertex3fv(c); 156 glEnd(); 157 158 159} 160 161//法線を計算する 162void CalcNormal() 163{ 164 //ベクトルを計算 165 std::transform(b,b+3,a,v1,std::minus<float>());//v1 = b - a 166 std::transform(c,c+3,a,v2,std::minus<float>());//v2 = c - a 167 168 //外せきを計算(v1 x v2) 169 for(int loop = 0;loop < 3; ++loop) 170 { 171 FaceNormal[loop]=v1[(loop+1)%3] * v2[(loop+2)%3] - v1[(loop+2)%3]*v2[(loop+1)%3]; 172 } 173 174 //正規化用に大きさ|v1 x v2| を計算 175 float length = sqrtf( std::inner_product(FaceNormal.begin(),FaceNormal.end(),FaceNormal.begin(),0.f)); 176 if(length == 0.f) //長さが0の場合は計算できない 177 { 178 std::cerr << "Can't Calc normal\n"; 179 return ; 180 } 181 182 183 //各要素をlengthで割って正規化 184 std::transform(FaceNormal.begin(),FaceNormal.end(),FaceNormal.begin(),std::bind2nd(std::divides<float>(),length)); 185 186 std::cout << "Normal is : "; 187 for(int loop = 0;loop < 3; ++loop) 188 { 189 std::cout << FaceNormal[loop]<<", "; 190 } 191 std::cout <<'\n'; 192}
法線ベクトルが重なる、といっているのはどういう状態を指しますか?また、平均化とはなにとなにの平均ですか?

回答1件
あなたの回答
tips
プレビュー