REQUIREMENT SPECIFICATION
1. INTRODUCTION:
An editor which can be used to create and as well as edit images. Various tools are to be provided in order to accomplish the necessary tasks. A good user interface which can be used by people of varied age groups, computer knowledge.
2. OVERALL DESCRIPTION:
2.1. PROJECT PERSPECTIVE:
The project is done for fulfilling the requirements of 6th semester computer graphics lab with the subject code 06CSL67 under VTU, Belgaum.
2.2. PRODUCT FEATURES:
The project, graphical editor will contain tools such as pencil, eraser, spray, free polygon, different shapes such as oval, square, rectangle, rhombus, parallelogram and arrows in 4 directions namely right, left, down, top and a canvas to do the intended pictures.
2.3. USER CLASSES AND CHARACTERISTICS:
The editor may be used by people who have little computer knowledge like using keyboard and mouse. There is no need to know any computer programming knowledge. Age groups of 10-15 who would like make drawings and 15 and above who would like to use it for drawing flowcharts.
2.4. OPERATING ENVIRONMENT:
The software must run on windows platform like Windows XP and Windows Vista. It must co-exist with the rest of the software already installed on the system.
2.5. DESIGN AND IMPLEMENTATION CONSTRAINTS:
As this must be interactive software, timing should be good and the user should not be made to wait for long durations for the response. OpenGL API’s are to be used to implement the editor using VC++ as a tool and C or C++ as a programming language.
2.6. USER DOCUMENTATION:
A user manual is to be provided which elaborates on the usage of each tool and the associated constraints. It must be in English and should be in simple language.
3. SYSTEM FEATURES:
3.1. PENCIL:
To draw free hand sketches by using mouse and the picture should be drawn spontaneously.
3.2 ERASER:
To erase the drawn sketches.
3.3 SPRAY:
To emulate a spray –can which can take any color from the color palette.
3.4 BASIC SHAPES:
To draw flowcharts and other graphics using simple shapes.
4. EXTERNAL INTERFACE REQUIREMENTS:
4.1: USER INTERFACE:
It has to be very easy to use. Icons have to be provided for selection of tools. Color palette for color selection which shows many colors is to be provided.
4.2: HARDWARE INTERFACE:
Usage of mouse to select an icon and also to draw sketches is expected. Mouse will provide the co-ordinates to the program. A mouse with left and right button is used. Color Monitor with good resolution.
System : Intel
Frequency : 166 MHz
RAM : 16 MB
Disk Capacity : 2 MB
4.3: SOFTWARE INTERFACE:
Package should run on a windows platform which has the operating system namely WINDOWS 98/VISTA/XP. A compiler which can compile c++ using openGL API should be functional. Microsoft word is required to see the user manual.
5. OTHER NONFUNCTIONAL REQUIREMENTS:
5.1: PERFORAMNCE REQUIREMENTS:
As this is an interactive device, it should be fast in responding to the selection of the user. For pencil, eraser, spray user must get a feel that it is happening in real time.
5.2: SAFETY REQUIREMENTS:
It should not cause damage to user in any form. It should be perfectly safe even for the usage of children.
5.3: SECURITY REQUIREMENT:
It should not try to access the internet and download or upload any form of data.
5.4: SOFTWARE QUALITY ATTRIBUTES:
5.4.1: TESTABILITY: Software should be testable, to see if all features are working as specified.
5.4.2: RELIABILITY: It should be in a position to deliver the services as specified.
5.4.3: MAINTAINABILITY: over a course of time the software should be able to evolve to meet the needs of the user i.e. addition of new features must be possible.
5.4.4: REUASABILITY: It should be coded in such a way that it can be used for another project which is similar to the one working on.
5.4.5: PORTABILITY: Software should be able to perform in the same fashion on all windows platform such as 98 or XP or VISTA.
DATA DESIGN:
1:COLORS:
The colors for the color palette is stored in an 2D array.
float colors[][3]=
{
{0.0,0.0,0.0},
{0.0,0.0,0.0},
{0.0,0.0,1.0},
{0.0,1.0,0.5},
{1.0,0.0,0.0},
{1.0,0.0,1.0},
{1.0,1.0,0.0},
{1.0,1.0,1.0},
{0.5,0.5,0.5},
{0.22,0.08,0.69},
{0.64,0.94,0.0},
{0.05,0.36,0.65},
{0.0,0.7,0.7},
{0.03,0.054,0.45},
{0.8,0.2,0.4},
{0.9,0.9,1.0},
{0.0,0.4,0.0},
};
2: MASK:
The pattern used in polygon stippling is a 32*32bit array.
GLubyte mask []= {
0x92,0x93,0x90,0x91,0x96,0x97,0x94,0x95,0x9b,0x9a,0x99,0x98,0x9f,0x9e,0x9d,0x9c,
0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x89,0x88,0x8b,0x8a,0x8d,0x8c,0x8f,0x8e,
0xb6,0xb7,0xb4,0xb5,0xb2,0xb3,0xb0,0xb1,0xbf,0xbe,0xbd,0xbc,0xbb,0xba,0xb9,0xb8,
0xa4,0xa5,0xa6,0xa7,0xa0,0xa1,0xa2,0xa3,0xad,0xac,0xaf,0xae,0xa9,0xa8,0xab,0xaa,
0xdb,0xda,0xd9,0xd8,0xdf,0xde,0xdd,0xdc,0xd2,0xd3,0xd0,0xd1,0xd6,0xd7,0xd4,0xd5,
0xc9,0xc8,0xcb,0xca,0xcd,0xcc,0xcf,0xce,0xc0,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,
0xff,0xfe,0xfd,0xfc,0xfb,0xfa,0xf9,0xf8,0xf6,0xf7,0xf4,0xf5,0xf2,0xf3,0xf0,0xf1,
0xed,0xec,0xef,0xee,0xe9,0xe8,0xeb,0xea,0xe4,0xe5,0xe6,0xe7,0xe0,0xe1,0xe2,0xe3};
3: COLLECTED VERTICES:
In order to collect the vertices or the points that are clicked by the mouse on the canvas, there is a 2d array collected.
int collected[100][2]={0};
4: SELECTION OF TOOL:
Selection of any of the tools by the user is reflected in the funsel variable.
Each tool has been assigned a unique funsel value. Based on the funsel value, the required tool is activated.
5: GLOBAL VERTICES:
In order to store the vertices values so that it is available to all the functions.
double ga,gb,gc,gd,ge,gf;
6: OTHER VARIABLES:
Many variables have been used to store the states and they will be explained in the implementation part.
FUNCTIONS:
TEXT:
This function renders the string that is passed to it and uses the current attributes available.
void text(int x,int y,void *font,char *string)
{
char *c;
glRasterPos2d(x,y);
c=string;
while(*c!='\0')
{
glutBitmapCharacter(font, *c);
c++;
}
}
TEXT TOOL:
This tool uses text function to draw text. Keyboard function is used to get the ASCII value of the characters keyed in. Global variable g and h are used to store the mouse click position and every time g is incremented by 10 i.e. the size of the character so that the character do not overlap.
void subwindow1_keyboard (unsigned char key, int x, int y)
{
glColor3fv(colors[s]);
mykey=key;
g=g+10;
glRasterPos2d(g,h);
glutBitmapCharacter(GLUT_BITMAP_9_BY_15,key);
glutPostRedisplay ();
}
Spray:
This uses rand() function in the stdlib.h header file which generates a random number. By using the % operator it is seen to that the number stays within 30. As the spray has to be in a circular form a for loop is used and polar coordinates for a circle is used to generate it and points are plotted.
void draw_spray(int x,int y)
{
y=500-y;
if(first==0){
x0=x;yash=y;first=1;
}
for(int i=0;i<100;i++)
{
int c=rand();
int res=3+c%30;
glPointSize(1.0);
glBegin(GL_POINTS);
glVertex2d(x+res*cos(i*PI/180),y+res*sin(i*PI/180));
glEnd();
glFlush();
}
}
PENCIL:
This tool is used to draw freehand sketches. When the leftbutton is pressed to draw, a motion function is registerd which in turn calls the drawline(x,y); The concept used here is to have a global variable first that is initialised to zero and when the a point is clicked it is stored so that next point connected to it.
Code snippet:
if(b==GLUT_LEFT_BUTTON)
{ if(s==GLUT_DOWN)
if(funsel==1||funsel==2||funsel==3||funsel==5)
glutMotionFunc(motion);
}
void motion(int x,int y)
{
if(funsel==1)drawline(x,y);
}
void drawline(int x,int y)
{
if(first==0){
x0=x;yash=y;first=1;
}
glBegin(GL_LINES);
glVertex2d(x0,500-yash);
glVertex2d(x,500-y);
x0=x;yash=y;
glEnd();
glFlush();
}
ERASER:
This tool is used to erase the sketches drawn. This designed similar to pencil tool. The concept used here is to draw in white color which is the background color so that the sketch made is erased.
void draw_era(int x,int y)
{ glColor3f(1,1,1);
if(first==0){
x0=x;yash=y;first=1;
}
glRectf(x0,500-yash,x,500-y);
x0=x;yash=y;
glEnd();
glFlush();
}
FREE POLYGON:
This tool is used to draw n-sided-polygons. This is designed similar to the pencil tool. set is initialised to zero and lter to one to state that polygon is finished when right button is clicked.poly_mouse is a mouse funs that is used to ahndle the vertices of polygon.
void poly(int x,int y)
{
if(firstp==0){
px=x;py=y;firstp=1;}
glBegin(GL_LINES);
glVertex2d(px,500-py);
glVertex2d(x,500-y);
px=x;py=y;
glEnd();
glFlush();
}
void poly_mouse(int b,int s,int x,int y)
{
if(b==GLUT_LEFT_BUTTON && s==GLUT_DOWN)
{
if(!set){
glColor3fv(colors[s]);
poly(x,y);
}
}
if(b==GLUT_RIGHT_BUTTON && s==GLUT_DOWN){
glutMouseFunc (main_mouse);
glutMouseFunc (subwindow1_mouse);
set=1;funsel=0;
}
}
SPIRAL:
This tool draws a spiral at the clicked point.the radius of the spiarl is already fixed and also the distance by which the spiral is drawn.The concept used here is to increase the radius in each iteration so that a spiral is drawn instead of a circle.
void spiral(double a,double b)
{
b=500-b;
long double r=5;
glLineWidth(2.0);
glBegin(GL_LINE_STRIP);
for(int j=0;j<5;j++)
{
for(long double i=180;i>-180;i--,r=r+(5.0/180.0))
{
long double t=(PI*i)/180.0;
glVertex2f(a+r*cos(t),b+r*sin(t));
}
}glEnd();
glFlush();
}
CYLINDER: This tool draws a cylinder by drawing circles one on top of the other. The cylinder is generated at the point clicked by the user and radius and height is already set.
void circle(int x,int y,int r)
{
long double circle_points = 100000;
glBegin(GL_LINE_LOOP);
for (long double i = 0; i < circle_points; i++) {
long double angle = 2*PI*i/circle_points;
glVertex2f(x+r*cos(angle),y+r*sin(angle));
}
glEnd();}
void cyl(int a,int b)
{
b=500-b;
int r=50;
int i,n=20;
for(i=0;i<n;i+=3)
circle(a,b+i,r);
}
SPECIAL TRIANGLE:
This tool draws a triangle using the three points clicked by user. But the speciality of this triangle is that it 3 colors for 3 vertices and a beautiful colorful triangle is drawn. The concept used here is bilinear interpolation that uses S(α)= αP+(1- α)Q where P and Q are vertices and S is a point on the line joining them and α varies from 0 to 1.
void tri(int a,int b,int c,int d,int e,int f)
{
glBegin(GL_TRIANGLES);
glColor3fv(colors[s]);
glVertex2d(a,500-b);
glColor3fv(colors[s+1]);
glVertex2d(c,500-d);
glColor3fv(colors[s+2]);
glVertex2d(e,500-f);
glEnd();
glFlush();
}
Flowchart symbols:
Oval:This tool draws the oval which is used to specify the start and stop states in a flowchart. The concept used here is to draw lines for the top and bottom and draw semicircles for the sides when the two corners of the oval are clicked by user.
void oval(int a,int b,int c,int d)
{
b=500-b;
d=500-d;
int r=abs((b-d)/2);
glBegin(GL_LINE_STRIP);
glVertex2d(a,b);
glVertex2d(c,b);
for(long double i=90;i>-90;i--)
glVertex2d(c+r*cos(i*PI/180),d+r+r*sin(i*PI/180));
glVertex2d(c,d);
glVertex2d(a,d);
glEnd();
glBegin(GL_LINE_STRIP);
for(int i=90;i<=270;i++){
glVertex2d(a+r*cos(i*PI/180),d+r+r*sin(i*PI/180));}
glEnd();
glFlush();
}
Rhombus: This tool draws a rhombus when two points are clicked by user. Vertical distance between the points is calculated and used to find other vertices of the rhombus.
void rho(int a,int b,int c,int d)
{
b=500-b;d=500-d;
int dis=(b-d)/2;
glBegin(GL_LINE_STRIP);
glVertex2d(a,b);
glVertex2d(a+dis,b-dis);
glVertex2d(a,d);
glVertex2d(a-dis,d+dis);
glVertex2d(a,b);
glEnd();
glFlush();
}
Parallelogram: T his tool draws a parallelogram when two points are clicked by user. The indent for the parallelogram is already set keeping in mind the shape that is required when drawing flowcharts.
void para(int a,int b,int c,int d)
{
b=500-b;d=500-d;
int dis=30;
glBegin(GL_LINE_STRIP);
glVertex2d(a,b);
glVertex2d(c+dis,b);
glVertex2d(c,d);
glVertex2d(a-dis,d);
glVertex2d(a,b);
glEnd();
glFlush();
}
Rectangle:This tool draws a rectangle using the two points clicked by the user.
void rect(int a,int b,int c,int d)
{ int dist=a-c;
glBegin(GL_LINE_LOOP);
glVertex2f(c,500-d);
glVertex2f(c+dist,500-d);
glVertex2f(a,500-b);
glVertex2f(c,500-b);
glEnd();
glFlush();
}
ARROWS: these arrows are formed such that they are not inclined or look jagged. They are drawn by using the concept by slightly varying one of the points a straight line can be drawn. Triangles are drawn to shown in which direction they point to.
LEFT ARROW: This tool draws the left arrow using the two points clicked by the user.
void larrow(int a,int b,int c,int d)
{b=500-b;d=500-d;
glBegin(GL_LINE_STRIP);
glVertex2d(a,d);
glVertex2d(c,d);
glEnd();
glBegin(GL_TRIANGLES);
glVertex2d(c+10,d-5);
glVertex2d(c,d);
glVertex2d(c+10,d+5);
glEnd();
glFlush();
}
RIGHT ARROW: This tool draws the right arrow using the two points clicked by the user.
void rarrow(int a,int b,int c,int d)
{ b=500-b;d=500-d;
glBegin(GL_LINE_STRIP);
glVertex2d(a,d);
glVertex2d(c,d);
glEnd();
glBegin(GL_TRIANGLES);
glVertex2d(c,d);
glVertex2d(c-10,d-5);
glVertex2d(c-10,d+5);
glEnd();
glFlush();
}
DOWN ARROW: This tool draws the down arrow using the two points clicked by the user.
void darrow(int a,int b,int c,int d)
{b=500-b;d=500-d;
glBegin(GL_LINE_STRIP);
glVertex2d(c,b);
glVertex2d(c,d);
glEnd();
glBegin(GL_TRIANGLES);
glVertex2d(c+4,d+10);
glVertex2d(c,d);
glVertex2d(c-4,d+10);
glEnd();
glFlush();
}
UP ARROW: This tool draws the up arrow using the two points clicked by the user.
void uarrow(int a,int b,int c,int d)
{b=500-b;d=500-d;
glBegin(GL_LINE_STRIP);
glVertex2d(c,b);
glVertex2d(c,d);
glEnd();
glBegin(GL_TRIANGLES);
glVertex2d(c+4,d-10);
glVertex2d(c,d);
glVertex2d(c-4,d-10);
glEnd();
glFlush();
}
USER INTERFACE DESIGN:
There are icons for the various tools. Each icon is shown with a picture. Each icon has a unique funsel value which is used to indicate the tool selected by the user. For the picking process, bounding box technique is used. The x and y values got by the mouse function void main_mouse (int button, int state, int x, int y); registered in main function using glutMouseFunc (main_mouse); are used to check if the icon is selected or not. On the same lines even the colors are selected and the value is stored in s variable.
Code snippet:
if(x<100)
{
if(my<100)funsel=7;
else if(my<200)funsel=6;
else if(my<300)funsel=5;
else if(my<400)funsel=4;
}
There 2 windows in the package. The main windows has the icons and the color aplette. The subwindow is modelled as a cancas for the skecthing purposes. main_window is an integer variable which has the value of the window and can be used later also. The window title is set as GRAPHICAL EDITOR. The size of the window is 1010,700 and is positioned at 100,100 as the top left corner in device coordinates.
main_window = glutCreateWindow ("GRAPHCAL EDITOR");
glutInitWindowSize (1010,700);
glutInitWindowPosition (100,100);
subwindow_1 is an integer variable which has the value that can be used as a reference for the subwindow. main_window is used to specify that this is a subdindow created in that main window. The size of sunwindow is 600,500 and is positioned at 400,200 wrt the window coordinates.
subwindow_1 = glutCreateSubWindow (main_window,400,200,600,500);
DRAWING OF ICONS:
All icons have a replica of intended tool.
void draw_pen()
{
glColor3f(1.0,0.0,0.0);
glBegin(GL_LINES);
glVertex2d(10,640);
glVertex2d(60,640);
glEnd();
glBegin(GL_LINES);
glVertex2d(10,630);
glVertex2d(60,630);
glEnd();
glBegin(GL_LINES);
glVertex2d(10,620);
glVertex2d(60,620);
glEnd();
glBegin(GL_LINES);
glVertex2d(10,620);
glVertex2d(10,640);
glEnd();
glColor3f(0.0,0.0,0.0);
glBegin(GL_TRIANGLES);
glVertex2d(60,620);
glVertex2d(90,630);
glVertex2d(60,640);
glEnd();
glBegin(GL_LINE_LOOP);
glVertex2d(40,560);
glVertex2d(40,580);
glVertex2d(60,580);
glVertex2d(60,560);
glEnd();
text(30,530,GLUT_BITMAP_HELVETICA_12," Eraser");
int x=50,y=450;
for(int j=-2;j<3;j++)
for(int i=0;i<100;i++)
{ int c=rand();
int res=3+c%30;
glPointSize(1.0);
glBegin(GL_POINTS);
glVertex2d(x+2*j+res*cos(i*PI/180),y+2*j+res*sin(i*PI/180)); glEnd();
}
text(20,420,GLUT_BITMAP_HELVETICA_12," Spray");
glColor3f(0.0,0.0,0.0);
glBegin(GL_TRIANGLES);
glVertex2d(10,340);
glColor3f(1.0,1.0,0.0);
glVertex2d(90,340);
glColor3f(0.0,1.0,1.0);
glVertex2d(50,390);
glEnd();
text(5,320,GLUT_BITMAP_HELVETICA_12,"Special Triangle");
glColor3f(0.0,0.0,0.0);
glBegin(GL_LINE_LOOP);
glVertex2d(10,250);
glVertex2d(25,290);
glVertex2d(75,290);
glVertex2d(90,250);
glVertex2d(75,210);
glVertex2d(25,210);
glEnd();
glBegin(GL_LINE_STRIP);
glVertex2d(25,250);
glVertex2d(50,290);
glVertex2d(75,250);
glVertex2d(25,275);
glVertex2d(75,275);
glVertex2d(25,250);
glEnd();
text(30,240,GLUT_BITMAP_HELVETICA_12,"Free");
text(30,230,GLUT_BITMAP_HELVETICA_12,"Polygon");
long double r=1,a=50,b=150;
glBegin(GL_LINE_STRIP);
for(int j=0;j<5;j++)
{
for(long double i=180;i>-180;i--,r=r+(3.0/180.0))
{
long double t=(PI*i)/180.0;
glVertex2f(a+r*cos(t),b+r*sin(t));
}
}glEnd();
text(30,105,GLUT_BITMAP_HELVETICA_12,"Spiral");
int rar=2,w=50,v=50;
int i,n=15;
for(i=0;i<n;i+=3)
circle(w,v+i,r);
text(20,10,GLUT_BITMAP_HELVETICA_12,"Cylinder");
a=120; b=640; c=180;
float d=620;
r=abs((b-d)/2);
glBegin(GL_LINE_STRIP);
glVertex2d(a,b);
glVertex2d(c,b);
for(long double i=90;i>-90;i--)
glVertex2d(c+r*cos(i*PI/180),d+r+r*sin(i*PI/180));
glVertex2d(c,d);
glVertex2d(a,d);
glEnd();
glBegin(GL_LINE_STRIP);
for(int i=90;i<=270;i++){
glVertex2d(a+r*cos(i*PI/180),d+r+r*sin(i*PI/180));}
glEnd();
text(140,630,GLUT_BITMAP_HELVETICA_12,"oval");
a=120;b=575;c=180;d=555;
int dis=10;
glBegin(GL_LINE_STRIP);
glVertex2d(a,b);
glVertex2d(c+dis,b);
glVertex2d(c,d);
glVertex2d(a-dis,d);
glVertex2d(a,b);
glEnd();
text(110,530,GLUT_BITMAP_HELVETICA_12,"Parrallelogram");
glBegin(GL_LINE_LOOP);
glVertex2d(120,460);
glVertex2d(120,480);
glVertex2d(180,480);
glVertex2d(180,460);
glEnd();
text(120,430,GLUT_BITMAP_HELVETICA_12,"Rectangle");
glBegin(GL_LINE_LOOP);
glVertex2d(150,390);
glVertex2d(175,365);
glVertex2d(150,345);
glVertex2d(125,365);
glEnd();
text(120,320,GLUT_BITMAP_HELVETICA_12,"Rhombus");
circle(150,250,40);
text(130,250,GLUT_BITMAP_HELVETICA_12,"Circle");
rarrow(120,500-180,170,500-180);
larrow(170,500-140,120,500-140);
uarrow(125,500-10,125,500-80);
darrow(175,500-80,175,500-10);
text(30,670,GLUT_BITMAP_HELVETICA_12,"Text");
text(100,670,GLUT_BITMAP_HELVETICA_12," Flowchart");
text(100,660,GLUT_BITMAP_HELVETICA_12," Symbols");
}
Drawing background:
The concept used here is polygon stippling facility in openGl. This has to enabled before stippling and disabled after stippling.
void drawbackground()
{
glEnable(GL_POLYGON_STIPPLE);
glPolygonStipple(pot3);
glColor4f(1.0,0.9,1.0,0.0);
glRectf(0,0,200.0, 700.0);
glDisable(GL_POLYGON_STIPPLE);
}
Drawing color pallette:
Pallete is drawn by using the color array and rectf which draws filled rectangles. The geometric shape of the palette helps in drawing it with a simple for loop.
void draw_color_buttons()
{
for(int i=4;i<20;i++)
{
int n;
n=i-3;
glColor3fv(colors[n]);
glRectf(50*i,0,(50*i)+50,100);
}
}