Click to See Complete Forum and Search --> : Brauche Hilfe für Winkelberechnung


Manuel
May 23rd, 1999, 09:13 AM
Bei einem Projekt habe ich das Problem, dass ich bei der 3d Darstellung von Molekülen nicht die Moleküle sondern die Ansicht verändere, also bleibt der Winkel immer gleich!
Bei mir wird der Winkel aber immer wieder neu berechnet!!!
Bitte helft mir damit mein Arbeitgeber sitzt mir schon im Nacken !!!
Ich füge Euch hier den Ausschnitt der cpp Datei unten ein, und danach ddie Complette cpp File !!

Der Ausschnitt:
// berechnen des Winkels fuer gluPerspective
G = Mol->GreatestDist*1.3;
ViewD=2*G;
M = Mol->GetMolCenter();
D= sqrt((0-M[0])*(0-M[0])+(0-M[1])*(0-M[1])+(ViewD-M[2])*(ViewD-M[2]));
theta=atan(G/(2*D));
angle = (180 * 2 * theta / 3.14159);

GLdouble aspect = double(width)/double(height);
glViewport(0,0,width, height);
if(I<((G+D)*2)) I = (G+D)*2;
gluPerspective(angle,aspect,0.5,I);


Die Complette cpp File :

#include "flgui.h"
#define RenderQuality 12

GL_Window::GL_Window(int x,int y,int w,int h,const char *l)
: Fl_Gl_Window(x,y,w,h,l){
Mol=NULL;
prevx=curx=prevy=cury=startx=starty=0; //for mouse handling
zoomfactor=0.0f;
InitHasToBeDone=true;
LightChanged=true;
ViewPortChanged=true;
SetBackground();
rotate=true;

}
void GL_Window::SetBackground(float r, float g, float b){
red=r; green=g; blue=b;

}
void GL_Window::draw(void){

glClearColor(red,green,blue,0.0f);
glClear( GLbitfield(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));
if (!valid()) {
valid(1);
LightChanged=true;
ViewPortChanged=true;
}
if (Mol != NULL){
if(InitHasToBeDone){
// GLUquadricObj *quadObj;
quadObj = gluNewQuadric();
gluQuadricDrawStyle (quadObj, GLenum(GLU_FILL));
gluQuadricOrientation(quadObj, GLenum(GLU_OUTSIDE));
gluQuadricNormals (quadObj, GLenum(GLU_SMOOTH));

glNewList(SPHERE, GL_COMPILE );
gluSphere(quadObj, 1.0, 2*RenderQuality,RenderQuality);
glEndList();

glNewList(CYLINDER, GL_COMPILE );
gluCylinder(quadObj,0.5,0.5,1.0,RenderQuality+2,RenderQuality+2);
glEndList();

glNewList(CONE, GL_COMPILE );
gluCylinder(quadObj,0.5,0.0,1.0,RenderQuality+2,RenderQuality+2);
glEndList();

glNewList(DISK, GL_COMPILE );
gluDisk(quadObj,0,0.5,RenderQuality+2,RenderQuality+2);
glEndList();

// gluDeleteQuadric(quadObj);
//
InitHasToBeDone=false;
}
if(LightChanged){
SetLight();
LightChanged=false;
}
if(ViewPortChanged){
OpenGL_Draw.WindowWidth=w();
OpenGL_Draw.WindowHeight=h();
OpenGL_Draw.SetViewPort(w(),h());
ViewPortChanged=false;
}
glPushMatrix();
//glCullFace(GL_BACK);
//glEnable(GL_CULL_FACE);
OpenGL_Draw.Plot();
glPopMatrix();

}
}

void GL_Window::SetCurrentMol(T_Molecule *mol){
Mol=mol;
OpenGL_Draw.SetCurrentMol(Mol);
ViewPortChanged=true;
redraw();
}
void GL_Window::SetLight(void)
{
GLfloat m_fvAmbient[2][3];
GLfloat m_fvDiffuse[2][3];
GLfloat m_fvSpecular[2][3];
GLfloat glfPosition[2][4] =
{{-4.0f, 4.0f, 4.0f, 0.0f},
{ 4.0f,-4.0f, 0.0f, 0.0f}};

int i,j;
GLfloat fvLight[2*3][3] =
{{0.2f, 0.2f, 0.2f}, {0.0f, 0.0f, 0.0f}, // ambient
{0.8f, 0.8f, 0.8f}, {0.3f, 0.3f, 0.3f}, // diffus
{0.1f, 0.1f, 0.1f}, {0.0f, 0.0f, 0.0f}}; // specular
// {{0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f}, // ambient
// {0.0f, 0.0f, 0.0f}, {0.8f, 0.8f, 0.8f}, // diffus
// {0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f}}; // specular
// {{0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f}, // ambient
// {1.0f, 1.0f, 1.0f}, {0.0f, 0.0f, 0.0f}, // diffus
// {0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f}}; // specular
// {{1.0f, 1.0f, 1.0f}, {0.0f, 0.0f, 0.0f}, // ambient
// {0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f}, // diffus
// {0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f}}; // specular

for (i=0; i<2; i++) {
for(j=0; j<3; j++) {
m_fvAmbient[i][j] = fvLight[i][j];
m_fvDiffuse[i][j] = fvLight[i+2][j];
m_fvSpecular[i][j] = fvLight[i+4][j];
}
}

glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
for ( i=0; i<2; i++) {
GLenum ilight = GLenum(GL_LIGHT0+i);
glLightfv(ilight, GL_AMBIENT, m_fvAmbient[i]);
glLightfv(ilight, GL_DIFFUSE, m_fvDiffuse[i]);
glLightfv(ilight, GL_SPECULAR, m_fvSpecular[i]);
glLightfv(ilight, GL_POSITION, glfPosition[i]);
glEnable(ilight);
}
glPopMatrix();
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glShadeModel(GL_SMOOTH);
glEnable(GL_COLOR_MATERIAL);
//glColorMaterial( GL_FRONT,GL_EMISSION);
///GL_EMISSION, GL_AMBIENT, GL_DIFFUSE, GL_SPECULAR, and GL_AMBIENT_AND_DIFFUSE
glEnable(GL_NORMALIZE);


}


void GL_Window::SetPickingViewPort(int width, int height)
//calculate viewport according to window width and height
{
double D = 1;
double G = 10, ViewD=2*G;
double I = 100;
double angle =10;
double theta;
float *M;
// berechnen des Winkels fuer gluPerspective
G = Mol->GreatestDist*1.3;
ViewD=2*G;
M = Mol->GetMolCenter();
D= sqrt((0-M[0])*(0-M[0])+(0-M[1])*(0-M[1])+(ViewD-M[2])*(ViewD-M[2]));
theta=atan(G/(2*D));
angle = (180 * 2 * theta / 3.14159);

GLdouble aspect = double(width)/double(height);
glViewport(0,0,width, height);
if(I<((G+D)*2)) I = (G+D)*2;
gluPerspective(angle,aspect,0.5,I);
}
int GL_Window::handle(int event) {
int button= -1; //button may be 1 or 2 or 3
int k;
switch(event) {
case FL_PUSH:
button=Fl::event_button();
if (button==3){//right mouse will select
//make_current(); // make OpenGL context current
OpenGL_Draw.ProcessSelection(Fl::event_x(), Fl::event_y(),w(),h());
}
redraw();
prevx = Fl::event_x();
prevy = Fl::event_y();

return 1;
case FL_DRAG:
// ... mouse moved while down event ...
button=Fl::event_button();
if (button==1){
curx = Fl::event_x();
cury = Fl::event_y();
if (rotate==true){
RotateXY(curx-prevx,cury-prevy);
}else{
TranslateXY(curx-prevx,cury-prevy);
}
redraw();
prevx = curx;
prevy = cury;
}
#ifdef UNIX
if (button==2){//middle mouse will zoom
#endif
#ifdef WIN32
if (button==3){//poor windows probably has only 2 mousebuttons
#endif
curx = Fl::event_x();
cury = Fl::event_y();
TranslateZ(curx-prevx);
redraw();
prevx = curx;
prevy = cury;
}
return 1;
case FL_RELEASE:
//... mouse up event ...
return 1;
case FL_FOCUS :
case FL_UNFOCUS :
//... Return 1 if you want keyboard events, 0 otherwise
return 1;
case FL_KEYBOARD:
//... keypress, key is in Fl::event_key(), ascii in Fl::event_text()
//... Return 1 if you understand/use the keyboard event, 0 otherwise...
if (Fl::event_key()==113){ //==ESC
exit(0);
}
if (Fl::event_key()==114){ //==r reset viewport
ViewPortChanged=true;
redraw();
}
if (Fl::event_key()==48){ //=="0" the 10th xyz-orb will be drawn
if ((Mol != NULL)||(Mol->GetXYZORBCount()>0)){
for(k=0;k<Mol->GetAtomCount();k++){
Mol->GetXYZORB(k)->draw=!Mol->GetXYZORB(k)->draw;
}
}
redraw();
}
if (Fl::event_key()==49){ //=="1" the 1th xyz-orb will be drawn
if ((Mol != NULL)||(Mol->GetXYZORBCount()>0)){
for(k=Mol->GetAtomCount();k<Mol->GetAtomCount()*2;k++){
Mol->GetXYZORB(k)->draw=!Mol->GetXYZORB(k)->draw;
}
}
redraw();
}
if (Fl::event_key()==50){ //=="2" the 2nd xyz-orb will be drawn
if ((Mol != NULL)||(Mol->GetXYZORBCount()>0)){
for(k=Mol->GetAtomCount()*2;k<Mol->GetAtomCount()*3;k++){
Mol->GetXYZORB(k)->draw=!Mol->GetXYZORB(k)->draw;
}
}redraw();
}
if (Fl::event_key()==51){
if ((Mol != NULL)||(Mol->GetXYZORBCount()>0)){
for(k=Mol->GetAtomCount()*3;k<Mol->GetAtomCount()*4;k++){
Mol->GetXYZORB(k)->draw=!Mol->GetXYZORB(k)->draw;
}
}
redraw();
}
if (Fl::event_key()==52){
if ((Mol != NULL)||(Mol->GetXYZORBCount()>0)){
for(k=Mol->GetAtomCount()*4;k<Mol->GetAtomCount()*5;k++){
Mol->GetXYZORB(k)->draw=!Mol->GetXYZORB(k)->draw;
}
}
redraw();
}
if (Fl::event_key()==53){
if ((Mol != NULL)||(Mol->GetXYZORBCount()>0)){
for(k=Mol->GetAtomCount()*5;k<Mol->GetAtomCount()*6;k++){
Mol->GetXYZORB(k)->draw=!Mol->GetXYZORB(k)->draw;
}
} redraw();
}
if (Fl::event_key()==54){
if ((Mol != NULL)||(Mol->GetXYZORBCount()>0)){
for(k=Mol->GetAtomCount()*6;k<Mol->GetAtomCount()*7;k++){
Mol->GetXYZORB(k)->draw=!Mol->GetXYZORB(k)->draw;
}
}
redraw();
}
if (Fl::event_key()==55){
if ((Mol != NULL)||(Mol->GetXYZORBCount()>0)){
for(k=Mol->GetAtomCount()*7;k<Mol->GetAtomCount()*8;k++){
Mol->GetXYZORB(k)->draw=!Mol->GetXYZORB(k)->draw;
}
}
redraw();
}
if (Fl::event_key()==56){
if ((Mol != NULL)||(Mol->GetXYZORBCount()>0)){
for(k=Mol->GetAtomCount()*8;k<Mol->GetAtomCount()*9;k++){
Mol->GetXYZORB(k)->draw=!Mol->GetXYZORB(k)->draw;
}
}
redraw();
}
if (Fl::event_key()==57){
if ((Mol != NULL)||(Mol->GetXYZORBCount()>0)){
for(k=Mol->GetAtomCount()*9;k<Mol->GetAtomCount()*10;k++){
Mol->GetXYZORB(k)->draw=!Mol->GetXYZORB(k)->draw;
}
}
redraw();
}

return 1;
case FL_SHORTCUT:
//... shortcut, key is in Fl::event_key(), ascii in Fl::event_text()
//... Return 1 if you understand/use the shortcut event, 0 otherwise...
return -1;
default:
// tell FLTK that I don't understand other events
return 0;
}

}
void GL_Window::RotateXY(int x,int y)
{
GLfloat RotX, RotY, afMatrix[16];
glMatrixMode(GL_MODELVIEW);
glGetFloatv(GL_MODELVIEW_MATRIX,afMatrix);
GLfloat Z = afMatrix[14];
afMatrix[14]=0.0f;
glLoadIdentity();
RotX = GLfloat(y)*0.5f;
RotY = GLfloat(x)*0.5f;
glRotatef(RotX, 1.0f, 0.0f, 0.0f);
glRotatef(RotY, 0.0f, 1.0f, 0.0f);
glMultMatrixf(afMatrix);
glGetFloatv(GL_MODELVIEW_MATRIX,afMatrix);
afMatrix[14]=Z;
glLoadMatrixf(afMatrix);
}
void GL_Window::TranslateZ(float zoom) //Zoom
{
GLfloat TransZ, afMatrix[16];
glMatrixMode(GL_MODELVIEW);
// Save old model view matrix
glGetFloatv(GL_MODELVIEW_MATRIX,afMatrix);
// Create a rotation matrix around z-axis
glLoadIdentity();
TransZ = GLfloat(0.5*zoom);
glTranslatef(0.0f, 0.0f, TransZ);
// Multiply with shifted old model view matrix
glMultMatrixf(afMatrix);
}
void GL_Window::TranslateXY(int x,int y)
{
GLfloat TransX,TransY, afMatrix[16];
glMatrixMode(GL_MODELVIEW);
// Save old model view matrix
glGetFloatv(GL_MODELVIEW_MATRIX,afMatrix);
// Create a rotation matrix around z-axis
glLoadIdentity();
TransX = GLfloat(0.02*GLfloat(x));
TransY = GLfloat(-0.02*GLfloat(y));
glTranslatef(TransX, TransY, 0.0f);
// Multiply with shifted old model view matrix
glMultMatrixf(afMatrix);
}

Danke Bitte helft mir schnell, es müsste eigentlich schon gestern funktioniert haben !!!!