Thursday, May 19, 2011

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. */
}


No comments:

Post a Comment