如何在其他部件旋转时阻止物体旋转?

Posted

技术标签:

【中文标题】如何在其他部件旋转时阻止物体旋转?【英文标题】:how can I stop an object from rotating while other parts rotate? 【发布时间】:2011-05-10 02:33:25 【问题描述】:

我刚刚画了一个带有 3 个旋转关节的 3 dof 机器人,我画了一个 shere 作为障碍物,它应该是恒定的,没有任何移动,但是随着机器人的抓手开始移动我的障碍物移动同样,这不应该,第二个问题是:我想转动我的机器人,我用箭头键做了这个,没有错误,但它不起作用。这是我的代码:

#include <GL/glut.h>
#include <stdio.h>
#include <stdlib.h>

#define VIEW_TURN_RATE  10
#define GLUT
#define GLUT_KEY
#define GLUT_SPEC

float t1=30;
float t2=45;
float t3=45;
float t4=0;
float t5=0;
float l=1.5;
float h=0.2*l;
double m=0.2;
double n=0.2;
double p=0.2;

float eyex,eyey=0;
float eyez=6;
float lx,ly,lz=0;

int turn = 0, turn1 = 0;

void TurnRight(void)

    turn = (turn - VIEW_TURN_RATE) % 360;


void TurnLeft(void)

    turn = (turn + VIEW_TURN_RATE) % 360;


void TurnForwards(void)

    turn1 = (turn1 - VIEW_TURN_RATE) % 360;


void TurnBackwards(void)

    turn1 = (turn1 + VIEW_TURN_RATE) % 360;


void myidlefunc()

    if(t1<100)
        t1+=2;
    else
       
        if(t2<150)
            t2+=2;
        else
        

            if(t3<150)
                t3+=2;
            else
            

                if(t4<150)
                    t4+=2;
                else
                

                    if(t5<120)
                        t5+=2;
                    else
                    
                        glutIdleFunc(0);
                    
                
            
        
    

    glutPostRedisplay();


#ifdef GLUT
#ifdef GLUT_SPEC
void
    special(int key, int x, int y)


    int i = 0;
    printf("this is special keyboard: %d \n",key);
    switch (key) 
        /* start of view position functions */
    case 'r':
        TurnRight();
        i++;
             
             break;
    case GLUT_KEY_LEFT:
        TurnLeft();
        i++;
                       
                       break;
    case GLUT_KEY_DOWN:
        TurnForwards();
        i++;
                       
                       break;
    case GLUT_KEY_UP:
        TurnBackwards();
        i++;
                     
                     break;
                     /* end of view postions functions */
    
    if (i)
        glutPostRedisplay();

#endif

#ifdef GLUT_KEY
void keyboard(unsigned char c,int x,int y)

    switch(c)
    
    case 27:
        exit(0);
        break;

    case 's':
        if (t1 < 50) 
            t1++;
        break;
    case 'S':
        //if (t1 < 80) 
        t1--;
        //
        break;
    case 'q':
        glutIdleFunc(myidlefunc);
        break;
    case 'f':
        if (t2 < 160) 
            t2++;
        break;
    case 'F':
        t2--;
        break;
    case 'g':
        t3++;
        break;
    case 'h':
        t4++;
        break;
    case 'k':
        t5++;
        break;
    
    glutPostRedisplay();

#endif
#endif

void drawFloor(void)

    glPushMatrix ();
    glBegin(GL_QUADS);
    glColor3f(0.0,0.8,0.8);
    glVertex3f(-20.0, 0.0, 100.0);
    glVertex3f(20.0, 0.0, 100.0);
    glVertex3f(20.0, 0.0, -100.0);
    glVertex3f(-20.0, 0.0, -100.0);
    glEnd();
    glPopMatrix ();
    glEnable(GL_LIGHTING);


void Base(float l)

    glPushMatrix();
    //glColor3f(0.4,0.6,0.5);
    glScaled(1.0*l,0.2*l,1.0*l);
    glutSolidCube(1);
    glPopMatrix();


void obst(float radius, int slices, int stacks)

    glTranslated (0,-0.5,0.0);
    glPushMatrix ();
    glutSolidSphere (radius,slices,stacks);
    glPopMatrix ();


void arm(float l,float r,int slices,int stacks,float rotat)

    float d;
    d=0.2*l;

    glTranslated (0,l/2+d/2,0);
    glPushMatrix ();
    glScaled (d/l,1,d/l);
    glutSolidCube (l);
    glPopMatrix ();

    glTranslated (0,l/2,0);
    glRotated (rotat,0,0,1);
    glPushMatrix ();
    glutSolidSphere (r,slices,stacks);
    glPopMatrix ();


void Base2(float l,float r,int slices,int stacks,float rotat)

    float d;
    d=0.2*l;

    glTranslated (d/2,d/2,d/2);
    glPushMatrix ();
    glScaled (d,d/2,d);
    glutSolidCube (2);
    glPopMatrix ();


void hand(float d,float x)

    glColor3f(0.0,0.4,0.3);
    glRotated(t5,0,1,0);
    glPushMatrix ();
    glTranslated(0,-d/2+x/2,0);
    glScaled(1,x/d,1);
    glutSolidCube (d);
    glPopMatrix();

    glPushMatrix ();
    glTranslated(-d/2+x/2,x/2,0);
    glScaled (x/(d-x),1,d/(d-x));
    glutSolidCube(d-x);
    glPopMatrix ();

    glPushMatrix ();
    glTranslated (d/2-x/2,x/2,0);
    glScaled (x/(d-x),1,d/(d-x));
    glutSolidCube(d-x);
    glPopMatrix ();


void display()

    float l,T,r,x,d;
    double radius,height;
    int slices, stacks;
    l=1.5;
    T=30;
    d=0.2*l;
    x=0.2*d;
    r=d/2;
    radius=1.0;
    height=3;
    slices=1000;
    stacks=202;

    glClearColor(1.0,1.0,1.0,1.0);
    glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);

    glPushMatrix ();
    //lightning start here
    glEnable(GL_LIGHT0);
    GLfloat light0_pos []=lx,ly+1,lz+1,1;
    GLfloat light0_diffuse []=1,0,0,0;
    glLightfv(GL_LIGHT0,GL_DIFFUSE,light0_diffuse);

    GLfloat light0_Ambient []=0,1,1,0;
    glLightfv(GL_LIGHT0,GL_DIFFUSE,light0_Ambient);

    gluLookAt(0.2,0.8,0.0,5.0,3.0,5.0,0.0,0.1,0.0);
    glLightfv(GL_LIGHT0,GL_POSITION,light0_pos);

    glScaled(0.2,0.2,0.2);
    glRotated(90,0.0,1.0,0.0);



    /* Draw "bottom" of floor in blue. */
    glColor3f(0.0, 0.8, 0.8);
    drawFloor();

    //base
    glColor3f(0.0,0.0,0.0);
    Base(2);

    //base2
    glColor3f(1.0,0.0,0.0);
    Base2(l,r,60,60,t1);

    //arm1  

    glColor3f(1.0,0.0,0.8);
    arm(l,r,60,60,t1);

    glColor3f(0.0,1.0,0.0);
    arm(l,r,60,60,t2);

    glColor3f(1.0,0.8,0.5);
    arm(l,r,60,60,t3);


    //hand   
    glTranslated (0,d/2+r,0);
    hand(d,x);

    //obst
    glTranslated (-1,3,0);
    glColor3f(0.0,0.0,1.0);
    obst(radius,slices,stacks);
    //glRotated(0.0,0.0,1.0,0.0);

    glPopMatrix ();
    glFlush();
    glutSwapBuffers();  


void reshape(int width,int height)

    float aspect=(float)width/(float)height;
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glViewport(0,0,width,height);

    //glOrtho(-aspect,aspect,-1,+1,-1,+1);
    gluPerspective(60.0,0.0,0.0,8);

    glMatrixMode (GL_MODELVIEW);
    glLoadIdentity();
    //glTranslatef(0.0, 0.0, 0.0);  /* viewing transform  */


int main(int argc,char** argv)
 
    glutInit(&argc,argv);
    glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE);
    glutInitWindowPosition(0,0);
    glutInitWindowSize(500,500);
    static int window=glutCreateWindow("OPenGL!");
    glutDisplayFunc(display);
    glutReshapeFunc(reshape);
    glutKeyboardFunc(keyboard);
#ifdef GLUT_SPEC
    glutSpecialFunc(special);
#endif

    glShadeModel(GL_FLAT);
    glEnable(GL_LIGHTING);
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_COLOR_MATERIAL);
    glutMainLoop();
    exit(0);

【问题讨论】:

只是对编码风格的评论,您可以将嵌套的 if-else 语句以更易读的格式(请原谅评论中缺少换行符)表达为:if(t1&lt;100) t1+=2; else if(t2&lt;150) t2+=2; else if(t3&lt;150) t3+=2; else if(t4&lt;150) t4+=2; else if(t5&lt;120) t5+=2; else glutIdleFunc(0); 【参考方案1】:

当您最后渲染障碍物时,您的模型视图矩阵已成为该点之前所有变换的接收者。您需要使用glPushMatrix()glPopMatrix() 更仔细地管理您的模型视图矩阵。我还没有测试,但尝试在 //arm 1 之前推送并在您的 //obst 之前弹出。

【讨论】:

亲爱的 Edf,您的想法非常有效。你对我的第二个问题有什么想法吗? 关于您的其他问题,您可以根据系统部件的位置和大小的知识来检查是否存在冲突。这些知识目前遍布您的图形功能。值得将其整合到对象中,然后将它们用于图形和碰撞检测算法。

以上是关于如何在其他部件旋转时阻止物体旋转?的主要内容,如果未能解决你的问题,请参考以下文章

Android:如何在手机旋转后阻止创建新线程

如何阻止 Android 应用程序旋转? [复制]

unity3d如何使物体一直旋转 ,既按下按键后物体一直旋转,再按一次则停止,切换两种旋转速度时不冲突

如何阻止我的角色在 zRotation 约束下过度旋转?

触墙后如何阻止播放器旋转?

如何在悬停时不停止猫头鹰旋转木马?