2016-01-26 4 views
0

У меня проблема с моими часами. В первые 10 минут часовая стрелка не показывает правильный час, и она изменяется, когда меняется минутная стрелка, но через 10 минут она отображается правильно. Не могли бы вы помочь мне исправить это?Аналоговые часы OpenGL отображаются неправильно?

Я думаю, что есть проблема в этих строках, но я не уверен:

static void TimeEvent(int te) 
{ 
    rx = 30 * cos(angle); 
    ry = 30 * sin(angle); 
    rz = 30 * cos(angle); 
    angle += 0.01; 
    if (angle > M_TWOPI) angle = 0; 

    glutPostRedisplay(); 
    glutTimerFunc(100, TimeEvent, 1); 
} 

Вот весь мой код:

#include <GL/glut.h> 
#include <gl/gl.h> 
#include <string.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <math.h> 
#include <time.h> 

GLUquadricObj *Cylinder; 

struct tm *newtime; 
time_t l_time; 
int M_TWOPI=0; 
GLfloat rx, ry, rz, angle; 

GLfloat LightAmbient[]= { 0.5f, 0.5f, 0.5f, 1.0f }; 
GLfloat LightDiffuse[]= { 0.5f, 0.5f, 0.5f, 1.0f }; 
GLfloat LightPosition[]= { 5.0f, 25.0f, 15.0f, 1.0f }; 
GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 }; 

static int view_state = 1; // Ortho view = 1, Perspective = 0 


void newLine(float Start, float End, float angle){ 
    float c = cos(angle), s = sin(angle); 
    glVertex2f(-8.0f*Start*c, -8.0f*Start*s); 
    glVertex2f(-8.0f*End*c, -8.0f*End*s); 
} 


void Sprint(float x, float y, char *st) 
{ 
    int l,i; 

    l=strlen(st); 
    glRasterPos3f(x, y, -1); 
    for(i=0; i < l; i++) 
     { 
     glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, st[i]); 
    } 

} 

static void TimeEvent(int te) 
{ 
    rx = 30 * cos(angle); 
    ry = 30 * sin(angle); 
    rz = 30 * cos(angle); 
    angle += 0.01; 
    if (angle > M_TWOPI) angle = 0; 

    glutPostRedisplay(); 
    glutTimerFunc(100, TimeEvent, 1); 
} 


void Draw_clock(GLfloat cx, GLfloat cy, GLfloat cz) 
{ 

    int hour_ticks , sec_ticks; 
    glPushMatrix(); 
    glTranslatef(cx,cy,cz); 
    glRotatef(180, 1.0, 0.0, 0.0); 


    glPushMatrix(); 
    glColor3f(1.0, 0.5, 0.0); 
    glTranslatef(0, 0, 0.0); 
    glRotatef((360/12) * newtime->tm_hour + (360/60) * (60/(newtime->tm_min+1)), 0.0, 0.0, 1.0); 
    glPushMatrix(); 
    glTranslatef(0.0, 0.0, 2.0); 
    glPopMatrix(); 
    glRotatef(90, 1.0, 0.0, 0.0); 
    gluCylinder(Cylinder, 0.75, 0, 4, 16, 16); 
    glPopMatrix(); 

    glPushMatrix(); 
    glColor3f(1.0, 0.0, 1.0); 
    glTranslatef(0, 0, 0.0); 
    glRotatef((360/60) * newtime->tm_min, 0.0, 0.0, 1.0); 
    glPushMatrix(); 
    glTranslatef(0.0, 0.0, 3.0); 
    glScalef(0.5, 0.5, 1.0); 
    glPopMatrix(); 
    glRotatef(90, 1.0, 0.0, 0.0); 
    glutSolidCone (0.5, 6, 6, 16); 
    glPopMatrix(); 

    glPushMatrix(); 
    glColor3f(1.0, 0.0, 0.0); 
    glTranslatef(0, 0, -0.0); 
    glRotatef((360/60) * newtime->tm_sec, 0.0, 0.0, 1.0); 
    glPushMatrix(); 
    glTranslatef(0.0, 0.0, 4.0); 
    glScalef(0.25, 0.25, 1.0); 
    glPopMatrix(); 
    glRotatef(90, 1.0, 0.0, 0.0); 
    gluCylinder(Cylinder, 0.25, 0, 6, 16, 16); 
    glPopMatrix(); 


    for(hour_ticks = 0; hour_ticks < 12; hour_ticks++) 
     { 
     glPushMatrix();// Draw next arm axis. 
     glColor3f(0.0, 1.0, 1.0); // give it a color 
     glTranslatef(0.0, 0.0, 0.0); 
     glRotatef((360/12) * hour_ticks, 0.0, 0.0, 1.0); 
     glTranslatef(6.0, 0.0, 0.0); 
     glEnable(GL_LINE_SMOOTH); 
     glBegin(GL_LINES); 
     newLine(0.08f, 0.2f, 0.0f); 
     glEnd(); 

     glPopMatrix(); 
    } 

    for(sec_ticks = 0; sec_ticks < 60; sec_ticks++) 
    { 
    glPushMatrix(); 
    glTranslatef(0.0, 0.0, 0.0); 
    glRotatef((360/60) * sec_ticks, 0.0, 0.0, 1.0); 
    glTranslatef(6.0, 0.0, 0.0); 
    glutSolidCone(1.0, 2.0, 3, 4); 
    glPopMatrix(); 
    } 


    glPopMatrix(); 

} 

void num() 
{ 

    glColor3f(0.0, 0.0, 1.0); 
    Sprint(-6.2,-0.2,"9"); //counting from center 
    Sprint(-0.2,-6.2,"6"); 
    Sprint(2.8,-5.5,"5"); 
    Sprint(5.0,-3.2,"4"); 
    Sprint(5.0,+2.8,"2"); 
    Sprint(2.8,+5.0,"1"); 
    Sprint(-3.33,+4.95,"11"); 
    Sprint(-0.2,-6.2,"6"); 
    Sprint(-3.2,-5.45,"7"); 
    Sprint(-0.4,5.7,"12"); 
    Sprint(-5.35,-3.25,"8"); 
    Sprint(-5.55,+2.8,"10"); 
    Sprint(5.8,-0.2,"3"); 

} 


void display_clock() 
{ 
    time(&l_time); // Get time 
    newtime = localtime(&l_time); // Convert to local time 

    glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

    // easy way to put text on the screen. 
    glMatrixMode (GL_PROJECTION); 
    glLoadIdentity(); 
    glOrtho(-8.0, 8.0, -8.0, 8.0, 1.0, 60.0); 
    glMatrixMode(GL_MODELVIEW); 
    glLoadIdentity(); 
    glDisable(GL_LIGHTING); 
    glDisable(GL_COLOR_MATERIAL); 

    glColor3f(1.0, 1.0, 1.0); 

    Sprint(-2, 3, "  Clock"); 


Draw_clock(0.0, 0.0, -14.0); 
num(); 
glutSwapBuffers(); 
} 


void display(void) 
{ 
    glClear(GL_COLOR_BUFFER_BIT); 
    display_clock(); 
    glFlush(); 
} 

void reshape (int w, int h) 
{ 
    glViewport (0, 0, (GLsizei) w, (GLsizei) h); 
    glMatrixMode (GL_PROJECTION); 
    glLoadIdentity(); 
} 



int main(int argc, char** argv) 
{ 
    glutInit(&argc, argv); 
    glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB); 
    glutInitWindowSize (500, 500); 
    glutInitWindowPosition (50, 50); 
    glutCreateWindow (argv[0]); 
    glutSetWindowTitle("Clock"); 
    Cylinder = gluNewQuadric(); 
    glutAttachMenu(GLUT_RIGHT_BUTTON); 
    glutDisplayFunc(display); 
    glutReshapeFunc(reshape); 
    glutTimerFunc(10, TimeEvent, 1); 
    glutMainLoop(); 
    return 0; 
} 

ответ

0

Вы делаете целочисленную арифметику:

glRotatef((360/12) * newtime->tm_hour + (360/60) * (60/(newtime->tm_min+1)), 0.0, 0.0, 1.0); 

должно быть:

glRotatef(30.0 * newtime->tm_hour + 6.0) * (60.0/(newtime->tm_min+1)), 0.0, 0.0, 1.0); 

и так далее.

Хотя, поскольку 360/12 и 360/60 являются константами, вы также можете заменить их на вычисленные значения.

+0

Это не сработало. Я изменил их, но у меня такая же проблема. – rumay

0

Я считаю, что ваша проблема здесь:

glRotatef((360/12) * newtime->tm_hour + (360/60) * (60/(newtime->tm_min+1)), 0.0, 0.0, 1.0); 

Оно должно быть:

glRotatef((360/12) * newtime->tm_hour + (360.0/12/60) * (newtime->tm_min+1), 0.0, 0.0, 1.0);