Monday, July 11, 2011

Dijkstra Algorithm

Here is the program of Dijkstra algorithm done in Tubo C++



 // Program to find the shortest path to all the nodes

// From the given SOURCE NODE.

// Using DIJKSTRA ALGORITHM.

#include<stdio.h>

#include<conio.h>

int main()

{

int path[10][10]={0}; // this matrix will store the shortes path to all notes

int edge[10][10]={0}; // this matrix will hold the weights of edges in a graph

int distance[10]={0}; // this matrix will hold the shortest distance to all

// nodes from the given source node

int visited[10]={0}; // this matrix will holds the status of visited nodes in the algorithm

int a=1;

int n,i,j;

clrscr();

printf("Enter number of nodes:");

scanf("%d",&n);

// Initialise Path matrix

for(i=0;i<n;i++) {

path[i][0]=999;

}

printf("Enter the adjacency matrix:\n \n");

// Get the adjacency matrix Input

for(i=1;i<n;i++)

{

for(j=0;j<i;j++)

{

printf(" Distance from %c to %c ",65+i,65+j);

scanf("%d",&edge[i][j]);

edge[j][i]=edge[i][j];

}

}

// Print the adjacency table

printf("\n Adjacency matrix\n");

for(i=0;i<n;i++) {

for(j=0;j<n;j++) {

printf(" %d\t",edge[i][j]);

}

printf("\n");

}

// Get the source and destination node

fflush(stdin);

char source,dest;

printf("Enter the source:");

scanf("%c",&source);

fflush(stdin);

printf("Enter the destination:");

scanf("%c",&dest);

int from=source-65;

int to=dest-65;

printf("\n Source : %d destination:%d\n",from,to);

// Initialise the distance table

// Set the distance to very hight value(in algo infinity)

// except the from node

for(i=0;i<n;i++) {

if(i!=from) {

distance[i]=1000;

}else {

distance[i]=0;

}

}

//////////////////////////////////////////////////////

// DIJKSTRA ALGORITHM

/////////////////////////////////////////////////////

int k;

for(k=0;k<n;k++) {

// Search the node which is closest to the source node

int short_index=0;

int found=0;

int short_value=1000;

for(i=0;i<n;i++)

{

if(visited[i]==0)

{

// Node is not visited

if(distance[i]<short_value) {

short_index=i;

short_value=distance[i];

found=1;

}

}

}

printf("\n visited : %c",65+short_index);

// Mark the node visited

visited[short_index]=1;

// printf("\n\n distance table :");

// print the distance table

// for(i=0;i<n;i++) {

// printf(" %c: %d\t",65+i,distance[i]);

// }

// Update the distance table

// Check if the current distance is larger than the distance

// via shorted node and if YES update the distance table

// and add the node to the shortes path

int p;

for(p=0;p<n;p++)

{

int via_short = distance[short_index]+edge[short_index][p];

if(distance[p]>via_short) {

distance[p]= via_short;

// Add the current node in the path

int h=0;

while(path[p][h]!=999) {

h++;

}

path[p][h]=short_index;

path[p][h+1]=999;

}

}

}

printf("\n\n FINAL TABLE \n");

// print the distance table

for(i=0;i<n;i++) {

printf(" %c: %d\t",65+i,distance[i]);

}

// Print shorted paths to all nodes

printf("\n\n SHORTEST PATHS TO ALL NODES from source node :\n");

for(i=0;i<n;i++) {

int h=0;

printf(" %c :",65+i);

while(path[i][h]!=999) {

printf("%c->",65+path[i][h]);

h++;

}

printf("%c\n",i+65);

}

getch();

return 0;

}

Tuesday, May 24, 2011

CAR Game part-1




Hi,
Here I come with yet another game.
This one came out rather too quickly as I had most of the functions already written and tested. :-) This is the game which i used to play in the video parlour, that was fun back then. well, Now there is fun in developing it.






#include "stdafx.h"

#include <iostream>
#include <stdlib.h>

#include <GL/glut.h>

#include "imageloader.h"
#include "math.h"

using namespace std;

const int MAX_X=1200;
const int MAX_Y=900;
const int MIN_X=0;
const int MIN_Y=0;

int car_x = MAX_X/4;
int car_y = MAX_Y;


int car_width=100;
int car_length=200;
int rx = MAX_X/4;
int ry = MAX_Y;
int road_width = 420;
int path_width = 20;
int lane_distance = car_width+40;
int car_max_x = (car_x+path_width) + lane_distance;
int car_min_x = MAX_X/4;

int car_cnt = 1;
GLuint _textureId; //The id of the texture
GLuint _textureId1; //The id of the texture
GLuint _textureId2; //The id of the texture
GLuint _textureId3; //The id of the texture

GLuint current_textureId; //The id of the texture

int timedelay = 100;
void draw_car(int length,int width,int x, int y);

int move_cnt=0;

typedef struct vehicle {
int x,y;
int length,width;
int texture_id;
struct vehicle* next;
}VEHICLE;

VEHICLE *head=NULL;
int current_y=0;

void create_vehicles() {
int rand_x = 0;

if(current_y>car_length) {
current_y = -200;
} else {
return;
}
// Create a new vehicle;
VEHICLE* temp = new VEHICLE;
temp->length = car_length;
temp->width = car_width;
temp->next = NULL;
temp->x = car_x+path_width;
temp->y = current_y;
if(car_cnt==1) {
temp->texture_id = _textureId1;
} else if(car_cnt==2) {
temp->texture_id = _textureId2;
} else if(car_cnt==3) {
temp->texture_id = _textureId3;
}

car_cnt++;
if(car_cnt==4) car_cnt = 1;

// Add it to the list
if(!head) {
head = temp;
} else {
VEHICLE* t = head;
while(t->next) {
t = t->next;
}
t->next = temp;
}
}

void draw_vehicles() {

VEHICLE* temp = head;
while(temp) {

int car_width = temp->width;
int car_length = temp->length;
int car_x = temp->x;
int car_y = temp->y;
current_textureId = temp->texture_id;
draw_car(car_width,car_length,car_x,car_y);

temp = temp->next;
}
}

void move_vehicles() {
VEHICLE* temp = head;
while(temp) {
temp->y = temp->y+10;
temp = temp->next;
}
current_y+=10;
}
void drawScene();

void *font = GLUT_BITMAP_TIMES_ROMAN_24;
void *fonts[] =
{
GLUT_BITMAP_9_BY_15,
GLUT_BITMAP_TIMES_ROMAN_10,
GLUT_BITMAP_TIMES_ROMAN_24
};


void specialKey(int key, int x, int y) {
switch (key) {
case 101: //UP arrow key
if(timedelay>0){
timedelay-=10;
}

break;
case 103: //DOWN arrow key
if(timedelay<500){
timedelay+=10;
}
break;

case 100: //LEFT arrow key
if(car_x>MAX_X/4){
car_x-=car_width;
}
break;

case 102: //RIGHT arrow key
if(car_x<(MAX_X/4-car_width+400)){
car_x+=car_width;
}
break;

}
}

void handleKeypress(unsigned char key, int x, int y) {
switch (key) {
case 27: //Escape key
exit(0);
}
}

void output(int x, int y, char *string)
{
int len, i;

glRasterPos2f(x, y);
len = (int) strlen(string);
for (i = 0; i < len; i++) {
glutBitmapCharacter(font, string[i]);
}
}

//Makes the image into a texture, and returns the id of the texture
GLuint loadTexture(Image* image) {
GLuint textureId;
glGenTextures(1, &textureId); //Make room for our texture
glBindTexture(GL_TEXTURE_2D, textureId); //Tell OpenGL which texture to edit
//Map the image to the texture
glTexImage2D(GL_TEXTURE_2D, //Always GL_TEXTURE_2D
0, //0 for now
GL_RGB, //Format OpenGL uses for image
image->width, image->height, //Width and height
0, //The border of the image
GL_RGB, //GL_RGB, because pixels are stored in RGB format
GL_UNSIGNED_BYTE, //GL_UNSIGNED_BYTE, because pixels are stored
//as unsigned numbers
image->pixels); //The actual pixel data
return textureId; //Returns the id of the texture
}



void initRendering() {
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_NORMALIZE);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_LINE_STIPPLE);
glLineWidth(4);
Image* image = loadBMP("car3.bmp");
_textureId = loadTexture(image);
delete image;

image = loadBMP("car4.bmp");
_textureId1 = loadTexture(image);
delete image;

image = loadBMP("car5.bmp");
_textureId2 = loadTexture(image);
delete image;

image = loadBMP("car6.bmp");
_textureId3 = loadTexture(image);
delete image;

}

void handleResize(int w, int h) {
/*glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0, (float)w / (float)h, 1.0, 200.0);*/

glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, w, h, 0);
glMatrixMode(GL_MODELVIEW);
}

void draw_lanes() {

glLineStipple(1,0x00ff);
glBegin(GL_LINES);

for(int i=1; i<=3;i++) {
glVertex3f(rx+path_width+car_width*i, MAX_Y, 0);
glVertex3f(rx+path_width+car_width*i, 0, 0);
}

glEnd();

glLineStipple(1,0xffff);
}

void draw_footpath(int x,int y,int path_width) {
int cnt=25;
int bwidth = path_width-2;
int bheight = 40;
int yy=y;
int xx=x+2;

// Blocks on the foot path
for(int i=0; i<cnt; i++) {
glBegin(GL_POLYGON);
glVertex3f(xx,yy,0);
glVertex3f(xx+bwidth,yy,0);
glVertex3f(xx+bwidth,yy+bheight,0);
glVertex3f(xx,yy+bheight,0);
glEnd();
yy+=2*bheight;
}
}

void create_road() {

glColor3f(1.0f, 1.0f, 1.0f);

ry = MAX_Y;
// Lines on the side
glBegin(GL_LINES);
glVertex3f(rx, ry, 0);
glVertex3f(rx, 0, 0);
glVertex3f(rx+path_width, ry, 0);
glVertex3f(rx+path_width, 0, 0);

glVertex3f(rx+road_width, ry, 0);
glVertex3f(rx+road_width, 0, 0);
glVertex3f(rx+path_width+road_width, ry, 0);
glVertex3f(rx+path_width+road_width, 0, 0);

glEnd();

ry=-200;
move_cnt ++;
if (move_cnt==8) {
move_cnt = 0;
}
ry = ry + 10*move_cnt;

// Draw footpath on both the sides of the road
draw_footpath(rx,ry,path_width);
draw_footpath(rx+road_width,ry,path_width);

// Draw the lanes in the road
draw_lanes();

}

void draw_car(int length,int width,int x, int y) {

glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, current_textureId);

//Bottom
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
//glColor3f(0.0f, 0.1f, 0.1f);

glBegin(GL_QUADS);

glTexCoord2f(0.0f, 0.0f);
glVertex3f(x, y, 0);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(x+length,y,0);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(x+length,y-width,0);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(x,y-width,0);

glEnd();

glBindTexture(GL_TEXTURE_2D,0);
}

void drawScene() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

GLfloat ambientLight[] = {0.2f, 0.2f, 0.2f, 1.0f};
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientLight);

GLfloat directedLight[] = {0.7f, 0.7f, 0.7f, 1.0f};
GLfloat directedLightPos[] = {-10.0f, 15.0f, 20.0f, 0.0f};
glLightfv(GL_LIGHT0, GL_DIFFUSE, directedLight);
glLightfv(GL_LIGHT0, GL_POSITION, directedLightPos);

// Show the X and Y coordinate location of the mouse
glClear(GL_COLOR_BUFFER_BIT);

// Draw the main racing
current_textureId = _textureId;
draw_car(car_width,car_length,car_x+path_width,car_y);

// Create a road
create_road();

// Create new vehicle
create_vehicles();

// Move vehicles
move_vehicles();

// Draw the vehicles
draw_vehicles();

glutSwapBuffers();
}

//Called every 25 milliseconds
void update(int value) {

drawScene();

glutPostRedisplay();
glutTimerFunc(timedelay, update, 0);
}

int main(int argc, char** argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(MAX_X, MAX_Y);

glutCreateWindow("Car Game");
initRendering();

glutDisplayFunc(drawScene);
glutKeyboardFunc(handleKeypress);
glutSpecialFunc(specialKey);

glutReshapeFunc(handleResize);
glutTimerFunc(timedelay , update, 0);

glutMainLoop();
return 0;
}


Monday, May 23, 2011

Bouncing Ball

Hi, I was having trouble with my half accomplished game. The problem was that I couldnt increase the speed of the moving ball. Even if I put absolutely no timer then also ball was moving with very less speed. I asked my friends on the lunch table and they gave me the solution that I should be increasing the step count OR i should always draw the ball in the origin space and translate it. SO I tried BOTH :-) Increasing step count did help and it doesn't look bad. I was expecting that I will get a little discrete moves but that didnt happen. I still get enough smooth output. Now I went for divide and conquer apporach and decided to get the ball properly rolling first. :-) So here is my program which will show the ball bouncing on the edges of the windows. User can resize the window. He can increase and decrease the speed of moving ball by using the UP and DOWN arrow keys. thanks :-)
#include "stdafx.h"

#include <iostream>
#include <stdlib.h>

#include <GL/glut.h>

#include "math.h"

using namespace std;

int MAX_X=1200;
int MAX_Y=900;
const int MIN_X=0;
const int MIN_Y=0;
int m_x=0;
int m_y=0;

int ball_x=500;
int ball_y=500;
int radius = 30;
int poly_circle[20][2];
int circle_segments = 0;


// BY default ball will go up
int x_dir = 1;
int y_dir = -1;
int base_y;
int base_x;
float move_mag = 5.0;

void init_circle() {
int x1=0;
int y1=0;
int cnt=0;
float angle = 0;
float x2,y2;
for (angle = 0; angle < 360; angle+=25.0,cnt++) {
float rad_angle = angle * 3.14 / 180;
x2 = x1+radius * sin((double)rad_angle);
y2 = y1+radius * cos((double)rad_angle);
poly_circle[cnt][0] = x2;
poly_circle[cnt][1] = y2;
}
poly_circle[cnt][0]=poly_circle[0][0];
poly_circle[cnt][1]=poly_circle[0][1];
circle_segments = cnt;
}



void drawScene();

void move_ball() {
ball_x = ball_x + (move_mag*x_dir);
ball_y = ball_y + (move_mag*y_dir);
}

void change_y_dir() {
y_dir = -y_dir;
}
void change_x_dir() {
x_dir = -x_dir;
}
void change_both_dir() {
change_y_dir();
change_x_dir();
}

int crossed_x_limits() {
if((ball_x-radius)<=MIN_X) {
return 1;
}
if((ball_x+radius)>=MAX_X) {
return 1;
}
return 0;
}


int crossed_y_limits() {
if(ball_y-radius<=MIN_Y) {
return 1;
}
if(ball_y+radius>=MAX_Y) {
return 1;
}
return 0;
}


// the mouse callback function:
void mouse_move(int x, int y)
{
m_x = x;
m_y = y;

drawScene();
}


void handleResize(int w, int h) {

glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
MAX_X = w;
MAX_Y = h;
gluOrtho2D(0, w, h, 0);
glMatrixMode(GL_MODELVIEW);
}


void drawCircle(float radius, float x1, float y1)
{
float angle = 0;
float x2,y2,cx,cy,fx,fy;
int cache = 0;

glPushMatrix();//(NEW) Create a new matrix
glTranslatef(x1,y1,0);//(NEW) Rotate the triangle on z axis based on how much time has passed

glBegin(GL_LINES);
for(int i=0; i<circle_segments;++i) {
glVertex2f(poly_circle[i][0],poly_circle[i][1]);
glVertex2f(poly_circle[i+1][0],poly_circle[i+1][1]);
}
glEnd();

glPopMatrix();//(NEW) stops current transformations to the matrix
}

void play_ball() {
move_ball();

if (crossed_x_limits()) {
change_x_dir();
} else if (crossed_y_limits()) {
change_y_dir();
} else {
// Do nothing
}
}

void drawScene() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

glLineWidth(4);
// Draw the ball
play_ball();
drawCircle(radius,ball_x,ball_y);

glutSwapBuffers();
}

//Called every 25 milliseconds
void update(int value) {

drawScene();

glutPostRedisplay();
glutTimerFunc(25, update, 0);
}

void idle_func(void) {
drawScene();
}

void initRendering() {
glEnable(GL_DEPTH_TEST);

}

void handleKeypress(unsigned char key, int x, int y) {
switch (key) {
case 27: //Escape key
exit(0);

}
}

void specialKey(int key, int x, int y) {
switch (key) {
case 101: //UP arrow key
if (move_mag<radius-1) {
move_mag+=0.5;
}
break;
case 103: //DOWN arrow key
if (move_mag>1) {
move_mag-=0.5;
}
break;
}
}


int main(int argc, char** argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(MAX_X, MAX_Y);

glutCreateWindow("Bouncing Ball");
initRendering();
init_circle();

glutDisplayFunc(drawScene);
glutSpecialFunc(specialKey);
glutReshapeFunc(handleResize);
glutMotionFunc(mouse_move);
glutPassiveMotionFunc(mouse_move);
glutTimerFunc(25 , update, 0);
//glutIdleFunc(idle_func);

glutMainLoop();
return 0;
}

Sunday, May 22, 2011

Brick Game part1

Hi, Here I am uploading game which i developed in openGL (motive was to kill the time on boring friday) This is very novice and still in the early in its life. This is work of just 4-5 hours. I wasted some of time just to figure out that the Image which I used for texture mapping needs to be of size 256X256 or some multiple of it. It's only after Kapil(one of my colleague) came for my rescue and we figured out the flaw. thanks Kapil! :) Once I could draw the wall of bricks i developed the logic on weekend and implemented it as first thing on monday morning. All I can say is it works! :) it can be made more efficient and more cool but I will leave that for some other day. You can download the code and make your own amendments to it. Its all free. thanks. :)


#include <iostream>
#include <stdlib.h>

#include <GL/glut.h>

#include "imageloader.h"
#include "math.h"

using namespace std;

const int MAX_X=1200;
const int MAX_Y=900;
const int MIN_X=0;
const int MIN_Y=0;
int m_x=0;
int m_y=0;
int brick_length=100,brick_width=30;

int ball_x=500;
int ball_y=500;
int radius = 20;

// BY default ball will go up
int x_dir = 1;
int y_dir = -1;
int base_y;
int base_x;
float move_mag = 5.0;

typedef struct brick {
int x;
int y;
int visible;
}BRICK;

BRICK BR[10][10];

void drawScene();

void *font = GLUT_BITMAP_TIMES_ROMAN_24;
void *fonts[] =
{
GLUT_BITMAP_9_BY_15,
GLUT_BITMAP_TIMES_ROMAN_10,
GLUT_BITMAP_TIMES_ROMAN_24
};

void init_bricks() {

// Initialise the bricks
int x=100,y=50;

for(int row=0;row<10;row++) {
for(int column=0;column<10;column++) {
BRICK temp;
temp.visible = 1;
temp.x = (brick_length*column)+x;
temp.y = (brick_width*row)+y;
BR[row][column] = temp;
}
}

}

void move_ball() {
ball_x = ball_x + (move_mag*x_dir);
ball_y = ball_y + (move_mag*y_dir);
}

void change_y_dir() {
y_dir = -y_dir;
}
void change_x_dir() {
x_dir = -x_dir;
}
void change_both_dir() {
change_y_dir();
change_x_dir();
}

int crossed_x_limits() {
if((ball_x-radius)<=MIN_X) {
ball_x = MIN_X+radius;
return 1;
}
if((ball_x+radius)>=MAX_X) {
ball_x = MAX_X-radius;
return 1;
}
return 0;
}


int crossed_y_limits() {
if(ball_y-radius<=MIN_Y) {
ball_y = MIN_Y+radius;
return 1;
}
if(ball_y+radius>=MAX_Y) {
ball_y = MAX_Y-radius;
return 1;
}
return 0;
}
int hit_base() {

if (ball_x>=m_x-brick_length && ball_x<=m_x+brick_length) {
if((ball_y+radius)<=MAX_Y && (ball_y+radius)>=(MAX_Y-brick_width)) {
return 1;
}
}

return 0;
}


// the mouse callback function:
void mouse_move(int x, int y)
{
m_x = x;
m_y = y;

drawScene();
}

void specialKey(int key, int x, int y) {
switch (key) {
case 101: //UP arrow key
if (move_mag<radius-1) {
move_mag+=0.5;
}
break;
case 103: //DOWN arrow key
if (move_mag>1) {
move_mag-=0.5;
}
break;
}
}

void handleKeypress(unsigned char key, int x, int y) {
switch (key) {
case 27: //Escape key
exit(0);
}
}

void output(int x, int y, char *string)
{
int len, i;

glRasterPos2f(x, y);
len = (int) strlen(string);
for (i = 0; i < len; i++) {
glutBitmapCharacter(font, string[i]);
}
}

//Makes the image into a texture, and returns the id of the texture
GLuint loadTexture(Image* image) {
GLuint textureId;
glGenTextures(1, &textureId); //Make room for our texture
glBindTexture(GL_TEXTURE_2D, textureId); //Tell OpenGL which texture to edit
//Map the image to the texture
glTexImage2D(GL_TEXTURE_2D, //Always GL_TEXTURE_2D
0, //0 for now
GL_RGB, //Format OpenGL uses for image
image->width, image->height, //Width and height
0, //The border of the image
GL_RGB, //GL_RGB, because pixels are stored in RGB format
GL_UNSIGNED_BYTE, //GL_UNSIGNED_BYTE, because pixels are stored
//as unsigned numbers
image->pixels); //The actual pixel data
return textureId; //Returns the id of the texture
}

GLuint _textureId; //The id of the texture

void initRendering() {
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_NORMALIZE);
glEnable(GL_COLOR_MATERIAL);

Image* image = loadBMP("br.bmp");
_textureId = loadTexture(image);
delete image;
}

void handleResize(int w, int h) {
/*glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0, (float)w / (float)h, 1.0, 200.0);*/

glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, w, h, 0);
glMatrixMode(GL_MODELVIEW);
}

void create_brick(int length,int width,int x, int y) {
glBegin(GL_QUADS);

glTexCoord2f(0.0f, 0.0f);
glVertex3f(x, y, 0);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(x+length,y,0);
glTexCoord2f(1.0f, 1.0f);
glVertex3f(x+length,y-width,0);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(x,y-width,0);

glEnd();
}



void drawCircle(float radius, float x1, float y1)
{
float angle = 0;
float x2,y2,cx,cy,fx,fy;
int cache = 0;
glBegin(GL_LINES);
for (angle = 0; angle < 360; angle+=25.0) {
float rad_angle = angle * 3.14 / 180;
x2 = x1+radius * sin((double)rad_angle);
y2 = y1+radius * cos((double)rad_angle);
if (cache) {
glVertex2f(cx,cy);
glVertex2f(x2,y2);
} else {
fx = x2;
fy = y2;
}
cache = 1;
cx = x2;
cy = y2;
}
glVertex2f(x2,y2);
glVertex2f(fx,fy);

glEnd();
}

void play_ball() {
move_ball();

if (crossed_x_limits()) {
change_x_dir();
} else if (crossed_y_limits()) {
change_y_dir();
} else {
// Do nothing
}
}

void detect_collision() {

if(hit_base()) {
change_y_dir();
return;
}

for(int row=0;row<10;row++) {
for(int column=0;column<10;column++) {
BRICK temp = BR[row][column];
if (temp.visible) {
int min_y = temp.y - brick_width;
int min_x = temp.x;
int max_x = temp.x + brick_length;
int max_y = temp.y ;

if ((ball_x+radius)>=min_x &&
(ball_x-radius)<=max_x &&
(ball_y+radius)>=min_y &&
(ball_y-radius)<=max_y) {
BR[row][column].visible = 0;
change_both_dir();
return;
}

}
}
}
}


void drawScene() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();


/*GLfloat ambientLight[] = {0.2f, 0.2f, 0.2f, 1.0f};
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientLight);

GLfloat directedLight[] = {0.7f, 0.7f, 0.7f, 1.0f};
GLfloat directedLightPos[] = {-10.0f, 15.0f, 20.0f, 0.0f};
glLightfv(GL_LIGHT0, GL_DIFFUSE, directedLight);
glLightfv(GL_LIGHT0, GL_POSITION, directedLightPos);*/

// Show the X and Y coordinate location of the mouse
glClear(GL_COLOR_BUFFER_BIT);

glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, _textureId);

//Bottom
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glColor3f(1.0f, 0.2f, 0.2f);

// Draw the wall of bricks
int x=100,y=50;

for(int row=0;row<10;row++) {
for(int column=0;column<10;column++) {
if (BR[row][column].visible ==1) {
create_brick(
brick_length,
brick_width,
(brick_length*column)+x,
(brick_width*row)+y);
}
}
}

// Draw the moving support base
{
int x=m_x-brick_length,y=MAX_Y;
for(int row=0;row<1;row++) {
for(int column=0;column<2;column++) {
create_brick(
brick_length,
brick_width,
(brick_length*column)+x,
y-(brick_width*row));
}
}
}

// Draw the ball
play_ball();
drawCircle(radius,ball_x,ball_y);
detect_collision();

glutSwapBuffers();
}

//Called every 25 milliseconds
void update(int value) {

drawScene();

glutPostRedisplay();
glutTimerFunc(5, update, 0);
}

int main(int argc, char** argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(MAX_X, MAX_Y);

glutCreateWindow("Texture demo");
initRendering();

init_bricks();
glutDisplayFunc(drawScene);
glutKeyboardFunc(handleKeypress);
glutSpecialFunc(specialKey);

glutReshapeFunc(handleResize);
glutMotionFunc(mouse_move);
glutPassiveMotionFunc(mouse_move);
glutTimerFunc(5 , update, 0);

glutMainLoop();
return 0;
}


Thursday, May 19, 2011

Using styles of lines and letting user control it



Hi,
This one you would definitely like.
A small but cute program. It lets user draw the lines and also lets user control the styles of the lines. Colors would have been even better, But for some other time.
:-)

// This program is for line drawing using opengl 
// User cn draw the lines by clicking the points in the opengl window
// User can remove the lines by pressing the right mouse button

#include "stdafx.h"

#include <string.h>
#include <GL/glut.h>
#include "math.h"

float rotate =0.0;
float start = 0.0;
float z_dep = 0.0;

int poi_size = 0;
int poi_arr[100][2];
int poi_pattern[100];
int m_x = 0;
int m_y = 0;

int m_pattern = 0;
const int max_x = 1000;
const int max_y = 800;

int rubber_band_on = 0;
int pattern=0;

int down_flag = 0;
void *font = GLUT_BITMAP_TIMES_ROMAN_24;
void *fonts[] =
{
GLUT_BITMAP_9_BY_15,
GLUT_BITMAP_TIMES_ROMAN_10,
GLUT_BITMAP_TIMES_ROMAN_24
};

void selectFont(int newfont)
{
font = fonts[newfont];
glutPostRedisplay();
}

int get_pattern(int cx,int cy) {
float y = max_y-10;
float x = max_x-10;

for(int cnt=0;cnt<7;cnt++) {
if (cx<x && cx>(x-120) && cy<y && cy>(y-30)) {
return cnt+1;
}
y-=30;
}
return 0;
}

void set_pattern(int pattern) {
switch(pattern) {
case 0: glLineStipple(1,0xffff); break;
case 1: glLineStipple(1,0x00ff); break;
case 2: glLineStipple(1,0xffff); break;
case 3: glLineStipple(1,0x0c0f); break;
case 4: glLineStipple(2,0x0c0f); break;
case 5: glLineStipple(1,0xaaaa); break;
case 6: glLineStipple(3,0xaaaa); break;
default: glLineStipple(2,0xaaaa); break;
}
}

void draw_pallet() {
float y = max_y-10;
float x = max_x-10;
glLineStipple(1,0xffff);

// two vertical lines
glBegin(GL_LINES);
glVertex2f(x,y);
glVertex2f(x,y-180);
glVertex2f(x-120,y);
glVertex2f(x-120,y-180);

glEnd();
// several horizontal lines
for(int cnt=0;cnt<7;cnt++) {
glLineStipple(1,0xffff);
glBegin(GL_LINES);
glVertex2f(x,y);
glVertex2f(x-120,y);
glEnd();

if(cnt!=6) {
set_pattern(cnt+1);
glBegin(GL_LINES);
glVertex2f(x-20,y-10);
glVertex2f(x-100,y-10);
glEnd();
}
y-=30;
}

}

void myinit() {
glEnable(GL_LINE_STIPPLE);

}

void drawCircle(float radius, float x1, float y1)
{
float angle = 0;
float x2,y2,cx,cy,fx,fy;
int cache = 0;
glBegin(GL_LINES);
for (angle = 0; angle < 360; angle+=1.0) {
float rad_angle = angle * 3.14 / 180;
x2 = x1+radius * sin((double)rad_angle);
y2 = y1+radius * cos((double)rad_angle);
if (cache) {
glVertex2f(cx,cy);
glVertex2f(x2,y2);
} else {
fx = x2;
fy = y2;
}
cache = 1;
cx = x2;
cy = y2;
}
glVertex2f(x2,y2);
glVertex2f(fx,fy);

glEnd();
}


void tick(void)
{
//glutPostRedisplay();
}

void output(int x, int y, char *string)
{
int len, i;

glRasterPos2f(x, y);
len = (int) strlen(string);
for (i = 0; i < len; i++) {
glutBitmapCharacter(font, string[i]);
}
}


void display(void)
{
// Show the X and Y coordinate location of the mouse
glClear(GL_COLOR_BUFFER_BIT);
char x_coord[10];
sprintf(x_coord,"X:%d",m_x);
char y_coord[10];
sprintf(y_coord,"Y:%d",m_y);
output(0, 24, x_coord);
output(100, 24, y_coord);

draw_pallet();

// Draw the lines created by user
int i=0;
for(i=0; i<poi_size-1; i+=2) {
set_pattern(poi_pattern[i]);
glBegin(GL_LINES);
glVertex2f(poi_arr[i][0],poi_arr[i][1]);
glVertex2f(poi_arr[i+1][0],poi_arr[i+1][1]);
glEnd();
}
if (rubber_band_on && (poi_size%2==1)) {
set_pattern(m_pattern);
glBegin(GL_LINES);
glVertex2f(poi_arr[i][0],poi_arr[i][1]);
glVertex2f(m_x,m_y);
glEnd();
}

glEnd();

set_pattern(0);
// Draw small circles at the line start ane end point
for(int i=0; i<poi_size; i++) {
drawCircle(2,poi_arr[i][0],poi_arr[i][1]);
}
glutSwapBuffers();
}

void handleKeypress(unsigned char key, int x, int y) {
switch (key) {
case 27: //Escape key
exit(0);
}
}

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

// the mouse callback function:
void mouse_move(int x, int y)
{
m_x = x;
m_y = y;
display();
}

// the mouse callback function:
void mouse(int button, int state, int x, int y)
{
m_x = x;
m_y = y;

switch (button) {
case GLUT_RIGHT_BUTTON:
if (state == GLUT_DOWN) {
// glutIdleFunc(spinDisplay);
}
if (state == GLUT_UP) {
if (poi_size>0) {
poi_size-=2;
}
rubber_band_on = 0;
glutIdleFunc(NULL);
}
break;

case GLUT_LEFT_BUTTON:
rubber_band_on = 1;
if (state == GLUT_DOWN) {
down_flag = 1;
}
if (state == GLUT_UP) {
if(down_flag) {
int pattern = get_pattern(x,y);
if (pattern) {
m_pattern = pattern;
} else {
poi_arr[poi_size][0]=x;
poi_arr[poi_size][1]=y;
poi_pattern[poi_size] = m_pattern;
poi_size++;
}
down_flag = 0;
}
glutIdleFunc(NULL);
}
break;

default:
break;
}
display();
}

int main(int argc, char **argv)
{
int i, msg_submenu, color_submenu;

glutInit(&argc, argv);
for (i = 1; i < argc; i++) {
if (!strcmp(argv[i], "-mono")) {
font = GLUT_BITMAP_9_BY_15;
}
}
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(1000, 800);
glutCreateWindow("OPENGL LINE DRAWING");
glClearColor(0.0, 0.0, 0.0, 1.0);

myinit();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutIdleFunc(tick);
glutKeyboardFunc(handleKeypress);
glutMouseFunc(mouse);
glutMotionFunc(mouse_move);
glutPassiveMotionFunc(mouse_move);

glutMainLoop();
return 0; /* ANSI C requires main to return int. */
}


Interactive circle drawing




Below program will let you draw the circle wherever you want and of whatever radius you want it to be.


// This program is for line drawing using opengl 
// User cn draw the lines by clicking the points in the opengl window
// User can remove the lines by pressing the right mouse button

#include "stdafx.h"

#include <string.h>
#include <GL/glut.h>
#include "math.h"

float rotate =0.0;
float start = 0.0;
float z_dep = 0.0;

int poi_size = 0;
int poi_arr[100][2];
float rad_arr[50];
int m_x = 0;
int m_y = 0;

int rubber_band_on = 0;

int down_flag = 0;
void *font = GLUT_BITMAP_TIMES_ROMAN_24;
void *fonts[] =
{
GLUT_BITMAP_9_BY_15,
GLUT_BITMAP_TIMES_ROMAN_10,
GLUT_BITMAP_TIMES_ROMAN_24
};

void selectFont(int newfont)
{
font = fonts[newfont];
glutPostRedisplay();
}

void drawCircle(float radius, float x1, float y1)
{
float angle = 0;
float x2,y2,cx,cy,fx,fy;
int cache = 0;
glBegin(GL_LINES);
for (angle = 0; angle < 360; angle+=1.0) {
float rad_angle = angle * 3.14 / 180;
x2 = x1+radius * sin((double)rad_angle);
y2 = y1+radius * cos((double)rad_angle);
if (cache) {
glVertex2f(cx,cy);
glVertex2f(x2,y2);
} else {
fx = x2;
fy = y2;
}
cache = 1;
cx = x2;
cy = y2;
}
glVertex2f(x2,y2);
glVertex2f(fx,fy);

glEnd();
}


void tick(void)
{
//glutPostRedisplay();
}

void output(int x, int y, char *string)
{
int len, i;

glRasterPos2f(x, y);
len = (int) strlen(string);
for (i = 0; i < len; i++) {
glutBitmapCharacter(font, string[i]);
}
}

float calculate_radius(int x1,int y1) {
int x_diff = m_x - x1;
int y_diff = m_y - y1;
if(x_diff<0) {
x_diff *= -1;
}
if(y_diff<0) {
y_diff *= -1;
}
float mag = x_diff*x_diff + y_diff*y_diff;
float rad = sqrt(mag);
return rad;
}

void display(void)
{
// Show the X and Y coordinate location of the mouse
glClear(GL_COLOR_BUFFER_BIT);
char x_coord[10];
sprintf(x_coord,"X:%d",m_x);
char y_coord[10];
sprintf(y_coord,"Y:%d",m_y);
output(0, 24, x_coord);
output(100, 24, y_coord);

// Draw the circles at the existing positions
for(int i=0; i<poi_size; i+=2) {
int rad_index = (int)(i/2);
float rad = rad_arr[rad_index];
if (rad>1) {
drawCircle(rad,poi_arr[i][0],poi_arr[i][1]);
}
}

glutSwapBuffers();
}

void handleKeypress(unsigned char key, int x, int y) {
switch (key) {
case 27: //Escape key
exit(0);
}
}

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

// the mouse callback function:
void mouse_move(int x, int y)
{
m_x = x;
m_y = y;
if (rubber_band_on) {
float rd = calculate_radius(poi_arr[poi_size-1][0],poi_arr[poi_size-1][1]);
rad_arr[poi_size/2] = rd;
}
display();
}

// the mouse callback function:
void mouse(int button, int state, int x, int y)
{
m_x = x;
m_y = y;

switch (button) {
case GLUT_RIGHT_BUTTON:
if (state == GLUT_DOWN) {
// glutIdleFunc(spinDisplay);
}
if (state == GLUT_UP) {
glutIdleFunc(NULL);
}
break;
case GLUT_LEFT_BUTTON:
if (state == GLUT_DOWN) {
down_flag = 1;
}
if (state == GLUT_UP) {
if(down_flag) {
poi_arr[poi_size][0]=x;
poi_arr[poi_size][1]=y;
poi_size++;
down_flag = 0;
rubber_band_on = !rubber_band_on;
}
glutIdleFunc(NULL);
}
break;

default:
break;
}

if (rubber_band_on && poi_size>0) {
float rd = calculate_radius(poi_arr[poi_size-1][0],poi_arr[poi_size-1][1]);
rad_arr[poi_size/2] = rd;
}
display();
}

int main(int argc, char **argv)
{
int i, msg_submenu, color_submenu;

glutInit(&argc, argv);
for (i = 1; i < argc; i++) {
if (!strcmp(argv[i], "-mono")) {
font = GLUT_BITMAP_9_BY_15;
}
}
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(1000, 800);
glutCreateWindow("OPENGL CIRCLE DRAWING");
glClearColor(0.0, 0.0, 0.0, 1.0);

glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutIdleFunc(tick);
glutKeyboardFunc(handleKeypress);
glutMouseFunc(mouse);
glutMotionFunc(mouse_move);
glutPassiveMotionFunc(mouse_move);

glutMainLoop();
return 0; /* ANSI C requires main to return int. */
}


Interactive Line drawing in openGL



This is simple program based on the mouse inputs.
Using mouse inputs user can draw the lines in the opengl window.
Since the world space is same as that of the device space we dont have to worry about the
convertion here and that makes this program simple.

Still in the 2D world. :-)

// This program is for line drawing using opengl 
// User cn draw the lines by clicking the points in the opengl window
// User can remove the lines by pressing the right mouse button

#include "stdafx.h"

#include <string.h>
#include <GL/glut.h>
#include "math.h"

float rotate =0.0;
float start = 0.0;
float z_dep = 0.0;

int poi_size = 0;
int poi_arr[100][2];
int m_x = 0;
int m_y = 0;

int rubber_band_on = 0;

int down_flag = 0;
void *font = GLUT_BITMAP_TIMES_ROMAN_24;
void *fonts[] =
{
GLUT_BITMAP_9_BY_15,
GLUT_BITMAP_TIMES_ROMAN_10,
GLUT_BITMAP_TIMES_ROMAN_24
};

void selectFont(int newfont)
{
font = fonts[newfont];
glutPostRedisplay();
}

void drawCircle(float radius, float x1, float y1)
{
float angle = 0;
float x2,y2,cx,cy,fx,fy;
int cache = 0;
glBegin(GL_LINES);
for (angle = 0; angle < 360; angle+=1.0) {
float rad_angle = angle * 3.14 / 180;
x2 = x1+radius * sin((double)rad_angle);
y2 = y1+radius * cos((double)rad_angle);
if (cache) {
glVertex2f(cx,cy);
glVertex2f(x2,y2);
} else {
fx = x2;
fy = y2;
}
cache = 1;
cx = x2;
cy = y2;
}
glVertex2f(x2,y2);
glVertex2f(fx,fy);

glEnd();
}


void tick(void)
{
glutPostRedisplay();
}

void output(int x, int y, char *string)
{
int len, i;

glRasterPos2f(x, y);
len = (int) strlen(string);
for (i = 0; i < len; i++) {
glutBitmapCharacter(font, string[i]);
}
}

void display(void)
{
// Show the X and Y coordinate location of the mouse
glClear(GL_COLOR_BUFFER_BIT);
char x_coord[10];
sprintf(x_coord,"X:%d",m_x);
char y_coord[10];
sprintf(y_coord,"Y:%d",m_y);
output(0, 24, x_coord);
output(100, 24, y_coord);

// Draw the lines created by user
glBegin(GL_LINES);
for(int i=0; i<poi_size; i++) {
glVertex2f(poi_arr[i][0],poi_arr[i][1]);
}
if (rubber_band_on && (poi_size%2==1)) {
glVertex2f(m_x,m_y);
}

glEnd();

// Draw small circles at the line start ane end point
for(int i=0; i<poi_size; i++) {
drawCircle(2,poi_arr[i][0],poi_arr[i][1]);
}
glutSwapBuffers();
}

void handleKeypress(unsigned char key, int x, int y) {
switch (key) {
case 27: //Escape key
exit(0);
}
}

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

// the mouse callback function:
void mouse_move(int x, int y)
{
m_x = x;
m_y = y;
display();
}

// the mouse callback function:
void mouse(int button, int state, int x, int y)
{
m_x = x;
m_y = y;

switch (button) {
case GLUT_RIGHT_BUTTON:
if (state == GLUT_DOWN) {
// glutIdleFunc(spinDisplay);
}
if (state == GLUT_UP) {
if (poi_size>0) {
poi_size-=2;
}
rubber_band_on = 0;
glutIdleFunc(NULL);
}
break;
case GLUT_LEFT_BUTTON:
rubber_band_on = 1;
if (state == GLUT_DOWN) {
down_flag = 1;
}
if (state == GLUT_UP) {
if(down_flag) {
poi_arr[poi_size][0]=x;
poi_arr[poi_size][1]=y;
poi_size++;
down_flag = 0;
}
glutIdleFunc(NULL);
}
break;

default:
break;
}
display();
}

int main(int argc, char **argv)
{
int i, msg_submenu, color_submenu;

glutInit(&argc, argv);
for (i = 1; i < argc; i++) {
if (!strcmp(argv[i], "-mono")) {
font = GLUT_BITMAP_9_BY_15;
}
}
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(1000, 800);
glutCreateWindow("OPENGL LINE DRAWING");
glClearColor(0.0, 0.0, 0.0, 1.0);

glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutIdleFunc(tick);
glutKeyboardFunc(handleKeypress);
glutMouseFunc(mouse);
glutMotionFunc(mouse_move);
glutPassiveMotionFunc(mouse_move);

glutMainLoop();
return 0; /* ANSI C requires main to return int. */
}


Wednesday, May 18, 2011

Mouse programming in opengl


Hushh.. Finally I could get the mouse working in my opengl programs.
Here is the program which will let you use the mouse to enter the coordinates in opengl window. This is very useful template program to do various graphics assignment.


// text1.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

#include <string.h>
#include <GL/glut.h>

float rotate =0.0;
float start = 0.0;
float z_dep = 0.0;

int poi_size = 0;
int poi_arr[100][2];
int m_x = 0;
int m_y = 0;

int rubber_band_on = 0;

int down_flag = 0;
void *font = GLUT_BITMAP_TIMES_ROMAN_24;
void *fonts[] =
{
GLUT_BITMAP_9_BY_15,
GLUT_BITMAP_TIMES_ROMAN_10,
GLUT_BITMAP_TIMES_ROMAN_24
};

void selectFont(int newfont)
{
font = fonts[newfont];
glutPostRedisplay();
}


void selectColor(int color)
{
switch (color) {
case 1:
glColor3f(0.0, 1.0, 0.0);
break;
case 2:
glColor3f(1.0, 0.0, 0.0);
break;
case 3:
glColor3f(1.0, 1.0, 1.0);
break;
}
glutPostRedisplay();
}

void tick(void)
{
glutPostRedisplay();
}

void output(int x, int y, char *string)
{
int len, i;

glRasterPos2f(x, y);
len = (int) strlen(string);
for (i = 0; i < len; i++) {
glutBitmapCharacter(font, string[i]);
}
}

void display(void)
{
// Show the X and Y coordinate location of the mouse
glClear(GL_COLOR_BUFFER_BIT);
char x_coord[10];
sprintf(x_coord,"X:%d",m_x);
char y_coord[10];
sprintf(y_coord,"Y:%d",m_y);
output(0, 24, x_coord);
output(100, 24, y_coord);

// Draw the lines created by user
glBegin(GL_LINE_STRIP);
for(int i=0; i<poi_size; i++) {
glVertex2f(poi_arr[i][0],poi_arr[i][1]);
}
if (rubber_band_on) {
glVertex2f(m_x,m_y);
}

glEnd();

glutSwapBuffers();
}

void handleKeypress(unsigned char key, int x, int y) {
switch (key) {
case 27: //Escape key
exit(0);
}
}

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

// the mouse callback function:
void mouse_move(int x, int y)
{
m_x = x;
m_y = y;
display();
}

// the mouse callback function:
void mouse(int button, int state, int x, int y)
{
m_x = x;
m_y = y;

switch (button) {
case GLUT_RIGHT_BUTTON:
if (state == GLUT_DOWN) {
// glutIdleFunc(spinDisplay);
}
if (state == GLUT_UP) {
if (rubber_band_on == 0) {
poi_size--;
}
rubber_band_on = 0;
glutIdleFunc(NULL);
}
break;
case GLUT_LEFT_BUTTON:
rubber_band_on = 1;
if (state == GLUT_DOWN) {
down_flag = 1;
}
if (state == GLUT_UP) {
if(down_flag) {
poi_arr[poi_size][0]=x;
poi_arr[poi_size][1]=y;
poi_size++;
down_flag = 0;
}
glutIdleFunc(NULL);
}
break;

default:
break;
}
display();
}

int main(int argc, char **argv)
{
int i, msg_submenu, color_submenu;

glutInit(&argc, argv);
for (i = 1; i < argc; i++) {
if (!strcmp(argv[i], "-mono")) {
font = GLUT_BITMAP_9_BY_15;
}
}
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(1000, 800);
glutCreateWindow("GLUT Mouse example");
glClearColor(0.0, 0.0, 0.0, 1.0);

glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutIdleFunc(tick);
glutKeyboardFunc(handleKeypress);
glutMouseFunc(mouse);
glutMotionFunc(mouse_move);
glutPassiveMotionFunc(mouse_move);

glutMainLoop();
return 0; /* ANSI C requires main to return int. */
}


Friday, March 25, 2011

OpenGL Program for sine wave


// tree.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <iostream>
#include <stdlib.h> //Needed for "exit" function
#include "math.h"
#include <windows.h>


//Include OpenGL header files, so that we can use OpenGL
#ifdef __APPLE__
#include <OpenGL/OpenGL.h>
#include <GLUT/glut.h>
#else
#include "glut.h"
#endif

using namespace std;

float rotate =0.0;

float start = 0.0;
void drawSinWave()
{
float radius = 7.5;
float x2=0,y2,cx,cy,fx,fy;
float cos_y,cache_cos_y;
int cache = 0;
start += 1.0;
if(start >360) {
start = 0;
}
glBegin(GL_LINES);
float angle = 0;
for(angle=start; ; angle+=1.0) {
if(angle>1020) {
break;
angle = 0.0;
}
float rad_angle = angle * 3.14 / 180;
x2 = x2+0.1;
y2 = radius * sin((double)rad_angle);
cos_y = radius * sin((double)-rad_angle);
if (cache) {
glVertex2f(cx,cy);
glVertex2f(x2,y2);

glVertex2f(cx,cache_cos_y);
glVertex2f(x2,cos_y);

} else {
fx = x2;
fy = y2;
}
cache = 1;
cx = x2;
cy = y2;
cache_cos_y = cos_y;
}
glEnd();
}

void display(void) {
glClearColor (0.0,0.0,0.0,1.0);
glClear (GL_COLOR_BUFFER_BIT);
glLineWidth(10);
glLoadIdentity();
glTranslatef(-40,0,-30);
glColor3f(1,0,0);

drawSinWave();
glutSwapBuffers();
}

void reshape (int w, int h) {
glViewport (0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gluPerspective (60, (GLfloat)w / (GLfloat)h, 0.1, 100.0);
glMatrixMode (GL_MODELVIEW);
}

void keyboard(unsigned char key, int x, int y)
{
switch (key) {
case 27:
exit(0);
break;
}
}

int main (int argc, char **argv) {
glutInit (&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE);
glutInitWindowSize (1200, 800);
glutInitWindowPosition (0, 0);
glutCreateWindow ("A Sine wave");

glutDisplayFunc (display);
glutIdleFunc (display);
glutReshapeFunc (reshape);
glutKeyboardFunc (keyboard);
glutMainLoop ();
return 0;
}

Thursday, March 24, 2011

shannon fano coding program in C


This is program for shanno fano coding .
It is a technique for constructing a prefix code based on a set of symbols and their probabilities (estimated or measured). It is suboptimal in the sense that it does not achieve the lowest possible expected code word length like Huffman coding; however unlike Huffman coding, it does guarantee that all code word lengths are within one bit of their theoretical ideal − logP(x).

// shannon.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include<stdio.h>

int g_level = 0;
void shannon(int start,int end,int arr[20], char code[20][20],int level) {
int i=start;
int j=end;
int isum = arr[i],jsum = arr[j];

if(level>g_level) {
g_level = level;
}
while(i<(j-1)) {
while(isum>jsum && i<(j-1)) {
j--;
jsum += arr[j];
}
while(isum<jsum && i<(j-1)) {
i++;
isum += arr[i];
}
}

if(i==start) {
code[start][level]='0';
} else if((i-start)>=1) {
for(int k=start;k<=i;++k)
code[k][level] = '0';

shannon(start,i,arr,code,level+1);
}
if(j==end) {
code[end][level]='1';
} else if((end-j)>=1) {
for(int k=j;k<=end;++k)
code[k][level] = '1';

shannon(j,end,arr,code,level+1);
}
}

int _tmain(int argc, _TCHAR* argv[])
{
int arr[20];
int n,i,j;
printf("Enter the number of symbols :");
scanf("%d",&n);

// Take the symbols and sort them as user enters them using insertion sort
for(i=0; i<n; ++i) {
int s;
printf("Enter symbol frquency : ");
scanf("%d",&s);
j=i;
while(j && arr[j-1]<s) {
arr[j] = arr[j-1];
j--;
}
arr[j] = s;
}

char code[20][20];

for(i=0; i<n; ++i) {
// Mark row as invalid
for(j=0;j<n;j++) {
code[i][j] = 'X';
}
}

shannon(0,n-1,arr,code,0);

printf("\n\n DATA CODE\n");
// Print the data and code
for(i=0; i<n; ++i) {
printf("\n %4d : ",arr[i]);
for(j=0; j<=g_level; j++) {
if(code[i][j]!='X')
printf("%c",code[i][j]);
}
}

printf("\n\n");
return 0;
}


Wednesday, March 23, 2011

Huffman coding with Opengl


// THis program will output the huffman tree in graphics window and will show the huffman code in command window

// huff.cpp : Defines the entry point for the console application.
//


#include "stdafx.h"
#include <iostream>
#include <stdlib.h> //Needed for "exit" function
#include "math.h"

//Include OpenGL header files, so that we can use OpenGL
#ifdef __APPLE__
#include <OpenGL/OpenGL.h>
#include <GLUT/glut.h>
#else
#include "glut.h"
#endif

typedef struct node {
char name[20]; // name of the node
float data;
struct node* right;
struct node* left;
struct node* parent;
struct node* next;
}NODE;

NODE* root = NULL;

using namespace std;

void display_list(NODE* head) {
if(head) {
cout<<"\nList contents:\n";
NODE* temp = head;
while(temp) {
cout<<"Node : "<<temp->name<<" probability:"<<temp->data<<endl;
temp = temp->next;
}
} else {
cout<<"\nEmpty List";
}
}

void find_smallest(NODE* head,NODE** smallest1, NODE** smallest2) {
*smallest1 = NULL;
*smallest2 = NULL;
NODE* t = head;
while(t) {
// Skip the nodes who has parent
if(t->parent) {
t = t->next;
continue;
}

if(!*smallest1) {
*smallest1 = t;
} else if(!*smallest2) {
*smallest2 = t;
} else if(t->data < (*smallest1)->data) {
if ((*smallest1)->data < (*smallest2)->data) {
*smallest2 = *smallest1;
}
*smallest1 = t;
} else if(t->data < (*smallest2)->data) {
*smallest2 = t;
} else {
// Do nothing
}

if(*smallest1 && *smallest2) {
if((*smallest1)->data > (*smallest2)->data) {
NODE* temp = *smallest1;
*smallest1 = *smallest2;
*smallest2 = temp;
}
}
t = t->next;
}
}

void add_element(NODE** head,NODE** e) {
if(!*head) {
*head = *e;
} else {
NODE* t = *head;
while(t->next!=NULL) {
t = t->next;
}
t->next = *e;
}
}

void tree_traversal(NODE* root,char code[20]) {
if(!root) {
return;
}
//cout<<"\n NODE : "<<root->name<<" prob: "<<root->data;
if(root->left==NULL && root->right==NULL) {
cout<<" \nNODE : "<<root->name<<" prob : "<<root->data<<" code: "<<code;
return;
}
int len = strlen(code);
if(root->left) {
code[len]='1';
code[len+1]='\0';
tree_traversal(root->left,code);
}
if(root->right) {
code[len]='0';
code[len+1]='\0';
tree_traversal(root->right,code);
}
}

void drawCircle(float segments, float radius, float sx, float sy)
{
float theta = 2 * 3.1415926 / segments;
float tan_factor = tanf(theta);
float radial_factor = cosf(theta);
float x = radius;
float y = 0;

int cache_pt = 0;
double cache_x;
double cache_y;

glBegin(GL_LINES);
for (int ii = 0; ii < segments; ii++) {
if(!cache_pt) {
cache_x = x+sx;
cache_y = y+sy;
cache_pt = 1;
} else {
//glVertex2f(cache_x,cache_y);
glVertex2f(x + sx, y + sy);
cache_x = x+sx;
cache_y = y+sy;
}
float tx = -y;
float ty = x;
x += tx * tan_factor;
y += ty * tan_factor;
x *= radial_factor;
y *= radial_factor;
}
glEnd();
}

void draw_line(float x1,float y1,float x2, float y2) {
glBegin(GL_LINES);
glVertex2f(x1,y1);
glVertex2f(x2,y2);
glEnd();
}

void draw_text(char* text,float x, float y) {
GLvoid *font_style = GLUT_BITMAP_TIMES_ROMAN_24;
glRasterPos3f(x, y, 0);
for (int i = 0; text[i] != '\0'; i++){
glutBitmapCharacter(font_style, text[i]);
}
}

void drawNode(NODE* t_root,float x1,float y1,int level) {
if (t_root==NULL) {
return;
}
float segments = 25;
float radius = 1.0;
float left_angle = 245;
float right_angle = 115;
float branch_length = 12 - level*2.5;
float angle_change = 20;

// Draw the current circle

drawCircle(segments,radius,x1,y1);

char buff[5];
//itoa(t_root->name,buff,10);
draw_text(t_root->name,x1,y1);

if(t_root->left) {
// Draw the Left circle
float angle = left_angle - level*angle_change;
double radian = angle*3.14/180;
float m = (double)tan((double)radian);
float x2 = x1 + branch_length * sin((double) radian);
float y2 = y1 + branch_length * cos((double) radian);
drawNode(t_root->left,x2,y2,level+1);
draw_line(x1,y1,x2,y2);

float x3 = (x1+x2) / 2;
float y3 = (y1+y2) / 2;
char label[2];
label[0]='1';
label[1]='\0';
draw_text(label,x3,y3);
}

if(t_root->right) {
// Draw the Right circle
float angle = right_angle + level*angle_change;
float radian = angle*3.14/180;
float m = (double)tan((double)radian);
float x2 = x1 + branch_length * sin((double) radian);
float y2 = y1 + branch_length * cos((double) radian);
drawNode(t_root->right,x2,y2,level+1);
draw_line(x1,y1,x2,y2);

float x3 = (x1+x2) / 2;
float y3 = (y1+y2) / 2;
char label[2];
label[0]='0';
label[1]='\0';
draw_text(label,x3,y3);

}

}


void display(void) {
glClearColor (0.0,0.0,0.0,1.0);
glClear (GL_COLOR_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0,10,-30);
glColor3f(1,1,1);

drawNode(root,0,0,0);

glutSwapBuffers();
}


void reshape (int w, int h) {
glViewport (0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gluPerspective (60, (GLfloat)w / (GLfloat)h, 0.1, 100.0);
glMatrixMode (GL_MODELVIEW);
}

void keyboard(unsigned char key, int x, int y)
{
switch (key) {
case 27:
exit(0);
break;
}
}

int _tmain(int argc, char** argv)
{
NODE* list = NULL;
float arr[10];
int n;
cout<<"Enter n:";
cin>>n;
for(int i=0; i<n; i++) {
cin>>arr[i];
// Create a new node and append it to the list
NODE* current = new NODE;
current->data = arr[i];
current->next = NULL;
current->left = NULL;
current->right = NULL;
current->parent = NULL;
current->name[0] = 65+i; current->name[1] = '\0';

// Appending the node to the list
add_element(&list,&current);
}

// Display the nodes entered by the user along with their probabilities
display_list(list);


while(1) {

// Find the 2 smallest elements from the list
NODE* smallest1 = NULL;
NODE* smallest2 = NULL;
find_smallest(list,&smallest1,&smallest2);

if(!smallest2) {
root = smallest1;
break;
}

float small1 = smallest1->data;
float small2 = smallest2->data;
NODE* current = new NODE;
current->data = small1 + small2;
current->left = smallest1;
current->right = smallest2;
current->parent = NULL;
current->next = NULL;
strcpy(current->name,smallest1->name);
strcat(current->name,smallest2->name);

smallest1->parent = current;
smallest2->parent = current;

add_element(&list,&current);

}

cout<<"\n\nHuffman code :\n\n";
char code[20];
code[0]='\0';
tree_traversal(root,code);

// OPENGL Drawing functions
glutInit (&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE);
glutInitWindowSize (1200, 800);
glutInitWindowPosition (0, 0);
glutCreateWindow ("A Binary search tree");

// Register function pointers to the drawing framework
glutDisplayFunc (display);
glutIdleFunc (display);
glutReshapeFunc (reshape);
glutKeyboardFunc (keyboard);
glutMainLoop ();

cout<<endl;
return 0;
}


Programming in OpenGL

This is for All my dear friends who are interested in doing programming in openGL.

All you need is Visual studio. and library files for openGL.

1. Create a new project and select win32 cosole Application .
2. Copy any of my program as it is into the main source file
3. Search for glut.h and glut32.lib and glut32.dll on internet and copy them in your windows folders. For example you can copy glut32.dll and glut32.lib in your windows system32 folder. you can copy glut.h in your program files/visual studio/vc/include folder etc.

4. Now compile and run your program.

Now start reading some nice book of openGL. Understand the concepts and write small small programs.

Welcome to the amazing world of openGL :-)

circle drawing in openGL


// tree.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <iostream>
#include <stdlib.h> //Needed for "exit" function
#include "math.h"

//Include OpenGL header files, so that we can use OpenGL
#ifdef __APPLE__
#include <OpenGL/OpenGL.h>
#include <GLUT/glut.h>
#else
#include "glut.h"
#endif

using namespace std;


void drawCircle(float radius, float x1, float y1)
{
float angle = 0;
float x2,y2,cx,cy,fx,fy;
int cache = 0;
glBegin(GL_LINES);
for (angle = 0; angle < 360; angle+=1.0) {
float rad_angle = angle * 3.14 / 180;
x2 = radius * sin((double)rad_angle);
y2 = radius * cos((double)rad_angle);
if (cache) {
glVertex2f(cx,cy);
glVertex2f(x2,y2);
} else {
fx = x2;
fy = y2;
}
cache = 1;
cx = x2;
cy = y2;
}
glVertex2f(x2,y2);
glVertex2f(fx,fy);

glEnd();
}

void display(void) {
glClearColor (0.0,0.0,0.0,1.0);
glClear (GL_COLOR_BUFFER_BIT);
glLoadIdentity();
glTranslatef(-10,0,-30);
glColor3f(1,0,0);
drawCircle(10,0,0);
glutSwapBuffers();
}

void reshape (int w, int h) {
glViewport (0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gluPerspective (60, (GLfloat)w / (GLfloat)h, 0.1, 100.0);
glMatrixMode (GL_MODELVIEW);
}

void keyboard(unsigned char key, int x, int y)
{
switch (key) {
case 27:
exit(0);
break;
}
}

int main (int argc, char **argv) {
glutInit (&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE);
glutInitWindowSize (1200, 800);
glutInitWindowPosition (0, 0);
glutCreateWindow ("A Pendulum");

glutDisplayFunc (display);
glutIdleFunc (display);
glutReshapeFunc (reshape);
glutKeyboardFunc (keyboard);
glutMainLoop ();
return 0;
}

Program for huffman coding

// huff.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include

typedef struct node {
char name[20]; // name of the node
float data;
struct node* right;
struct node* left;
struct node* parent;
struct node* next;
}NODE;

using namespace std;

void display_list(NODE* head) {
if(head) {
cout<<"\nList contents:\n";
NODE* temp = head;
while(temp) {
cout<<"Node : "<name<<" probability:"<data< temp = temp->next;
}
} else {
cout<<"\nEmpty List";
}
}

void find_smallest(NODE* head,NODE** smallest1, NODE** smallest2) {
*smallest1 = NULL;
*smallest2 = NULL;
NODE* t = head;
while(t) {
// Skip the nodes who has parent
if(t->parent) {
t = t->next;
continue;
}

if(!*smallest1) {
*smallest1 = t;
} else if(!*smallest2) {
*smallest2 = t;
} else if(t->data < (*smallest1)->data) {
if ((*smallest1)->data < (*smallest2)->data) {
*smallest2 = *smallest1;
}
*smallest1 = t;
} else if(t->data < (*smallest2)->data) {
*smallest2 = t;
} else {
// Do nothing
}

if(*smallest1 && *smallest2) {
if((*smallest1)->data > (*smallest2)->data) {
NODE* temp = *smallest1;
*smallest1 = *smallest2;
*smallest2 = temp;
}
}
t = t->next;
}
}

void add_element(NODE** head,NODE** e) {
if(!*head) {
*head = *e;
} else {
NODE* t = *head;
while(t->next!=NULL) {
t = t->next;
}
t->next = *e;
}
}

void tree_traversal(NODE* root,char code[20]) {
if(!root) {
return;
}
//cout<<"\n NODE : "<name<<" prob: "<data;
if(root->left==NULL && root->right==NULL) {
cout<<" \nNODE : "<name<<" prob : "<data<<" code: "< return;
}
int len = strlen(code);
if(root->left) {
code[len]='1';
code[len+1]='\0';
tree_traversal(root->left,code);
}
if(root->right) {
code[len]='0';
code[len+1]='\0';
tree_traversal(root->right,code);
}
}


int _tmain(int argc, _TCHAR* argv[])
{
NODE* list = NULL;
float arr[10];
int n;
cout<<"Enter n:";
cin>>n;
for(int i=0; i cin>>arr[i];
// Create a new node and append it to the list
NODE* current = new NODE;
current->data = arr[i];
current->next = NULL;
current->left = NULL;
current->right = NULL;
current->parent = NULL;
current->name[0] = 65+i; current->name[1] = '\0';

// Appending the node to the list
add_element(&list,¤t);
}

// Display the nodes entered by the user along with their probabilities
display_list(list);

NODE* root = NULL;

while(1) {

// Find the 2 smallest elements from the list
NODE* smallest1 = NULL;
NODE* smallest2 = NULL;
find_smallest(list,&smallest1,&smallest2);

if(!smallest2) {
root = smallest1;
break;
}

float small1 = smallest1->data;
float small2 = smallest2->data;
NODE* current = new NODE;
current->data = small1 + small2;
current->left = smallest1;
current->right = smallest2;
current->parent = NULL;
current->next = NULL;
strcpy(current->name,smallest1->name);
strcat(current->name,smallest2->name);

smallest1->parent = current;
smallest2->parent = current;

add_element(&list,¤t);
//cout<<"\n\n LIST: \n\n";
//display_list(list);
}

cout<<"\n\nHuffman code :\n\n";
char code[20];
code[0]='\0';
tree_traversal(root,code);

cout< return 0;
}

OpenGL program for Pendulum

// tree.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include
#include //Needed for "exit" function
#include "math.h"

//Include OpenGL header files, so that we can use OpenGL
#ifdef __APPLE__
#include
#include
#else
#include "glut.h"
#endif

using namespace std;


float rot = 0;
float angle = 135;
float inc = 1.0;

void drawCircle(float segments, float radius, float sx, float sy)
{
float theta = 2 * 3.1415926 / segments;
float tan_factor = tanf(theta);
float radial_factor = cosf(theta);
float x = radius;
float y = 0;

int cache_pt = 0;
double cache_x;
double cache_y;

glBegin(GL_LINES);
for (int ii = 0; ii < segments; ii++) {
if(!cache_pt) {
cache_x = x+sx;
cache_y = y+sy;
cache_pt = 1;
} else {
//glVertex2f(cache_x,cache_y);
glVertex2f(x + sx, y + sy);
cache_x = x+sx;
cache_y = y+sy;
}
float tx = -y;
float ty = x;
x += tx * tan_factor;
y += ty * tan_factor;
x *= radial_factor;
y *= radial_factor;
}
glEnd();
}


void drawCircles(float x1,float y1,double angle) {
float segments = 25;
float radius = 1.0;
// Draw the original circle
drawCircle(segments,radius,x1,y1);

// Draw the pendulum circle
double radian = angle*3.14/180;
float m = (double)tan((double)radian);
float y2 = 10 * cos((double) radian);
float x2 = 10 * sin((double) radian);
drawCircle(segments,radius,x2,y2);

glBegin(GL_LINES);
glVertex2f(x1,y1);
glVertex2f(x2,y2);
glEnd();

}

void display(void) {
glClearColor (0.0,0.0,0.0,1.0);
glClear (GL_COLOR_BUFFER_BIT);
glLoadIdentity();
glTranslatef(-10,0,-30);
glColor3f(1,1,1);

if (angle>225) {
angle = 225;
inc = -inc;
}
if (angle<135) {
angle = 135;
inc = -inc;
}
angle += inc;
drawCircles(0,0,angle);
glutSwapBuffers();

}

void reshape (int w, int h) {
glViewport (0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gluPerspective (60, (GLfloat)w / (GLfloat)h, 0.1, 100.0);
glMatrixMode (GL_MODELVIEW);
}

void keyboard(unsigned char key, int x, int y)
{
switch (key) {
case 27:
exit(0);
break;
}
}

int main (int argc, char **argv) {
glutInit (&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE);
glutInitWindowSize (1200, 800);
glutInitWindowPosition (0, 0);
glutCreateWindow ("A Pendulum");

glutDisplayFunc (display);
glutIdleFunc (display);
glutReshapeFunc (reshape);
glutKeyboardFunc (keyboard);
glutMainLoop ();
return 0;
}

Binary search tree using opengl


// tree.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include
#include //Needed for "exit" function
#include "math.h"

//Include OpenGL header files, so that we can use OpenGL
#ifdef __APPLE__
#include
#include
#else
#include "glut.h"
#endif

using namespace std;

typedef struct treenode {
int data;
struct treenode* left;
struct treenode* right;
struct treenode* parent;
}TREENODE;

TREENODE* root = NULL;


void add_node(TREENODE** t_root, TREENODE** current) {

if(*t_root==NULL) {
*t_root = *current;
return;
}
if((*current)->data < (*t_root)->data) {
if((*t_root)->left==NULL) {
(*t_root)->left = (*current);
} else {
add_node(&((*t_root)->left),current);
}
} else {
if((*t_root)->right==NULL) {
(*t_root)->right = *current;
} else {
add_node(&((*t_root)->right),current);
}
}
}

void accept_tree(){
int n;
cout<<"\nCREATING BST: (enter 0 to finish)\n";
while(1) {
fflush(stdin);
cout<<"\nEnter node value: ";
cin>>n;
if(n==0) {
break;
}
TREENODE* current = new TREENODE;
current->data = n;
current->right = NULL;
current->left = NULL;
current->parent = NULL;

add_node(&root,¤t);
}
}

void inorder(TREENODE* root) {
if(root!=NULL) {
inorder(root->left);
cout<data;
inorder(root->right);
}
}

void preorder(TREENODE* root) {
if(root!=NULL) {
cout<data;
preorder(root->left);
preorder(root->right);
}
}

void postorder(TREENODE* root) {
if(root!=NULL) {
postorder(root->left);
postorder(root->right);
cout<data;
}
}


void drawCircle(float segments, float radius, float sx, float sy)
{
float theta = 2 * 3.1415926 / segments;
float tan_factor = tanf(theta);
float radial_factor = cosf(theta);
float x = radius;
float y = 0;

int cache_pt = 0;
double cache_x;
double cache_y;

glBegin(GL_LINES);
for (int ii = 0; ii < segments; ii++) {
if(!cache_pt) {
cache_x = x+sx;
cache_y = y+sy;
cache_pt = 1;
} else {
//glVertex2f(cache_x,cache_y);
glVertex2f(x + sx, y + sy);
cache_x = x+sx;
cache_y = y+sy;
}
float tx = -y;
float ty = x;
x += tx * tan_factor;
y += ty * tan_factor;
x *= radial_factor;
y *= radial_factor;
}
glEnd();
}

void draw_line(float x1,float y1,float x2, float y2) {
glBegin(GL_LINES);
glVertex2f(x1,y1);
glVertex2f(x2,y2);
glEnd();
}

void draw_text(char* text,float x, float y) {
GLvoid *font_style = GLUT_BITMAP_TIMES_ROMAN_24;
glRasterPos3f(x, y, 0);
for (int i = 0; text[i] != '\0'; i++){
glutBitmapCharacter(font_style, text[i]);
}
}

void drawNode(TREENODE* t_root,float x1,float y1,int level) {
if (t_root==NULL) {
return;
}
float segments = 25;
float radius = 1.0;
float left_angle = 245;
float right_angle = 115;
float branch_length = 12 - level*2.5;
float angle_change = 20;

// Draw the current circle

drawCircle(segments,radius,x1,y1);

char buff[5];
itoa(t_root->data,buff,10);
draw_text(buff,x1,y1);

if(t_root->left) {
// Draw the Left circle
float angle = left_angle - level*angle_change;
double radian = angle*3.14/180;
float m = (double)tan((double)radian);
float x2 = x1 + branch_length * sin((double) radian);
float y2 = y1 + branch_length * cos((double) radian);
drawNode(t_root->left,x2,y2,level+1);
draw_line(x1,y1,x2,y2);
}
if(t_root->right) {
// Draw the Right circle
float angle = right_angle + level*angle_change;
float radian = angle*3.14/180;
float m = (double)tan((double)radian);
float x2 = x1 + branch_length * sin((double) radian);
float y2 = y1 + branch_length * cos((double) radian);
drawNode(t_root->right,x2,y2,level+1);
draw_line(x1,y1,x2,y2);
}

}


void display(void) {
glClearColor (0.0,0.0,0.0,1.0);
glClear (GL_COLOR_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0,10,-30);
glColor3f(1,1,1);

drawNode(root,0,0,0);

glutSwapBuffers();
}

void reshape (int w, int h) {
glViewport (0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gluPerspective (60, (GLfloat)w / (GLfloat)h, 0.1, 100.0);
glMatrixMode (GL_MODELVIEW);
}

void keyboard(unsigned char key, int x, int y)
{
switch (key) {
case 27:
exit(0);
break;
}
}


int main (int argc, char **argv) {

accept_tree();
inorder(root);

// OPENGL Drawing functions
glutInit (&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE);
glutInitWindowSize (1200, 800);
glutInitWindowPosition (0, 0);
glutCreateWindow ("A Binary search tree");

// Register function pointers to the drawing framework
glutDisplayFunc (display);
glutIdleFunc (display);
glutReshapeFunc (reshape);
glutKeyboardFunc (keyboard);
glutMainLoop ();


return 0;
}