Saturday, April 6, 2013

How to plot / draw sine curve in Open GL with step function.

Our theoretical graphics lecturer gave us an assignment of drawing sine curve in opengl with step function. After weeks of hunting in WWW I couldn't find a success solution. So I came up with my own solution given below.

First let me explain what is step function. For example if you want to draw a line in opengl there are existing functions. But what is happening inside them? Well if you just start draw like this basic method given below.

First calculate starting point. x0,y0. Then you increase x by one and you calculate respective y value using line equation, y=mx + c
Then you draw that pixel by (x+1,round(m(x+1)+c)) note that you have to round the value of y since pixels are in integer format.

But due to rounding this function is very inefficient. So there exists a simpler method. 

This is the alternative for that using step function.

void drawline2(int x0, int y0, int x1, int y1)
{
    int dx = x1-x0;
    int dy = y1-y0;
    int ddy = 2*dy;
    int ddx = 2*dx;
    int pk = ddy-dx;
    int yk = y0;
    int xk;
    glBegin(GL_POINTS);
    for(xk=x0;xk<=x1;xk++)
    {
        glVertex2i(xk,yk);
        if(pk<0 br="">        {
            pk += ddy;
        }
        else
        {
            pk += ddy-ddx;
            yk++;
        }

    }
    glEnd();
}


If you study the code carefully + you have a basic mathematics you can understand the mechanism of code.  Since this doesn't processor extensive floating point operations this is more faster.

Same manner I tried to draw the sine curve using step function. The algorithm is given below.





"
#ifdef __APPLE__
#include
#else
#include
#include
#endif

#include
#include
#define PI 3.14159265

void reshape(GLsizei w, GLsizei h)
{
    if (h==0)
        h = 1;

    glViewport(0, 0, w, h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    if (w<=h)
        glOrtho(0.0f,250.0f,0.0f,250.0f*h/w,1.0,-1.0);
    else
        glOrtho(0.0f,250.0f*w/h,0.0f,250.0f,1.0,-1.0);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity() ;
}

void writepixel(int x, int y)
{
    glBegin(GL_POINTS);
    glVertex2i(x,y);
    glVertex2i((180-x),y);
    glVertex2i((180+x),(-y));
    glVertex2i((360-x),(-y));
    glEnd();
}

void drawsine2()
{
    int x = 0;
    int y = 0;
    float temp = 57.3 * sin(PI/180);
    float pk = 0;
    while(x<=85) //after reaching 85 the change of Y is significantly low and curve fails to get it.
    {
        if(pk>=0)
        {
            writepixel(x,y);
            pk -= temp*sqrt(1-((y)*(y)/3283.29));//cos((x)*PI/180.0);
            x++;
        }
        else
        {
            writepixel(x,y);
            pk += 1 - temp*sqrt(1-((y)*(y)/3283.29));//cos((x)*PI/180.0);
            x++;
            y++;
        }
    }
    while(x<=90)
    {
        writepixel(x,y);
        x++;
    }
}



void Sinecurve(void)
{
    glClear(GL_COLOR_BUFFER_BIT);
    glColor3f(0.0,0.0,1.0);
    drawsine2();
    glLoadIdentity();
    glTranslatef(0.0,125.0,0.0);
    glFlush();
}

void initial(void)
{
    glClearColor(0.0,0.0,0.0,0.0);
    glShadeModel(GL_SMOOTH);
}

/* Program entry point */

int main(int argc, char *argv[])
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    glutInitWindowSize(800,500);
    glutInitWindowPosition(100,100);
    glutCreateWindow("Sine Curve");
    initial();
    glutDisplayFunc(Sinecurve);
    glutReshapeFunc(reshape);
    glutMainLoop();

"

Hope this might help anyone. :)

No comments: