Я пытаюсь нарисовать римскую поверхность Штейнера в OpenGL, и у меня возникают проблемы с получением правильных нормалей, чтобы поверхность правильно освещалась. Я использовал параметрическое уравнение из Википедии: http://en.wikipedia.org/wiki/Roman_surface. Для нормалей я сделал частичное дифференцирование по тэте, затем по фи, затем пересекли частные дифференциалы, чтобы получить нормаль.
Это не позволяет поверхности правильно освещаться, потому что римская поверхность - неориентируемая поверхность. Поэтому мне было интересно, есть ли способ вывести правильные нормали, чтобы поверхность могла правильно освещаться. Я пытался отрицать нормали для всей поверхности и части поверхности (отрицая для 1-й и последней четверти n), но, похоже, это не сработало.
Мой текущий код выглядит следующим образом:
double getRad(double deg, double n){
return deg * M_PI / n;
}
int n = 24;
for(int i = 0; i < n; i++){
for(int j = 0; j < 2*n; j++){
glBegin(GL_POLYGON);
double x = -pow(r,4) * cos(2*getRad(i+0.5,n)) * pow(cos(getRad(j+0.5,n)),2) * cos(2*getRad(j+0.5,n)) * sin(getRad(i+0.5,n)) - 2 * pow(r,4) * pow(cos(getRad(i+0.5,n)),2) * pow(cos(getRad(j+0.5,n)),2) * sin(getRad(i+0.5,n)) * pow(sin(getRad(j+0.5,n)),2);
double y = pow(r,4) * cos(getRad(i+0.5,n)) * cos(2*getRad(i+0.5,n)) * pow(cos(getRad(j+0.5,n)),2) * cos(2*getRad(j+0.5,n)) - 2 * pow(r,4) * cos(getRad(i+0.5,n)) * pow(cos(getRad(j+0.5,n)),2) * pow(sin(getRad(i+0.5,n)),2) * pow(sin(getRad(j+0.5,n)),2);
double z = -pow(r,4) * pow(cos(getRad(i+0.5,n)),2) * cos(getRad(j+0.5,n)) * cos(2*getRad(j+0.5,n)) * sin(getRad(j+0.5,n)) - pow(r,4) * cos(getRad(j+0.5,n)) * cos(2*getRad(j+0.5,n)) * pow(sin(getRad(i+0.5,n)),2) * sin(getRad(j+0.5,n));
glNormal3d(x, y, z);
glVertex3d(r*r*cos(getRad(i,n))*cos(getRad(j,n))*sin(getRad(j,n)),r*r*sin(getRad(i,n))*cos(getRad(j,n))*sin(getRad(j,n)),r*r*cos(getRad(i,n))*sin(getRad(i,n))*cos(getRad(j,n))*cos(getRad(j,n)));
glVertex3d(r*r*cos(getRad(i+1,n))*cos(getRad(j,n))*sin(getRad(j,n)),r*r*sin(getRad(i+1,n))*cos(getRad(j,n))*sin(getRad(j,n)),r*r*cos(getRad(i+1,n))*sin(getRad(i+1,n))*cos(getRad(j,n))*cos(getRad(j,n)));
glVertex3d(r*r*cos(getRad(i+1,n))*cos(getRad(j+1,n))*sin(getRad(j+1,n)),r*r*sin(getRad(i+1,n))*cos(getRad(j+1,n))*sin(getRad(j+1,n)),r*r*cos(getRad(i+1,n))*sin(getRad(i+1,n))*cos(getRad(j+1,n))*cos(getRad(j+1,n)));
glVertex3d(r*r*cos(getRad(i,n))*cos(getRad(j+1,n))*sin(getRad(j+1,n)),r*r*sin(getRad(i,n))*cos(getRad(j+1,n))*sin(getRad(j+1,n)),r*r*cos(getRad(i,n))*sin(getRad(i,n))*cos(getRad(j+1,n))*cos(getRad(j+1,n)));
glEnd();
glFlush();
}
}