CG Lab Manual

71
Practical-1 Aim: Study of various C graphics functions Software Required: Turbo C/C++ Compiler Knowledge Required: Basic ‘C/C++’ language programming, Hardware Interrupt, Hex number format. Theory/logic: - initgraph () Syntax:- #include <graphics.h> void initgraph(int *graphdriver, int *graphmode, char *pathtodriver); Description:-initgraph initializes the graphics system by loading a graphics driver from disk (or validating a registered driver), and putting the system into graphics mode. To start the graphics system, first call the initgraph function. initgraph loads the graphics driver and puts the system into graphics mode. You can tell initgraph to use a particular graphics driver and mode, or to autodetect the attached video adapter at run time and pick the corresponding driver. If you tell initgraph to autodetect, it calls detectgraph to select a graphics driver and mode. initgraph also resets all graphics settings to their defaults (current position, palette, color, viewport, and so on) and resets graphresult to 0. Normally, initgraph loads a graphics driver by allocating memory for the driver (through _graphgetmem), then loading the appropriate .BGI file from disk. As an alternative to this dynamic loading scheme, you can link a graphics driver file (or several of them) directly into your executable program file. pathtodriver specifies the directory path where initgraph looks for graphics drivers. initgraph first looks in the path specified in pathtodriver, then (if they are not there) in the current directory. Accordingly, if pathtodriver is null, the driver files (*.BGI) must be in the current directory. This is also the path settextstyle searches for the stroked character font files (*.CHR). *graphdriver is an integer that specifies the graphics driver to be used. You can give it a value using a constant of the graphics_drivers enumeration type, which is defined in graphics.h and listed below. Graphics Drivers Constant Numeric value DETECT 0 (requests autodetect) CGA 1 MCGA 2 EGA 3 EGA64 4 EGAMONO 5 IBM8514 6 HERCMONO 7 ATT400 8 VGA 9 PC3270 10 *graphmode is an integer that specifies the initial graphics mode (unless *graphdriver equals DETECT; in which case, *graphmode is set by initgraph to the highest resolution available for the detected driver). You

description

graphics program

Transcript of CG Lab Manual

Page 1: CG Lab Manual

Practical-1

Aim: Study of various C graphics functions

Software Required: Turbo C/C++ Compiler

Knowledge Required: Basic ‘C/C++’ language programming, Hardware Interrupt, Hex number format.

Theory/logic: -

initgraph ()

Syntax:- #include <graphics.h>

void initgraph(int *graphdriver, int *graphmode, char *pathtodriver);

Description:-initgraph initializes the graphics system by loading a graphics driver from disk (or

validating a registered driver), and putting the system into graphics mode.

To start the graphics system, first call the initgraph function. initgraph loads the graphics driver and puts

the system into graphics mode. You can tell initgraph to use a particular graphics driver and mode, or to

autodetect the attached video adapter at run time and pick the corresponding driver.

If you tell initgraph to autodetect, it calls detectgraph to select a graphics driver and mode. initgraph also

resets all graphics settings to their defaults (current position, palette, color, viewport, and so on) and resets

graphresult to 0.

Normally, initgraph loads a graphics driver by allocating memory for the driver (through _graphgetmem),

then loading the appropriate .BGI file from disk. As an alternative to this dynamic loading scheme, you

can link a graphics driver file (or several of them) directly into your executable program file.

pathtodriver specifies the directory path where initgraph looks for graphics drivers. initgraph first looks in

the path specified in pathtodriver, then (if they are not there) in the current directory. Accordingly, if

pathtodriver is null, the driver files (*.BGI) must be in the current directory. This is also the path

settextstyle searches for the stroked character font files (*.CHR).

*graphdriver is an integer that specifies the graphics driver to be used. You can give it a value using a

constant of the graphics_drivers enumeration type, which is defined in graphics.h and listed below.

Graphics Drivers Constant Numeric value

DETECT 0 (requests autodetect)

CGA 1

MCGA 2

EGA 3

EGA64 4

EGAMONO 5

IBM8514 6

HERCMONO 7

ATT400 8

VGA 9

PC3270 10

*graphmode is an integer that specifies the initial graphics mode (unless *graphdriver equals DETECT; in

which case, *graphmode is set by initgraph to the highest resolution available for the detected driver). You

Page 2: CG Lab Manual

can give *graphmode a value using a constant of the graphics_modes enumeration type, which is defined

in graphics.h and listed below.

graphdriver and graphmode must be set to valid values from the following tables, or you will get

unpredictable results. The exception is graphdriver = DETECT.

Palette listings C0, C1, C2, and C3 refer to the four predefined four-color palettes available on CGA (and

compatible) systems. You can select the background color (entry #0) in each of these palettes, but the

other colors are fixed.

Palette Number Three Colors

0 LIGHTGREEN LIGHTRED YELLOW

1 LIGHTCYAN LIGHTMAGENTA WHITE

2 GREEN RED BROWN

3 CYAN MAGENTA LIGHTGRAY

After a call to initgraph, *graphdriver is set to the current graphics driver, and *graphmode is set to the

current graphics mode.

Graphics

Driver

Graphics

Mode Value Columns x Rows Palette Pages

CGA CGAC1 1 320 x 200 C1 1

CGAC2 2 320 x 200 C2 1

CGAC3 3 320 x 200 C3 1

CGAHI 4 640 x 200 2 color 1

MCGA MCGAC0 0 320 x 200 C0 1

MCGAC1 1 320 x 200 C1 1

MCGAC2 2 320 x 200 C2 1

MCGAC3 3 320 x 200 C3 1

MCGAMED 4 640 x 200 2 color 1

MCGAHI 5 640 x 480 2 color 1

EGA EGALO 0 640 x 200 16 color 4

EGAHI 1 640 x 350 16 color 2

EGA64 EGA64LO 0 640 x 200 16 color 1

EGA64HI 1 640 x 350 4 color 1

EGA-

MONO EGAMONOHI 3 640 x 350 2 color

1

w/64K

EGAMONOHI 3 640 x 350 2 color 2

w/256K

HERC HERCMONOHI 0 720 x 348 2 color 2

Page 3: CG Lab Manual

ATT400 ATT400C0 0 320 x 200 C0 1

ATT400C1 1 320 x 200 C1 1

ATT400C2 2 320 x 200 C2 1

ATT400C3 3 320 x 200 C3 1

ATT400MED 4 640 x 200 2 color 1

ATT400HI 5 640 x 400 2 color 1

VGA VGALO 0 640 x 200 16 color 2

VGAMED 1 640 x 350 16 color 2

VGAHI 2 640 x 480 16 color 1

PC3270 PC3270HI 0 720 x 350 2 color 1

IBM8514 IBM8514HI 0 640 x 480 256 color

IBM8514LO 0 1024 x 768 256 color

Return Value: - initgraph always sets the internal error code; on success, it sets the code to 0. If an error

occurred, *graphdriver is set to -2, -3, -4, or -5, and graphresult returns the same value as listed below:

Constant Name Number Meaning

grNotDetected -2 Cannot detect a graphics card

grFileNotFound -3 Cannot find driver file

grInvalidDriver -4 Invalid driver

CIRCLE

Syntax: - Void circle (int x, int y, int radius);

Description: - Circle function takes X and Y values with respect to top left corner of the screen and third

argument is a radius of the circle.

Return Value: -None

Closegraph

Syntax: - void closegragh(void);

Description: - The closegraph() swithces back the screen from grpahics mode to text mode. If you don’t

use this function then you may have undesirable effects.Here this function is called afer the getch()

function as screen shouldn’t switch to text mode till user hits any key.

closegraph deallocates all memory allocated by the graphics system, then restores the screen to the mode

it was in before you called initgraph. (The graphics system deallocates memory, such as the drivers, fonts,

and an internal buffer, through a call to _graphfreemem.)

Return Value: -None.

Cleardevice

Syntax: - void cleardevice(void);

Description: -cleardevice erases (that is, fills with the current background color) the entire graphics

screen and moves the CP (current position) to home (0,0).

Return Value: -None

Page 4: CG Lab Manual

Ellipse

Syntax: - void ellipse(int x, int y, int stangle, int endangle, int xradius, int yradius);

Description: - ellipse draws an elliptical arc in the current drawing color with its center at (x,y) and the

horizontal and vertical axes given by xradius and yradius, respectively. The ellipse travels from stangle to

endangle. If stangle equals 0 and endangle equals 360, the call to ellipse draws a complete ellipse.

The angle for ellipse is reckoned counterclockwise, with 0 degrees at 3 o'clock, 90 degrees at 12 o'clock,

and so on. The linestyle parameter does not affect arcs, circles, ellipses, or pie slices. Only the thickness

parameter is used.

Return Value: -None

Fill-Ellipse

Syntax: - void fillellipse(int x, int y, int xradius, int yradius);

Description: -Draws an ellipse using (x,y) as a center point and xradius and yradius as the Horizontal and

vertical axes, and fills it with the current fill color and fill pattern.

Return Value: -None

Fillpoly

Syntax: - void fillpoly(int numpoints, int *polypoints);

Description: -fillpoly draws the outline of a polygon with numpoints points in the current line style and

color (just as drawpoly does), then fills the polygon using the current fill pattern and fill color. polypoints

points to a sequence of (numpoints * 2) integers. Each pair of integers gives the x- and y-coordinates of a

point on the polygon.

Return Value: -None

Getaspectratio

Syntax: - void getaspectratio(int *xasp, int *yasp);

Description: -The y aspect factor, *yasp, is normalized to 10,000. On all graphics adapters except the

VGA, *xasp (the x aspect factor) is less than *yasp because the pixels are taller than they are wide. On the

VGA, which has "square" pixels, *xasp equals *yasp. In general, the relationship between *yasp and

*xasp can be stated as *yasp = 10,000 *xasp <= 10,000 getaspectratio gets the values in *xasp & *yasp.

Return Value: -None

Getbkcolor

Syntax: - int getbkcolor(void);

Description: -getbkcolor returns the current background color. (See the table in setbkcolor for details.)

Return Value: - getbkcolor returns the current background color

Getcolor

Syntax: -int getcolor(void);

Description: - getcolor returns the current drawing color. The drawing color is the value to which pixels

are set when lines and so on are drawn. For example, in CGAC0 mode, the palette contains four colors:

the background color, light green, light red, and yellow. In this mode, if getcolor returns 1, the current

drawing color is light green.

Return Value: - getcolor returns the current drawing color

Page 5: CG Lab Manual

Getdrivername

Syntax: - char *getdrivername(void);

Description: - After a call to initgraph, getdrivername returns the name of the driver that is currently

loaded.

Return Value: - getdrivername returns a pointer to a string with the name of the currently loaded graphics

driver

Getgraphmode

Syntax: - int getgraphmode(void);

Description: -Your program must make a successful call to initgraph before calling getgraphmode. The

enumeration graphics_mode, defined in graphics.h, gives names for the predefined graphics modes. For a

table listing these enumeration values, refer to the description for initgraph.

Return Value: - getgraphmode returns the graphics mode set by initgraph or setgraphmode.

Getmaxx

Syntax: - int getmaxx(void);

Description: - getmaxx returns the maximum (screen-relative) x value for the current graphics driver and

mode. For example, on a CGA in 320*200 mode, getmaxx returns 319. getmaxx is invaluable for

centering, determining the boundaries of a region onscreen, and so on.

Return Value: - getmaxx returns the maximum x screen coordinate.

Getmaxy

Syntax: - int getmaxy(void);

Description: -getmaxy returns the maximum (screen-relative) y value for the current graphics driver and

mode. For example, on a CGA in 320*200 mode, getmaxy returns 199. getmaxy is invaluable for

centering, determining the boundaries of a region onscreen, and so on.

Return Value: - getmaxy returns the maximum y screen coordinate.

Getpixel

Syntax: -unsigned getpixel(int x, int y);

Description: - getpixel gets the color of the pixel located at (x,y).

Return Value: -getpixel returns the color of the given pixel.

Gety

Syntax: -int gety(void);

Description: -gety returns the current graphics position's y-coordinate. The value is viewport-relative.

Return Value: - gety returns the y-coordinate of the current position.

Line

Syntax: -void line(int x1, int y1, int x2, int y2);

Description: - line draws a line in the current color, using the current line style and thickness between the

two points specified, (x1,y1) and (x2,y2), without updating the current position (CP).

Return Value: -None

Page 6: CG Lab Manual

Linerel

Syntax: -void linerel(int dx, int dy);

Description: -linerel draws a line from the CP (current position) to a point that is a relative distance

(dx,dy) from the CP. The CP is advanced by (dx,dy).

Return Value: -None

Moverel

Syntax: - void moverel(int dx, int dy);

Description: - moverel moves the current position (CP) dx pixels in the x direction and dy pixels in the y

direction.

Return Value: -None

Moveto

Syntax: - void moveto(int x, int y);

Description: -moveto moves the current position (CP) to viewport position (x,y).

Return Value: -None

Outtext

Syntax: -void outtext(char *textstring);

Description: -outtext displays a text string in the viewport, using the current font, direction, and size.

outtext outputs textstring at the current position (CP). If the horizontal text justification is LEFT_TEXT

and the text direction is HORIZ_DIR, the CP's x-coordinate is advanced by textwidth(textstring).

Otherwise, the CP remains unchanged. To maintain code compatibility when using several fonts, use

textwidth and textheight to determine the dimensions of the string. If a string is printed with the default

font using outtext, any part of the string that extends outside the current viewport is truncated. outtext is

for use in graphics mode; it will not work in text mode.

Return Value: -None

Outtextxy

Syntax: - void outtextxy(int x, int y, char *textstring);

Description: -outtextxy displays a text string in the viewport at the given position (x, y), using the current

justification settings and the current font, direction, and size. To maintain code compatibility when using

several fonts, use textwidth and textheight to determine the dimensions of the string. If a string is printed

with the default font using outtext or outtextxy, any part of the string that extends outside the current

viewport is truncated. Outtextxy is for use in graphics mode; it will not work in text mode.

Return Value: -None

Putpixel

Syntax: -void putpixel(int x, int y, int color);

Description: -putpixel plots a point in the color defined by color at (x,y).

Return Value: - None

Page 7: CG Lab Manual

Rectangle

Syntax: -void rectangle(int left, int top, int right, int bottom);

Description: -rectangle draws a rectangle in the current line style, thickness, and drawing color. (left,top)

is the upper left corner of the rectangle, and (right,bottom) is its lower right corner.

Return Value: - None

Source Code:

/* 1. Program to show how to initialize graphics mode*/

#include<graphics.h>

#include<stdio.h>

#include<conio.h>

void main()

{

int gd=DETECT, gm;

initgraph(&gd, &gm, "c:\\turboc3\\tc\\bgi " );

circle(200,100,150);

getch();

closegraph();

}

/* 2. Program to show the use of various Graphics Library function */

#include<graphics.h>

#include<stdio.h>

#include<conio.h>

void main()

{

int gd=DETECT, gm;

int poly[12]={350,450, 350,410, 430,400, 350,350, 300,430, 350,450 };

initgraph(&gd, &gm, "c:\\turboc3\\tc\\bgi");

circle(100,100,50);

outtextxy(75,170, "Circle");

rectangle(200,50,350,150);

outtextxy(240, 170, "Rectangle");

ellipse(500, 100,0,360, 100,50);

outtextxy(480, 170, "Ellipse");

line(100,250,540,250);

outtextxy(300,260,"Line");

sector(150, 400, 30, 300, 100,50); outtextxy(120, 460, "Sector");

drawpoly(6, poly);outtextxy(340, 460, "Polygon");

getch();

closegraph();

}

Page 8: CG Lab Manual

Practical-2

Aim: Implementation and Using mouse in DOS

Software Required: Turbo C/C++ Compiler

Knowledge Required: Basic ‘C/C++’ language programming, Hardware Interrupt, Hex number format

Theory/logic:

Introduction to Mouse Programming There are many ways to access the mouse. Either using tool that are already equipped with mouse routine

or communicating with mouse driver or programming directly with the mouse. What this article is about is

using a method, which deals with mouse with the existence of the mouse driver. Mouse driver is a device

driver that assists the OS in determining what type of mouse is available to the OS.

What are Interrupts?

Interrupts are special functions, which is built in the BIOS (basic input output system). There are nearly

hundreds of interrupt in the BIOS and we are dealing with Interrupt 0x33 (mouse functions). Whenever an

interrupt is called, any task, which is in progress, will be interrupted to execute the requested task. This

interrupt is called by setting the appropriate register value, call the interrupt and output value will be set to

the same register. Either the programmer can look at the output value in the specified register to determine

the called interrupt is performed perfectly or error has occurred.

What are REGISTERS?

Register is a special memory placed in the microprocessor chip, i.e. the 8086, 80486 or Pentium® Chip

for faster calculation. This memory location is used during calculation and other stuff. There are several

kind of register in the chip and what I am listing here is just the information enough for us to get to mouse

programming. The Intel® 80x86 families and Pentium® have the following registers in their chips.

General-purpose register: AX, BX, CX, DX which will be used widely in our program

AX (16 bits) is a combination of AH and AL (H-higher 8 bits, L-lower 8 bits). This combination is

also applicable to BX, CX, DX register

8 bits 8 bits Names

AH AL Accumulator

BH BL Base

CH CL Counter

DH DL Data

Segment Register which in our consideration

16 bits Names

ES Extra Segment

CS Code Segment

SS Stack Segment

Page 9: CG Lab Manual

DS Data Segment

Pointer Registers

16 bits Names

SI Source Index

DI Destination Index

Basic Concept of Mouse Handling

First thing you must know how to tell a mouse to do anything. In actual we do not communicate with

mouse directly but through the driver provided. We use "Interrupts" to get access to this driver. Each

device provide by computer has its own port and more or less we access these ports.

Each device has a unique port which is a hexadecimal value and value is designed to be machine

independent enhancing portability of program.

Mouse has port 0X33 attached to it and similarly keyboard has attach port 0X60.

We make use of address registers. These are basically UNION of type REGS defined in "dos.h".

union REGS {

struct WORDREGS x;

struct BYTEREGS h;

};

BYTEREGS and WORDREGS

Structures for storing byte and word registers

struct WORDREGS {

unsigned int ax, bx, cx, dx;

unsigned int si, di, cflag, flags;

};

struct BYTEREGS {

unsigned char al, ah, bl, bh;

unsigned char cl, ch, dl, dh;

};

We use two registers to communicate to a device driver one for input and one for output.

The union REGS is used to pass information to and from these functions:

int86 int86x intdos intdosx

To do mouse programming you must include <dos.h>. We use a function called int86() to access

"interupts".

Declaration:

int int86(int intno, union REGS *inregs, union REGS *outregs);

We send value to device driver through the input register and receive information in it embedded in output

register.

Page 10: CG Lab Manual

Before the interrupt

Before executing the software interrupt, these functions copy register values from inregs into the registers.

After the interrupt

After the software interrupts returns, these functions copy the following: current register values to outregs

Return Value

Both functions return the value of AX after completion of the software interrupt

AX Register We can access various mouse functions using different values of AX input Register and passing those

values to mouse port using a interrupt.

The Functions are listed below - Here AX, BX, CX and DX are members of UNION REGS and more or

less integers.

Input Function Performed Returns

AX = 0 Get Mouse Status AX Value = FFFFh support is available.

AX Value = 0 ,support is not available.

AX = 1 Show Mouse Pointer Nothing

AX = 2 Hide Mouse Pointer Nothing

AX = 3 Mouse Position CX = Mouse X Coordinate

DX = Mouse Y Coordinate

AX = 3 Mouse Button Press BX = 0 No Key Is Pressed

BX = 1 Left Button is Pressed

BX = 2 Right Button is Pressed

BX = 3 Centre Button is Pressed

AX= 7 Set Horizontal Limit Nothing

CX = MaxX1

DX =MaxX2

AX= 8 Set Vertical Limit Nothing

CX = MaxX1

DX =MaxX2

Page 11: CG Lab Manual

Detecting Mouse: - Before you start your mouse program you should always check whether the mouse programming is

supported or not.

If somehow mouse fails to initialize you should always make sure that either program terminates or

employ a error handling approach that maybe shift to keyboard interface .

To detect mouse we use a user defined function name detect_mouse() which has following code -

#include <stdio.h>

#include <conio.h>

#include <dos.h>

union REGS in, out;

void detect_mouse ()

{

in.x.ax = 0;

int86 (0X33,&in,&out);

if (out.x.ax == 0)

printf ("\nMouse Failed To Initialize");

else

printf ("\nMouse was Succesfully Initialized");

}

int main ()

{

detect_mouse ();

getch ();

return 0;

}

Showing and Hiding Mouse: - Now first we show mouse on screen.

Mouse works both in text mode and graphic mode.

In text mode it looks like a square while in graphics mode it looks like a pointer.

Mouse Programming in Text Mode: -

To show mouse in text mode we added a user defined function showmouse_text() to above code so code

becomes -

#include <stdio.h>

#include <conio.h>

#include <dos.h>

union REGS in, out;

void detect_mouse ()

{

in.x.ax = 0;

int86 (0X33,&in,&out);

if (out.x.ax == 0)

printf ("\nMouse Failed To Initialize");

else

printf ("\nMouse was Succesfully Initialized");

getch();

}

Page 12: CG Lab Manual

void showmouse_text ()

{

in.x.ax = 1;

int86 (0X33,&in,&out);

}

int main ()

{

detect_mouse ();

showmouse_text();

getch ();

return 0;

}

Mouse Programming in Graphics Mode: -

To show mouse in graphics mode we added a user defined function showmouse_graphics() to detect

mouse code above.

#include <stdio.h>

#include <conio.h>

#include <dos.h>

#include <graphics.h>

union REGS in, out;

void detect_mouse ()

{

in.x.ax = 0;

int86 (0X33,&in,&out);

if (out.x.ax == 0)

printf ("\nMouse Failed To Initialize");

else

printf ("\nMouse was Succesfully Initialized");

getch();

}

void showmouse_graphics ()

{

//int gdriver = DETECT, gmode, errorcode;

//initgraph(&gdriver, &gmode, "c:\\tc\\bgi");

in.x.ax = 1;

int86 (0X33,&in,&out);

getch ();

//closegraph ();

}

int main ()

{

int gdriver = DETECT, gmode, errorcode;

initgraph(&gdriver, &gmode, "c:\\tc\\bgi");

detect_mouse ();

showmouse_graphics();

getch ();

closegraph ();

return 0;

}

Page 13: CG Lab Manual

Hiding mouse: -

To hide mouse we added a user defined function hide_mouse() to the above code.

#include <stdio.h>

#include <conio.h>

#include <dos.h>

#include <graphics.h>

union REGS in, out;

void detectmouse ()

{

in.x.ax = 0;

int86 (0X33,&in,&out);

if (out.x.ax == 0)

printf ("\nMouse Failed To Initialize");

else

printf ("\nMouse was Succesfully Initialize");

getch();

}

void showmouse_graphics ()

{

in.x.ax = 1;

int86 (0X33,&in,&out);

getch ();

}

void hide_mouse ()

{

in.x.ax = 2;

int86 (0X33,&in,&out);

}

int main ()

{

int gdriver = DETECT, gmode, errorcode;

initgraph(&gdriver, &gmode, "c:\\tc\\bgi");

detect_mouse ();

showmouse_graphics();

hide_mouse ();

getch ();

closegraph ();

return 0;

}

Page 14: CG Lab Manual

Detecting Mouse Click: - An important aspect of mouse programming "Detecting Clicks" i.e. Taking

Inputs. We make use of an additional library function known as kbhit ( ).

Kbhit() returns zero till no key is press and when a key is press it returns 1. It is used to run an

infinite while loop.

To detect mouse clicks we add a user defined function detect_mouse_click () to the above code, which

displays on screen the respective button clicked

#include <stdio.h>

#include <conio.h>

#include <dos.h>

#include <graphics.h>

union REGS in, out;

void detect_mouse ()

{

in.x.ax = 0;

int86 (0X33,&in,&out);

if (out.x.ax == 0)

printf ("\nMouse Failed To Initialize");

else

printf ("\nMouse was Succesfully Initialized");

getch();

}

void showmouse_graphics ()

{

in.x.ax = 1;

int86 (0X33,&in,&out);

}

void detect_mouse_click ()

{

while (!kbhit () ) //Press any keyboad key to exit the loop.

{

in.x.ax = 3;

int86 (0X33,&in,&out);

if (out.x.bx == 1) printf ("\nLeft");

if (out.x.bx == 2) printf ("\nRight");

if (out.x.bx == 3) printf ("\nMiddle");

delay (200); // Otherwise due to quick computer response 100s of words will get print

}

}

int main ()

{

int gdriver = DETECT, gmode, errorcode;

initgraph(&gdriver, &gmode, "c:\\tc\\bgi");

detect_mouse ();

showmouse_graphics();

detect_mouse_click ();

getch ();

closegraph ();

return 0;

}

Page 15: CG Lab Manual

Get Mouse Coordinates

We can obtain the coordinates of the mouse using same service 3 but using different elements of the

union.

This function has a prime use in games programming, application designing and GUI development.

Different decisions are taken on same left button click; it’s the position of click that matters.

BX element of output registers stores the X Coordinate of the position of mouse at time of calling

function.

CX element of output registers stores the Y Coordinate of the position of mouse at time of calling

function.

To get mouse coordinate we modified user defined function detect_mouse_click() in the above code, to

display x and y coordinates on screen when left click is pressed.

#include <stdio.h>

#include <conio.h>

#include <dos.h>

#include <graphics.h>

union REGS in, out;

void detect_mouse ()

{

in.x.ax = 0;

int86 (0X33,&in,&out);

if (out.x.ax == 0)

printf ("\nMouse Failed To Initialize");

else

printf ("\nMouse was Succesfully Initialized");

getch();

}

void showmouse_graphics ()

{

in.x.ax = 1;

int86 (0X33,&in,&out);

}

void hide_mouse ()

{

in.x.ax = 2;

int86 (0X33,&in,&out);

getch();

}

void detect_mouse_click() {

while (!kbhit () )

{

int x,y;

in.x.ax = 3;

int86 (0X33, &in, &out);

if (out.x.bx == 1)

Page 16: CG Lab Manual

{

x = out.x.cx;

y = out.x.dx;

printf ("\nLeft || X - %d Y - %d", x, y);

}

if (out.x.bx == 2)

printf ("\nRight");

if (out.x.bx == 3)

printf ("\nMiddle");

delay (200); // Otherwise due to quick computer response 100s of words will get print

}

}

int main ()

{

int gdriver = DETECT, gmode, errorcode;

initgraph(&gdriver, &gmode, "c:\\tc\\bgi");

detect_mouse ();

showmouse_graphics();

detect_mouse_click();

hide_mouse ();

getch ();

closegraph ();

return 0;

}

Restricting Mouse in Rectangular Window: - To restrict the mouse in one particular size window in GUI or In Games Programming, we added a user

defined function restrict () to the above code.

It takes four parameters, two Cartesian points each containing one x coordinate and one y coordinate.

First point mentions the top of the rectangle while second point mentions the bottom point of rectangle.

This service can be quite handy in special circumstances,

Ex - if you want to restrict your mouse in one particular size window in GUI or In Games Programming.

#include <stdio.h>

#include <conio.h>

#include <dos.h>

#include <graphics.h>

union REGS in, out;

void restrict (int x1,int y1,int x2, int y2)

{

in.x.ax = 7;

in.x.cx = x1;

in.x.dx = x2;

int86 (0X33,&in,&out);

in.x.ax = 8;

in.x.cx = y1;

in.x.dx = y2;

int86 (0X33,&in,&out);

}

Page 17: CG Lab Manual

void detect_mouse ()

{

in.x.ax = 0;

int86 (0X33,&in,&out);

if (out.x.ax == 0)

printf ("\nMouse Fail To Initialize");

else

printf ("\nMouse Succesfully Initialize");

getch();

}

void showmouse_graphics ()

{

in.x.ax = 1;

int86 (0X33,&in,&out);

}

void detect_mouse_click()

{

while (!kbhit () )

{

int x,y;

in.x.ax = 3;

int86 (0X33,&in,&out);

if (out.x.bx == 1)

{

x = out.x.cx;

y = out.x.dx;

printf ("\nLeft || X - %d Y - %d", x, y);

}

if (out.x.bx == 2) printf ("\nRight");

if (out.x.bx == 3) printf ("\nMiddle");

delay (200); // Otherwise due to quick computer response 100s of words will get print

}

}

int main ()

{

int gdriver = DETECT, gmode, errorcode;

initgraph(&gdriver, &gmode, "c:\\tc\\bgi");

detect_mouse ();

showmouse_graphics();

restrict (100,100,500,500); // Change values here to create different mouse movement space.

detect_mouse_click();

getch ();

closegraph ();

return 0;

}

Page 18: CG Lab Manual

Practical 3

Aim: Implement DDA line algorithm

Software Required: Turbo C/C++ Compiler

Knowledge Required: Basic ‘C/C++’ language programming

Theory/Logic:

This algorithms based on calculating either ∆x or ∆y. In this algorithm we have to sample the line at unit

intervals (e.g. ∆x=1 or ∆y=1) in one coordinate (x or y) and determine corresponding integer value nearest

the line path for other coordinate (xk or yk).

In this algorithm we have to consider four cases:

1. Line with a positive slope less than or equal to 1 and starting point is left most end-point.

2. Line with a positive slope greater than 1 and starting point is left most end-point.

3. Line with a positive slope greater than 1 and starting point is right most end-point.

4. Line with a positive slope less than or equal to 1 and starting point is right most end-point.

Case 1: Line with a positive slope less than or equal to 1 and starting point is left most end-point.

Consider a line with slope is less than or equal to 1. At this time we will sample at unit x intervals (∆x=1)

and compute each successive y value as

yk+1 = yk + m

Here,

m = ∆y / ∆x = y2 - y1 / ∆x

but ∆x = 1

so, m = y2 - y1

let y2 = yk+1 and y1 = yk

Here subscript k takes integer values starting from 1, for the first point and increases by 1 until the final

end-point is reached since m can be any real number between 0 and 1, the calculated y value must be

rounded to the nearest integer.

Case 2: Line with a positive slope greater 1 and starting point is left most end-point.

For line with a positive slope greater than 1, we reverse the roles of x and y. that is we have to sample as

unit y intervals (∆y = 1) and calculate each succeeding x value as xk+1=xk+1/m.

Case 3: Line with a positive slope greater than 1 and starting point is right most end-point.

For this case we have to ∆y = -1 because we are starting from right most end-point. So our equation will

be yk+1=yk-m

Case 4: Line with a positive slope less than or equal to 1 and starting point is right most end-point.

For this case we have to ∆x = -1 because we are starting from right most end-point. So our equation will

be yk+1=yk-m

Algorithm

Procedure lineDDA (xa, ya, xb, yb : integer);

Var

dx, dy, steps, k : integer

xincrement, yIncrement, x, y : real;

begin

dx := xb-xa;

dy := yb-ya;

Page 19: CG Lab Manual

if abs (dx) > abs (dy) then steps := abs (dx)

else steps := abs (dy);

xincrement := dx / steps;

yIncrement := dy / steps;

x := xa;

y := ya;

setpixel (round(x), round(y), 1);

for k := 1 to steps do

begin

x := x + xincrement;

y := y + yIncrement;

setpixel (round(x), round(y), 1);

end

end; (lineDDA)

Source Code: -

/*

-------------------------------------------------------------------------

DDA line drawing algorithm

-------------------------------------------------------------------------

*/

# include <graphics.h>

# include <math.h>

# include <conio.h>

# include <iostream.h>

void DDALine(int x1,int y1,int x2,int y2,int iColor);

void main()

{

int gDriver=DETECT,gMode;

int x1,x2,y1,y2,iColor;

initgraph(&gDriver,&gMode,"c:\\tc\\bgi");

cleardevice();

cout<<endl<<"Enter x1 : ";

cin>>x1;

cout<<"Enter y1 : ";

cin>>y1;

cout<<endl<<"Enter x2 : ";

cin>>x2;

cout<<"Enter y2 : ";

cin>>y2;

cout<<endl<<"Enter COLOR : ";

cin>>iColor;

cleardevice();

DDALine(320,1,320,480,12);

DDALine(1,240,640,240,12);

circle(320,240,2);

DDALine(320+x1,240-y1,320+x2,240-y2,iColor%16);

Page 20: CG Lab Manual

getch();

}

void DDALine(int x1,int y1,int x2,int y2,int iColor)

{

float dX,dY,iSteps;

float xInc,yInc,iCount,x,y;

dX = x1 - x2;

dY = y1 - y2;

if (fabs(dX) > fabs(dY))

{

iSteps = fabs(dX);

}

else

{

iSteps = fabs(dY);

}

xInc = dX/iSteps;

yInc = dY/iSteps;

x = x1;

y = y1;

circle(x,y,1);

for (iCount=1; iCount<=iSteps; iCount++)

{

putpixel(floor(x),floor(y),iColor);

x -= xInc;

y -= yInc;

}

circle(x,y,1);

return;

}

Advantages: - 1. Faster method for calculation of pixels position the direct use of equation.

2. It eliminates the multiplication in equation by making use of raster characteristic.

Disadvantages: -

1. The accumulation of round errors in successive additions of the floating point increment can cause

the calculated pixel positions to drift away from the true line path for long line segment.

2. Furthermore, the rounding operation and floating point arithmetic operation is procedure are still

time consuming.

Page 21: CG Lab Manual

Practical 4

Aim: - Implement Bresenham Line algorithm

Software Required: -Turbo C/C++ Compiler,

Knowledge Required: -Basic ‘C/C++’ language programming

Theory/Logic: -

The Bresenham Line Drawing Algorithm

Figure 2

Given two endpoints (Ax, Ay) and (Bx, By), we can chose the start point (xk, yk). The choice is purely

arbitrary, it can be either of (Ax, Ay) and (Bx, By) points. From this start point or pixel, we have eight

possible choices for the next pixel in the line, since each pixel is surrounded by 8 other pixels (except

border pixels). We need to isolate these eight choices into only two choices. If we restrict the slope m for

now to 0 <= m <=1 and assume Ax < Bx, we know that we can simply step in x one pixel at a time to the

right and determine what y value to choose next. Given (xk, yk), the next ideal pixel (the closest to the real

line) will be (xk+1, y) where,

y = m*(xk+1) + b

But we must choose between (xk+1, yk) or (xk+1, yk+1) as shown in figure 2. These pixels represent the

one just to the right and the one to the right and one up pixel, respectively.

To find the best "next pixel", first we must find the distances (d1 and d2) to the two available choices from

the ideal location (of the real line). Distance between pixel-to-right and ideal pixel is:

d1 = y - yk and the distance between pixel-to-right-and-up and ideal pixel is:

d2 = (yk +1) - y

So we can simply choose subsequent pixels based on the following:

if (d1<=d2) then choose pixel-to-right: ( xk+1, yk )

if (d1>d2) then choose pixel-to-right-and-up: ( xk+1, yk+1 )

In order to develop a fast way of doing this, we will not be comparing these values in such a manner;

instead we will create a decision variable that can be used to quickly determine which point to use.

Instead of comparing the two values to each other, we can simply evaluate d1-d2 and test the sign to

determine which to choose. If d1 > d2 then d1-d2 will be strictly positive, and if d1-d2 is strictly positive, we

will choose pixel-to-right-and-up. If d1-d2 is negative or zero, we will choose pixel-to-right. In addition to

this optimization, this Algorithm suggests to optimize more. If we evaluate d1-d2 as follows:

d1-d2 = y - yk - (yk+1 - y) = y - yk - yk+1 + y

Page 22: CG Lab Manual

and now substitute using

y = m*xk+1 + b,

we get ,

d1-d2 = m*xk+1 + b - yk - yk - 1 + m*xk+1 + b = 2*m*xk+1 - 2*yk + 2*b - 1

The last equation can be reduced by the slope m and substituting as follows:

m = ∆y/∆x

where ∆y = abs(By - Ay) and ∆x = abs(Bx - Ax),

so now we have,

d1-d2 = 2*(∆y/∆x)*xk+1 - 2*yk + 2*b - 1

or if we expand the first term (multiply), then:

d1-d2 = 2*(∆y/∆x)*(xk +1) - 2*yk + 2*b – 1

d1-d2 = 2*(∆y/∆x)*xk + 2*(∆y/∆x) - 2*yk + 2*b - 1

This last equation can be simplified by creating a new decision variable

Pk = ∆x * (d1-d2).

This ∆x will remove the divisions (all integer operations for faster and efficient computing) and will still

keep the same sign for the decision because ∆x variable is always positive (∆x = abs (Bx - Ax) -> absolute

value).

If we now evaluate a new decision variable Pk, we get:

Pk = ∆x * (2*(∆y/∆x)*xk + 2*(∆y/∆x) - 2*yk + 2*b - 1 )

or further:

Pk = 2*∆y*xk + 2*∆y - 2*∆x*yk + 2*∆x*b - ∆x

If we now rearrange the terms in the last equation, we get:

Pk = 2*∆y*xk - 2*∆x*yk + 2*∆y + 2*∆x*b - ∆x

or

Pk = 2*∆y*xk - 2*∆x*yk + c

Where c is always constant value (it depends only on the input endpoints) and is equal to 2*∆y + ∆x*(2*b

- 1)

Using described approach, decision variable can be computed very efficiently, but it still requires

evaluation of Pk for each point (pixel) along a line. Since line entity is linear in its nature, Pk change will

be linear as well; therefore we can evaluate subsequent Pk values incrementally by finding a constant

change in Pk for each subsequent pixel. By evaluating an incremental change of the decision function

P = ∆P = Pk+1 - Pk

we can evaluate by substitution ∆P as follows:

Pk+1 - Pk = 2*∆y*xk+1 - 2*∆x*yk+1 + c - 2*∆y*xk + 2*∆x*yk - c

= 2*∆y*xk+1 - 2*∆y*xk - 2*∆x*yk+1 + 2*∆x*yk

= 2*∆y*(xk+1 - xk) - 2*∆x*(yk+1 - yk)

Since we are processing pixel one by one in the x direction, the change in the x direction is (xk+1 - xk) = 1,

so if we substitute this into our ∆P derivation, we get:

Pk+1 - Pk = 2*∆y - 2*∆x*(yk+1 - yk)

For the y direction, there are two possibilities; the term (yk+1 - yk) can be only 0 or 1, depending on Pk. If

we choose pixel-to-right or pixel-to-right-and-up, so now our ∆P derivation looks like:

Pk+1 - Pk = 2*∆y - 2*∆x*(0) = 2*∆y

Pk+1= Pk +2*∆y

if pixel-to-right is chosen.

Pk+1 - Pk= 2*∆y - 2*∆x*(1) = 2*∆y - 2*∆x

if pixel-to-right-and-up is chosen.The only remaining thing is to decide what the initial value of P0 is. This

can be decided by evaluating equation

Pk = 2*∆y*xk - 2*∆x*yk + 2*∆y + ∆x*(2*b - 1),

Page 23: CG Lab Manual

so for zero (k = 0, xk = 0 and yk = 0), we get:

P0 = 2*∆y*x0 - 2*∆x*y0 + 2*∆y + ∆x*(2*b - 1)

From line equation at the starting pixel y0 = m*x0 + b we get term for b intercept b = y0 - m*x0.

Substituting b and slope m = ∆y/∆x into equation P0 we get:

P0 = 2*∆y*x0 - 2*∆x*y0 + 2*∆y + ∆x*(2*(y0 - (∆y/∆x)*x0) - 1)

= 2*∆y*x0 - 2*∆x*y0 + 2*∆y + 2*∆x*(y0 - (∆y/∆x)*x0) - ∆x

= 2*∆y*x0 - 2*∆x*y0 + 2*∆y + 2*∆x*y0 - 2*∆y*x0 - ∆x

P0 = 2*∆y - ∆x

Bresenham’s Line Algorithm

Begin {Bresenham for lines with slope between 0 and 1}

a := ABS(xend - xstart);

b := ABS(yend - ystart);

d := 2*b - a;

Incr1 := 2*(b-a);

Incr2 := 2*b;

If xstart > xend Then Begin

x := xend;

y := yend

End

Else Begin

x := xstart;

y := ystart

End;

For I: = 0 to a Do Begin

Plot(x,y);

x := x + 1;

If d 0 Then Begin

y := y + 1;

d := d + incr1

End

Else

d := d + incr2

End {For Loop}

End; {Bresenham}

Source Code: -

/*

-------------------------------------------------------------------------

Bresenham line drawing algorithm

-------------------------------------------------------------------------

*/

# include <iostream.h>

# include <conio.h>

# include <graphics.h>

# include <math.h>

char IncFlag;

void Bresenham(int x1,int x2,int y1,int y2);

void DrawLine(int X,int Y,int End,int PInc,int NInc,int P,int XInc,int YInc);

void main()

Page 24: CG Lab Manual

{

int gDriver=DETECT, gMode;

int x1,x2,y1,y2;

void Bresenham(int,int,int,int);

initgraph(&gDriver,&gMode,"c:\\tc\\bgi");

cout<<endl<<"x1 : ";

cin>>x1;

cout<<endl<<"y1 : ";

cin>>y1;

cout<<endl<<"x2 : ";

cin>>x2;

cout<<endl<<"y2 : ";

cin>>y2;

line(320,0,320,480);

line(0,240,640,240);

Bresenham(x1,x2,y1,y2);

getch();

}

void Bresenham(int x1,int x2,int y1,int y2)

{

int S,O,End;

int P;

int dx = abs(x1 - x2);

int dy = abs(y1 - y2);

float Slope;

int PInc,NInc,XInc,YInc;

if (dx == 0) //Slope Infinite

{

}

else

{

Slope = (float)(y1 - y2) / (x1 - x2);

if (Slope>-1 && Slope<1)

{

IncFlag = 'X';

PInc = 2 * (dy - dx);

NInc = 2 * dy;

P = 2 * dy - dx;

if (x1>x2)

{

S = x2;

O = y2;

End = x1;

}

else

{

S = x1;

O = y1;

Page 25: CG Lab Manual

End = x2;

}

// DrawLine(x,y,End,PInc,NInc,P,XInc,YInc);

}

else

{

IncFlag = 'Y';

PInc = 2 * (dx - dy);

NInc = 2 * dx;

P = 2 * dx - dy;

if (y1 > y2)

{ O = x2;

S = y2;

End = y1;

}

else

{ O = x1;

S = y1;

End = y2;

}

}

if (IncFlag == 'X')

putpixel(320+S,240-O,12);

else

putpixel(320+O,240-S,12);

while (S <= End)

{

S++;

if (P<0)

P = P + NInc;

else

{

P = P + PInc;

if (Slope>0.0)

O++;

else

O--;

}

if (IncFlag == 'X')

putpixel(320+S,240-O,12);

else

putpixel(320+O,240-S,12);

}

}

}

Advantages: This is faster method then DDA because here we have to do only integer calculation.

Disadvantages: Accumulation of error every time due to rounding in equation.

Page 26: CG Lab Manual

Practical 5

Aim: Implement Mid-point Circle algorithm

Software Required: Turbo C/C++ Compiler,

Knowledge Required: Basic ‘C/C++’ language programming

Theory/Logic:

If a circle is to be plotted efficiently, the use of trigonometric and power functions must be avoided. And

as with the generation of a straight line, it is also desirable to perform the calculations necessary to find

the scan-converted points with only integer addition, subtraction, and multiplication by powers of 2.

Midpoint circle algorithm allows these goals to be met.

Scan-converting a circle using midpoint algorithm works are follows. If the eight-way symmetry of a

circle is used to generate a circle, points will only have to be generated through a 45 angle. And, if points

are generated from 90 to 45, moves will be made only in the +x and -y directions (see Figure 1).

-y45

+x

Figure 1 Circle scan-converted with Midpoint algorithm.

The best approximation of the true circle will be described by those pixels in the raster that fall the least

distance from the true circle. Examine Figures 3(a) and 3(b). Notice that if points are generated from 90

and 45, each new point closest to the true circle can be found by taking either of two actions: (1) move in

the x direction one unit or (2) move in the x direction one unit and move in the negative y direction one

unit. Therefore, a method of selecting between these two choices is all that is necessary to find the points

closest to the true circle.

Due to the 8-way symmetry, we need to concentrate only on the are from (0, r) to (r / 2 r / 2, ) . Here

we assume r to be an integer.

Suppose that P(xi, yi) has been selected as closest to the circle. The choice of the next pixel is between U

and D (Fig.2).

P(xi, yi) U(xi + 1, yi )

D(xi +1, yi - 1)

M

(b)

Page 27: CG Lab Manual

Figure 2

Let F(x, y) = x2 + y

2 - r

2. We know that

F(x, y) = 0 then (x, y) lies on the circle

> 0 then (x, y) is outside the circle

< 0 then (x, y) is inside the circle

Let M be the midpoint of DU. If M is outside then pixel D is closer to the circle, and if M is

inside, pixel U is closer to the circle.

Let dold = F(xi+1, yi 12 )

= (xi + 1)2 + (yi 1

2 )2 r

2

* If dold < 0, then U (xi+1, yi) is chosen and the next midpoint will be one increment over x.

Thus

dnew = F(xi+2, yi 12 )

= dold + 2xi + 3

The increment in d is

dU = dnew dold = 2xi + 3

* If dold 0, M is outside the circle and D is chosen. The new midpoint will be one increment over x and

one increment down in y:

dnew = F (xi + 2, yi 32 )

= dold + 2xi 2yi + 5

The increment in d is therefore

dD = dnew dold = 2(xi yi ) + 5

Since the increments dU and dD are functions of (xi , yi), we call point P(xi, yi) the point of evaluation.

Initial point: (0, r). The next midpoint lies at (1, r- 12 ) and so

F (1, r 12 ) = 1 + (r 1

2 )2 r

2 = 5

4 r

(0, r)

O

(r / 2 r / 2, )

(a)

P ( x i , y i ) U ( x i + 1 , y i )

D ( x i + 1 , y i - 1 )

M

( b )

Figure 3 Midpoint Circle Algorithm

Midpoint Circle Algorithm

h = 1 r ; /*initialization */

x = 0;

y = r;

Plot Point (x, y);

While y > x

if h < 0 then /* Select U */

dU = 2*x + 3;

h = h + dU;

x = x + 1;

Page 28: CG Lab Manual

else /* Select D */

dD = 2*(x y) + 5;

h = h dD;

x = x + 1;

y = y 1;

endif

End While

Source Code: -

/*

-------------------------------------------------------------------------

Midpoint Circle Drawing

-------------------------------------------------------------------------

*/

# include <iostream.h>

# include <conio.h>

# include <graphics.h>

# include <math.h>

void Circle(int Radius,int xC,int yC);

void main()

{

int gDriver=DETECT, gMode;

initgraph(&gDriver,&gMode,"c:\\tc\\bgi");

int Radius, xC, yC;

cout<< endl << "Enter Center point coordinates...";

cout<<endl<<" Xc : ";

cin>>xC;

cout<<endl<<" Xc : ";

cin>>yC;

cout<<endl<<"Radius : ";

cin>>Radius;

cleardevice();

Circle(Radius,xC,yC);

getch();

return;

}

void Circle(int Radius,int xC,int yC)

{

int P;

int x,y;

void Draw(int x,int y,int xC,int yC);

P = 1 - Radius;

x = 0;

y = Radius;

Draw(x,y,xC,yC);

while (x<=y)

{

x++;

if (P<0)

Page 29: CG Lab Manual

{

P += 2 * x + 1;

}

else

{

P += 2 * (x - y) + 1;

y--;

}

Draw(x,y,xC,yC);

}

}

void Draw(int x,int y,int xC,int yC)

{

putpixel(xC + x,yC + y,12);

putpixel(xC + x,yC - y,12);

putpixel(xC - x,yC + y,12);

putpixel(xC - x,yC - y,12);

putpixel(xC + y,yC + x,12);

putpixel(xC - y,yC + x,12);

putpixel(xC + y,yC - x,12);

putpixel(xC - y,yC - x,12);

}

Advantage: This is faster method to draw a circle then that of conventional method.

Disadvantages: Accumulation of error at every step because of rounding

Page 30: CG Lab Manual

Practical 6

Aim: Implement Mid-point Ellipse algorithm

Software Required: Turbo C/C++ Compiler

Knowledge Required: Basic ‘C/C++’ language programming

Theory/Logic:

Ellipse is different from the circle. Ellipse is drawn as using similar algorithm with different direction of

sampling. As shown in figure ellipse is divided in two regions.

In Region 1:

Sampling is done in X-Direction

Choosing of pixel between ((xxkk++11,, yykk)),, oorr ((xxkk++11,, yykk--11))

MMiidd ppooiinntt:: ((xxkk++11,, yykk--00..55))

In Region 2:

Sampling is done in Y-Direction

Choosing of pixel between ((xxkk,, yykk--11)),, oorr ((xxkk++11,, yykk--11))

MMiidd ppooiinntt:: ((xxkk++00..55,, yykk--11))

Decision Parameters for drawing ellipse:

In Region 1:

In Region 2:

With –ve(Negative) P1k

Mid-Point is inside

Choose Pixel(Xk+1,Yk)

With –ve(Negative) P2k

Mid-Point is inside

Choose Pixel(Xk+1,Yk-1)

With +ve(Positive) P1k

Mid-Point is outside

Choose Pixel(Xk+1,Yk-1)

With +ve(Positive) P2k

Mid-Point is outside

Choose Pixel(Xk,Yk-1)

Source Code: -

/* -------------------------------------------------------------

MidEllipse

------------------------------------------------------------- */

#include<stdio.h>

#include<conio.h>

#include<graphics.h>

#include<math.h>

Slope

= -1

Region

1 Region

2

21,11 kkek yxfp 1,2 2

1 kkek yxfp

Page 31: CG Lab Manual

void disp();

float x,y;

int xc,yc;

void main()

{ int gd=DETECT,gm;

int a,b;

float p1,p2;

clrscr();

initgraph(&gd,&gm,"c:\\tc\\bgi");

printf("Enter the Values for XC, YC, a, b\n");

scanf("%d%d",&xc,&yc);

scanf("%d%d",&a,&b);

x=0;y=b;

disp();

p1=(b*b)-(a*a*b)+(a*a)/4;

while((2.0*b*b*x)<=(2.0*a*a*y))

{ x++;

if(p1<=0)

p1=p1+(2.0*b*b*x)+(b*b);

else

{

y--;

p1=p1+(2.0*b*b*x)+(b*b)-(2.0*a*a*y);

}

disp();

x=-x;

}

x=a;

y=0;

disp();

p2=(a*a)+2.0*(b*b*a)+(b*b)/4;

while((2.0*b*b*x)>(2.0*a*a*y))

{ y++;

if(p2>0)

p2=p2+(a*a)-(2.0*a*a*y);

else

{ x--;

p2=p2+(2.0*b*b*x)-(2.0*a*a*y)+(a*a);

}

disp();

y=-y;

}

getch();

closegraph();

}

void disp()

{ putpixel(xc+x,yc+y,10);

putpixel(xc-x,yc+y,10);

putpixel(xc+x,yc-y,10);

putpixel(xc+x,yc-y,10);

}

Page 32: CG Lab Manual

Practical 7

Aim: Implement Polygon Filling using Flood Fill and Boundary Fill algorithm

Software Required: C/C++

Knowledge Required: Basic ‘C’ language programming.

Theory/logic:-

1. Boundary Fill Algorithm: -

This method of area filling is starts with selecting a pixel which is located inside the region to be

filled. For this selected pixel, pixel is colored then its neighboring pixels are selected as new pixels to

be colored until the boundary pixel arrives, here it is to be assumed that boundary pixel is colored with

different color than color of region.

There are two methods for proceeding of Neighboring Pixels:

1. 4 connected pixels

2. 8 connected pixels

Procedure BoundaryFill(x, y, FillColor, BoundaryColor: integer)

If (getpixel(x,y) not BoundaryColor ) And (getpixel(x, y) not FillColor)

setpixel (x, y, FillColor);

BoundaryFill(x+1, y, FillColor, BoundaryColor);

BoundaryFill(x-1, y, FillColor, BoundaryColor);

BoundaryFill(x, y+1, FillColor, BoundaryColor);

BoundaryFill(x, y-1, FillColor, BoundaryColor);

BoundaryFill(x+1, y+1, FillColor, BoundaryColor);

BoundaryFill(x+1, y-1, FillColor, BoundaryColor);

BoundaryFill(x-1, y+1, FillColor, BoundaryColor);

BoundaryFill(x-1, y-1, FillColor, BoundaryColor);

End if

End Procedure

4 Connected 8 Connected

Page 33: CG Lab Manual

Source Code: -

/* ----------------------------------------------------------------

Boundary Fill (8 Connected Point)

---------------------------------------------------------------- */

#include<iostream.h>

#include<stdlib.h>

#include<conio.h>

#include<graphics.h>

#include<dos.h>

class Circle

{

int XCoord;

int YCoord;

int Radius;

void PlotPoint(int,int,int);

public:

Circle()

{

XCoord=0;

YCoord=0;

Radius=0;

}

Circle(int x, int y, int z)

{

XCoord=x;

YCoord=y;

Radius=z;

}

void CircleMidpoint();

void InitGraphs();

void BoundryFill(int,int,int,int);

void BoundryFillRound();

};

void Circle :: InitGraphs()

{

int gMode, gDriver=DETECT;

int errorcode;

initgraph(&gDriver,&gMode,"c:\\tc\\bgi");

errorcode = graphresult();

if (errorcode != grOk) /* an error occurred */

{

cout<<"Graphics error: "<< grapherrormsg(errorcode);

cout<<"Press any key to halt:";

getch();

exit(1); /* return with error code */

}

setbkcolor(3);

}

void Circle :: PlotPoint(int x,int y,int z)

{

Page 34: CG Lab Manual

putpixel(XCoord+x,YCoord+y,z);

putpixel(XCoord-x,YCoord+y,z);

putpixel(XCoord+x,YCoord-y,z);

putpixel(XCoord-x,YCoord-y,z);

putpixel(XCoord+y,YCoord+x,z);

putpixel(XCoord-y,YCoord+x,z);

putpixel(XCoord+y,YCoord-x,z);

putpixel(XCoord-y,YCoord-x,z);

}

void Circle :: CircleMidpoint()

{

int x,y;

int p;

x=0;

y=Radius;

PlotPoint(x,y,15);

p=1-Radius;

while(x<y)

{

if(p<0)

x+=1;

else

{

x+=1;

y-=1;

}

if(p<0)

p=p+2*x+1;

else

{

p=p + 2 *(x-y) + 1;

}

PlotPoint(x,y,15);

}

}

void Circle :: BoundryFillRound()

{

int x,y;

int p;

for(int iCntr=1;iCntr<Radius;iCntr++)

{

x=0;

y=iCntr;

PlotPoint(x,y,5);

p=1-iCntr;

while(x<y)

{

if(p<0)

x+=1;

else

{

Page 35: CG Lab Manual

x+=1;

y-=1;

}

if(p<0)

p=p+2*x+1;

else

{ p=p + 2 *(x-y) + 1;

}

PlotPoint(x,y,5);

}

}

}

void Circle :: BoundryFill(int x, int y,int fill,int bound)

{ int cur;

cur=getpixel(x,y);

if(cur!=bound && cur!= fill)

{ putpixel(x,y,fill);

Circle :: BoundryFill(x+1, y,fill,bound);

Circle :: BoundryFill(x-1, y,fill,bound);

Circle :: BoundryFill(x, y-1,fill,bound);

Circle :: BoundryFill(x, y+1,fill,bound);

Circle :: BoundryFill(x+1, y+1,fill,bound);

Circle :: BoundryFill(x+1, y+1,fill,bound);

Circle :: BoundryFill(x-1, y-1,fill,bound);

Circle :: BoundryFill(x-1, y+1,fill,bound);

}

}

void main()

{ Circle cObj(250,250,42);

cObj.InitGraphs();

cObj.CircleMidpoint();

cObj.BoundryFillRound();

//cObj.BoundryFill(250,250,11,15);

getch();

closegraph();

}

2. Flood Fill Algorithm: -

voidfloodFill4 (int x, int y, int fillcolor, int oldcolor)

{

if (getpixel (x. y) == oldcolor)

{

setcolor (fillcolor);

setpixel (x, y):

floodFill4 (x+l, y, fillColor, oldColor):

floodfill4 (x-1, y, fillcolor, oldcolor);

floodPill4 (x, y+l, fillcolor, oldcolor);

floodFill4 (x, y-1, fillColor, oldcolor);

}

}

Page 36: CG Lab Manual

Source Code: -

/*

----------------------------------------------------------------

Floodfill

----------------------------------------------------------------

*/

# include <stdio.h>

# include <dos.h>

# include <iostream.h>

# include <conio.h>

# include <stdlib.h>

# include <graphics.h>

void FloodFill(int,int,int,int);

void MidPoint(int);

void main()

{ int xCenter=320;

int yCenter=240;

int gDriver = DETECT, gMode, errorcode;

initgraph(&gDriver, &gMode, "c:\\tc\\bgi");

cleardevice();

MidPoint(49);

FloodFill(xCenter+1,yCenter+1,0,8);

getch();

return;

}

void MidPoint(int Radius)

{ int iCntr, x, y,p0;

x=0;

y=Radius;

int xCenter=320;

int yCenter=240;

p0=(5/4)-Radius;

putpixel(xCenter+x,yCenter+y,15);

putpixel(xCenter-x,yCenter+y,15);

putpixel(xCenter+x,yCenter-y,10);

putpixel(xCenter-x,yCenter-y,10);

putpixel(xCenter+y,yCenter+x,12);

putpixel(xCenter-y,yCenter+x,12);

putpixel(xCenter+y,yCenter-x,9);

putpixel(xCenter-y,yCenter-x,9);

while(x<=y)

{ if(p0 < 0)

{ p0=p0 + 2*(x+1) + 1;

x=x+1;

}

else

{ p0=p0 + 2*(x+1) + 1 - 2*(y-1);

x=x+1;

y=y-1;

}

Page 37: CG Lab Manual

putpixel(xCenter+x,yCenter+y,15);

putpixel(xCenter-x,yCenter+y,15);

putpixel(xCenter+x,yCenter-y,10);

putpixel(xCenter-x,yCenter-y,10);

putpixel(xCenter+y,yCenter+x,12);

putpixel(xCenter-y,yCenter+x,12);

putpixel(xCenter+y,yCenter-x,9);

putpixel(xCenter-y,yCenter-x,9);

}

}

void FloodFill(int pointx,int pointy,int OldColor,int NewColor)

{

int Intensity=getpixel(pointx,pointy);

if(Intensity==OldColor)

{

putpixel(pointx,pointy,NewColor);

FloodFill(pointx+1,pointy,OldColor,NewColor);

FloodFill(pointx-1,pointy,OldColor,NewColor);

FloodFill(pointx,pointy+1,OldColor,NewColor);

FloodFill(pointx,pointy-1,OldColor,NewColor);

}

}

Precaution:

1. Stack Overflow of recursion should be controlled

2. Infinite loop control.

Page 38: CG Lab Manual

Practical 8

Aim: Implement program to draw various charts

Software Required: C/C++

Knowledge Required: Basic ‘C’ language programming

Theory/logic:-

Charts are data representation techniques by which any body can visualize the data. It represents the data

in summarized format (the statistical features). Charts have many categories, some them are: PIE chart,

Bar Chart, Line chart, Area Chart, Composition chart .

C programming supports drawing of bar char and 3d bar chart, pie chart with different fill style and

different fill patterns so any body can implements basic chart using c graphics.

0

5

10

15

20

25

30

35

Jan Feb Mar Apr May Jun

1st Qtr

2nd Qtr

3rd Qtr

4th Qtr

BAR CHART PIE CHART

#include<stdio.h>

#include<conio.h>

#include<graphics.h>

#include<stdlib.h>

#include<math.h>

void main()

{ int gd,gm,x[20],y[20],n,x1,n1,val[20],i;

detectgraph(&gd,&gm);

initgraph(&gd,&gm,"c:\\tc\\bgi");

cleardevice();

void barc(int [],int,int);

void piec(int *,int);

/* for barchart n - no.of bars, x1-starting value for x axis, y[i] variable y axis values*/

printf("Enter n and x1\n");

scanf("%d %d",&n,&x1);

printf("Enter all y values\n");

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

{ scanf("%d",&y[i]); }

cleardevice();

line(5,0,5,480);

line(5,478,638,478);

barc(y,x1,n);

getch();

cleardevice();

Page 39: CG Lab Manual

/*for pie chart, n1- no. of sections, val[i] % values for each section, here sum of all val[i] = 100*/

printf("Enter no. of sections\n");

scanf("%d",&n1);

printf("Enter all values\n");

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

{ scanf("%d",&val[i]); }

piec(val,n1);

getch();

}

void barc(int y[20],int x1,int n)

{

int i,j=0,k=0;

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

{ rectangle(x1+j,y[i],x1+j+20,478);

j=j+50;

}

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

{ while(y[i]!=478)

{ line(x1+k+1,y[i],x1+k+19,y[i]);

y[i]=y[i]+1;

}

k+=50;

}

}

void piec(int val[20],int n)

{ int x1[20],y1[20],i,a,j,v[20];

v[0]=0;

val[0]=0;

cleardevice();

circle(320,240,100);

a=4;

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

{ v[i]=val[i]*3.6;

v[i]=v[i]+v[i-1];

x1[i]=100*cos(v[i]*3.14/180)+320;

y1[i]=100*sin(v[i]*3.14/180)+240;

setcolor(a);

line(320,240,x1[i],y1[i]);

// outtextxy(x1[i],y1[i],(char *)val[i]);

a=a+1;

}

/* a=4;

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

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

{ setcolor(a);

arc(320,240,val[i-1],val[i],j);

}

a=a+1;

}*/

}

Page 40: CG Lab Manual

Practical 9

Aim: Implement algorithm of 2D Transformation of an Object

Software Required: Turbo C/C++ Compiler,

Knowledge Required: Basic ‘C/C++’ language programming

Theory/Logic:

The following describes the 2d transformation of a point on a plane

P = ( x , y ) -> P' = ( x' , y' )

Translation

A translation (shift) by Tx in the x direction and Ty in the y direction is

x' = x + Tx

y' = y + Ty

Source Code: - /*

----------------------------------------------------------------

Translation

----------------------------------------------------------------

*/

# include <iostream.h>

# include <conio.h>

# include <graphics.h>

# include <math.h>

char IncFlag;

int PolygonPoints[4][2] ={{10,10},{10,100},{100,100},{100,10}};

float Tx=10;

float Ty=10;

void PolyLine()

{

int iCnt;

cleardevice();

line(0,240,640,240);

line(320,0,320,480);

for (iCnt=0; iCnt<4; iCnt++)

{

line(320+PolygonPoints[iCnt][0],

240-PolygonPoints[iCnt][1],

320+PolygonPoints[(iCnt+1)%4][0],

240-PolygonPoints[(iCnt+1)%4][1]);

}

}

void Translate()

{

int iCnt;

cout<<endl;

for (iCnt=0; iCnt<4; iCnt++)

{

Page 41: CG Lab Manual

PolygonPoints[iCnt][0] += Tx;

PolygonPoints[iCnt][1] += Ty;

}

}

void main()

{

int gDriver = DETECT, gMode;

int iCnt;

initgraph(&gDriver, &gMode, "C:\\TC\\BGI");

PolyLine();

getch();

Translate();

PolyLine();

getch();

}

Scaling: -

A scaling by Sx in the x direction and Sy in the y directions about the origin is

x' = Sx x

y' = Sy y

If Sx and Sy are not equal this results in a stretching along the axis of the larger scale factor.

To scale about a particular point, first translate to the origin, scale, and translate back to the original

position. For example, to scale about the point (x0,y0)

x' = x0 + Sx ( x - x0 )

y' = y0 + Sy ( y - y0 )

Source Code: -

/*

-----------------------------------------------------------

Scaling about Origin

-----------------------------------------------------------

*/

# include <iostream.h>

# include <conio.h>

# include <graphics.h>

# include <math.h>

char IncFlag;

int PolygonPoints[4][2] ={{10,10},{10,100},{100,100},{100,10}};

float Sx=0.5;

float Sy=2.0;

void PolyLine()

{

int iCnt;

cleardevice();

line(0,240,640,240);

line(320,0,320,480);

for (iCnt=0; iCnt<4; iCnt++)

{

line(320+PolygonPoints[iCnt][0],240-PolygonPoints[iCnt][1],

Page 42: CG Lab Manual

320+PolygonPoints[(iCnt+1)%4][0],240-PolygonPoints[(iCnt+1)%4][1]);

}

}

void Scale()

{

int iCnt;

int Tx,Ty;

cout<<endl;

for (iCnt=0; iCnt<4; iCnt++)

{

PolygonPoints[iCnt][0] *= Sx;

PolygonPoints[iCnt][1] *= Sy;

}

}

void main()

{

int gDriver = DETECT, gMode;

int iCnt;

initgraph(&gDriver, &gMode, "C:\\TC\\BGI");

PolyLine();

getch();

Scale();

PolyLine();

getch();

}

Source Code: -

/*

----------------------------------------------------------------

Scaling about Reference Point

----------------------------------------------------------------

*/

# include <iostream.h>

# include <conio.h>

# include <graphics.h>

# include <math.h>

char IncFlag;

int PolygonPoints[4][2] ={{10,10},{10,100},{100,100},{100,10}};

float Sx=0.5;

float Sy=2.0;

int RefX=55;

int RefY=55;

void PolyLine()

{

int iCnt;

cleardevice();

line(0,240,640,240);

line(320,0,320,480);

for (iCnt=0; iCnt<4; iCnt++)

{

Page 43: CG Lab Manual

line(320+PolygonPoints[iCnt][0],240-PolygonPoints[iCnt][1],

320+PolygonPoints[(iCnt+1)%4][0],240-PolygonPoints[(iCnt+1)%4][1]);

}

}

void Scale()

{

int iCnt;

int Tx,Ty;

cout<<endl;

for (iCnt=0; iCnt<4; iCnt++)

{

PolygonPoints[iCnt][0] *= Sx;

PolygonPoints[iCnt][0] += (1-Sx)*RefX;

PolygonPoints[iCnt][1] *= Sy;

PolygonPoints[iCnt][1] += (1-Sy)*RefY;

}

}

void main()

{

int gDriver = DETECT, gMode;

int iCnt;

initgraph(&gDriver, &gMode, "C:\\TC\\BGI");

PolyLine();

getch();

Scale();

PolyLine();

getch();

}

Rotation

Rotation about the origin by an angle A in a clockwise direction is

x' = x cos(A) + y sin(A)

y' = y cos(A) - x sin(A)

To rotate about a particular point apply the same technique as described for scaling, translate the

coordinate system to the origin, rotate, and the translate back.

Source Code: -

/*

-------------------------------------------------------------

Rotate About Origin

-------------------------------------------------------------

*/

# include <iostream.h>

# include <conio.h>

# include <graphics.h>

# include <math.h>

char IncFlag;

int PolygonPoints[4][2] ={{10,100},{110,100},{110,200},{10,200}};

Page 44: CG Lab Manual

void PolyLine()

{

int iCnt;

cleardevice();

line(0,240,640,240);

line(320,0,320,480);

for (iCnt=0; iCnt<4; iCnt++)

{

line(PolygonPoints[iCnt][0],PolygonPoints[iCnt][1],

PolygonPoints[(iCnt+1)%4][0],PolygonPoints[(iCnt+1)%4][1]);

}

}

void Rotate()

{

float Angle;

int iCnt;

int Tx,Ty;

cout<<endl;

Angle = 30.0*(22.0/7.0)/180.0;

for (iCnt=0; iCnt<4; iCnt++)

{

Tx = PolygonPoints[iCnt][0];

Ty = PolygonPoints[iCnt][1];

PolygonPoints[iCnt][0] = (Tx - 320)*cos(Angle) -

(Ty - 240)*sin(Angle) + 320;

PolygonPoints[iCnt][1] = (Tx - 320)*sin(Angle) +

(Ty - 240)*cos(Angle) + 240;

}

}

void main()

{

int gDriver = DETECT, gMode;

int iCnt;

initgraph(&gDriver, &gMode, "C:\\TC\\BGI");

for (iCnt=0; iCnt<4; iCnt++)

{

PolygonPoints[iCnt][0] += 320;

PolygonPoints[iCnt][1] = 240 - PolygonPoints[iCnt][1];

}

PolyLine();

getch();

Rotate();

PolyLine();

getch();

}

Page 45: CG Lab Manual

Source Code: - /*

-------------------------------------------------------------

Rotate about Reference Point

-------------------------------------------------------------

*/

# include <iostream.h>

# include <conio.h>

# include <graphics.h>

# include <math.h>

char IncFlag;

int PolygonPoints[4][2] ={{10,100},{110,100},{110,200},{10,200}};

int RefX = 10;

int RefY = 100;

void PolyLine()

{

int iCnt;

cleardevice();

line(0,240,640,240);

line(320,0,320,480);

for (iCnt=0; iCnt<4; iCnt++)

{

line(PolygonPoints[iCnt][0],PolygonPoints[iCnt][1],

PolygonPoints[(iCnt+1)%4][0],PolygonPoints[(iCnt+1)%4][1]);

}

}

void Translate(int Direction)

{

int iCnt;

for (iCnt=0; iCnt<4; iCnt++)

{

PolygonPoints[iCnt][0] += Direction*RefX;

PolygonPoints[iCnt][1] -= Direction*RefY;

}

}

void Rotate()

{

float Angle;

int iCnt;

int Tx,Ty;

Translate(-1);

cout<<endl;

Angle = 30.0*(22.0/7.0)/180.0;

for (iCnt=0; iCnt<4; iCnt++)

{

Tx = PolygonPoints[iCnt][0];

Ty = PolygonPoints[iCnt][1];

PolygonPoints[iCnt][0] = (Tx - 320)*cos(Angle) -

(Ty - 240)*sin(Angle) + 320;

PolygonPoints[iCnt][1] = (Tx - 320)*sin(Angle) +

(Ty - 240)*cos(Angle) + 240;

}

Translate(1);

}

Page 46: CG Lab Manual

void main()

{

int gDriver = DETECT, gMode;

int iCnt;

initgraph(&gDriver, &gMode, "C:\\TC\\BGI");

for (iCnt=0; iCnt<4; iCnt++)

{

PolygonPoints[iCnt][0] += 320;

PolygonPoints[iCnt][1] = 240 - PolygonPoints[iCnt][1];

}

PolyLine();

getch();

Rotate();

PolyLine();

getch();

}

Reflection

Case : 1 Reflection about the x axis

x' = x

y' = - y

Source Code: - /*

-------------------------------------------------------------

Reflection in x Axis

-------------------------------------------------------------

*/

# include <iostream.h>

# include <conio.h>

# include <graphics.h>

# include <math.h>

char IncFlag;

int PolygonPoints[3][2] ={{10,100},{110,100},{110,200}};

void PolyLine()

{

int iCnt;

cleardevice();

line(0,240,640,240);

line(320,0,320,480);

for (iCnt=0; iCnt<3; iCnt++)

{

line(PolygonPoints[iCnt][0],PolygonPoints[iCnt][1],

PolygonPoints[(iCnt+1)%3][0],PolygonPoints[(iCnt+1)%3][1]);

}

}

void Reflect()

{

float Angle;

int iCnt;

int Tx,Ty;

cout<<endl;

for (iCnt=0; iCnt<3; iCnt++)

Page 47: CG Lab Manual

PolygonPoints[iCnt][1] = (480 - PolygonPoints[iCnt][1]);

}

void main()

{

int gDriver = DETECT, gMode;

int iCnt;

initgraph(&gDriver, &gMode, "C:\\TC\\BGI");

for (iCnt=0; iCnt<3; iCnt++)

{

PolygonPoints[iCnt][0] += 320;

PolygonPoints[iCnt][1] = 240 - PolygonPoints[iCnt][1];

}

PolyLine();

getch();

Reflect();

PolyLine();

getch();

}

Case : 2 Reflection about the y axis

x' = - x

y' = y

Source Code: - /*

-------------------------------------------------------------

Reflection in y Axis

-------------------------------------------------------------

*/

# include <iostream.h>

# include <conio.h>

# include <graphics.h>

# include <math.h>

char IncFlag;

int PolygonPoints[3][2] ={{10,100},{110,100},{110,200}};

void PolyLine()

{ int iCnt;

cleardevice();

line(0,240,640,240);

line(320,0,320,480);

for (iCnt=0; iCnt<3; iCnt++)

{

line(PolygonPoints[iCnt][0],PolygonPoints[iCnt][1],

PolygonPoints[(iCnt+1)%3][0],PolygonPoints[(iCnt+1)%3][1]);

}

}

void Reflect()

{ float Angle;

int iCnt;

int Tx,Ty;

cout<<endl;

for (iCnt=0; iCnt<3; iCnt++)

PolygonPoints[iCnt][0] = (640 - PolygonPoints[iCnt][0]);

}

Page 48: CG Lab Manual

void main()

{

int gDriver = DETECT, gMode;

int iCnt;

initgraph(&gDriver, &gMode, "C:\\TC\\BGI");

for (iCnt=0; iCnt<3; iCnt++)

{

PolygonPoints[iCnt][0] += 320;

PolygonPoints[iCnt][1] = 240 - PolygonPoints[iCnt][1];

}

PolyLine();

getch();

Reflect();

PolyLine();

getch();

}

Case 3: - Reflections about an arbitrary line involve possibly a translation so that a point on the line

passes through the origin, a rotation of the line to align it with one of the axis, a reflection, inverse rotation

and inverse translation.

Source Code: - /*

----------------------------------------------------------------

Reflection on any line.

----------------------------------------------------------------

*/

# include <iostream.h>

# include <conio.h>

# include <graphics.h>

# include <math.h>

char IncFlag;

int PolygonPoints[3][2] =

{{10,100},{110,100},{110,200}};

int x1=10;

int y1=10;

int x2=100;

int y2=100;

void PolyLine()

{

int iCnt;

cleardevice();

line(0,240,640,240);

line(320,0,320,480);

for (iCnt=0; iCnt<3; iCnt++)

{

line(PolygonPoints[iCnt][0],PolygonPoints[iCnt][1],

PolygonPoints[(iCnt+1)%3][0],PolygonPoints[(iCnt+1)%3][1]);

}

}

Page 49: CG Lab Manual

void Reflect()

{

float Angle,Slope,Hx,Hy,B;

int iCnt;

int Tx,Ty;

Angle = atan((y2-y1)/(x2-x1));

Angle *= (M_PI)/180.0;

Slope = tan(Angle);

B = y2 - x2*Slope;

Hx = -B*sin(2.0 * Angle);

Hy = B*(cos(2.0 * Angle)+1);

for (iCnt=0; iCnt<3; iCnt++)

{

Tx = PolygonPoints[iCnt][0];

Ty = PolygonPoints[iCnt][1];

PolygonPoints[iCnt][0] = Tx*cos(2.0*Angle);

+ Ty*sin(2.0*Angle) + Hx;

PolygonPoints[iCnt][0] = Tx*sin(2.0*Angle);

- Ty*cos(2.0*Angle) + Hy;

}

}

void main()

{

int gDriver = DETECT, gMode;

int iCnt;

initgraph(&gDriver, &gMode, "C:\\TC\\BGI");

for (iCnt=0; iCnt<3; iCnt++)

{

PolygonPoints[iCnt][0] += 320;

PolygonPoints[iCnt][1] = 240 - PolygonPoints[iCnt][1];

}

PolyLine();

getch();

Reflect();

PolyLine();

getch();

}

Page 50: CG Lab Manual

Practical-10

Aim: Implementation of Line Clipping Algorithms

Software Required: C/C++

Knowledge Required: Basic ‘C’ language programming.

Theory/logic:

1. Cohen Sutherland Algorithm for Line clipping: -

This algorithm is used to clip the line against given rectangle window. As you proceed around the

window, extending each edge and defining an inside half-space and an outside half-space, nine regions

are created - the eight "outside" regions and the one "inside" region. Each of the nine regions

associated with the window is assigned a 4-bit code to identify the region. Each bit in the code is set to

either a 1(true) or a 0(false). If the region is to the left of the window, the first bit of the code is set to

1. If the region is to the top of the window, the second bit of the code is set to 1. If to the right, the

third bit is set, and if to the bottom, the fourth bit is set. The 4 bits in the code then identify each of

the nine regions as shown below.

For any endpoint ( x , y ) of a line, the code can be determined that identifies which region the endpoint

lies. The code's bits are set according to the following conditions:

The sequence for reading the codes' bits is LRBT (Left, Right, Bottom, Top).

Once the codes for each endpoint of a line are determined, the logical AND operation of the codes

determines if the line is completely outside of the window. If the logical AND of the endpoint codes is not

zero, the line can be trivally rejected. For example, if an endpoint had a code of 1001 while the other

endpoint had a code of 1010, the logical AND would be 1000 which indicates the line segment lies

Page 51: CG Lab Manual

outside of the window. On the other hand, if the endpoints had codes of 1001 and 0110, the logical AND

would be 0000, and the line could not be trivally rejected.

The logical OR of the endpoint codes determines if the line is completely inside the window. If the

logical OR is zero, the line can be trivally accepted. For example, if the endpoint codes are 0000 and

0000, the logical OR is 0000 - the line can be trivally accepted. If the endpoint codes are 0000 and 0110,

the logical OR is 0110 and the line can not be trivally accepted.

Data Structure: none.

Advantage:

Easy to implement.

First check is performed to find whether line is to be accepted or rejected, so no need to do any

calculations if line is to be rejected completely.

Disadvantage:

It is limited to rectangle window only.

Intersection point calculations are required.

Application : In window to viewport transformation, when the region is to be

Clipped, then this algorithm is used to clip the lines.

I/P & O/P: Before Clipping (Input) :

How Algorithm works?

1. Consider the line segment AD. Point A has an outcode of 0000 and point D has an outcode of

1001. The logical AND of these outcodes is zero; therefore, the line cannot be trivally rejected.

Also, the logical OR of the outcodes is not zero; therefore, the line cannot be trivally accepted. The

algorithm then chooses D as the outside point (its outcode contains 1's). By our testing order, we

first use the top edge to clip AD at B. The algorithm then recomputes B's outcode as 0000. With

the next iteration of the algorithm, AB is tested and is trivially accepted and displayed.

2. Consider the line segment EI. Point E has an outcode of 0100, while point I's outcode is 1010. The

results of the trivial tests show that the line can neither be trivally rejected or accepted. Point E is

determined to be an outside point, so the algorithm clips the line against the bottom edge of the

window. Now line EI has been clipped to be line FI. Line FI is tested and cannot be trivially

accepted or rejected. Point F has an outcode of 0000, so the algorithm chooses point I as an

outside point since its outcode is1010. The line FI is clipped against the window's top edge,

Page 52: CG Lab Manual

yielding a new line FH. Line FH cannot be trivally accepted or rejected. Since H's outcode is

0010, the next iteration of the algorthm clips against the window's right edge, yielding line FG.

The next iteration of the algorithm tests FG, and it is trivially accepted and display.

After Clipping (Output): - After clipping the segments AD and EI, the result is that only the line

segment AB and FG can be seen in the window.

Source Code: - /*

----------------------------------------------------------------

Cohen Sutherland Algorithm for Line clipping

----------------------------------------------------------------

*/

#include <iostream.h>

#include <graphics.h>

#include <stdio.h>

#include <conio.h>

FILE *fp;

class clipping

{private:

int x;

int y;

int code[4];

public:

clipping();

void getxy(char p[5]);

void encode(int left,int right,int bottom,int top);

int getcode(int k);

float getx(void);

float gety(void);

friend int accept(clipping p1,clipping p2);

friend int reject(clipping p1,clipping p2);

friend void swap_points(clipping &p1,clipping &p2);

int point_inside(void);

void clipping::operator =(clipping p2);

void changex(int winy,float m);

void changey(int winx,float m);

};

clipping::clipping()

{ int i;

x = 0;

Page 53: CG Lab Manual

y = 0;

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

code[i] = 0;

}

float clipping::getx(void)

{ return(x);

}

float clipping::gety(void)

{ return(y);

}

void clipping::getxy(char p[5])

{ cout << "\nEnter the coordinates of point " << p;

cout << "\nX :- ";

fscanf(fp,"%d",&x);

cout << "\nY :- ";

fscanf(fp,"%d",&y);

}

void clipping::encode(int left,int right,int bottom,int top)

{ if(x < left)

code[0] = 1;

else

code[0] = 0;

if (x > right)

code[1] = 1;

else

code[1] = 0;

if (y > bottom)

code[2] = 1;

else

code[2] = 0;

if (y < top)

code[3] = 1;

else

code[3] = 0;

}

int clipping::getcode(int k)

{ if (code[k] == 1)

return(1);

return(0);

}

int accept(clipping p1,clipping p2)

{ int k;

for(k=0;k<4;k++)

if (p1.getcode(k) || p2.getcode(k))

return(0);

return(1);

}

int reject(clipping p1,clipping p2)

{ int k;

for(k=0;k<4;k++)

if (p1.getcode(k) && p2.getcode(k))

return(1);

return(0);

}

Page 54: CG Lab Manual

int clipping::point_inside(void)

{ if (code[0] || code[1] || code[2] || code[3])

return(0);

return(1);

}

void clipping::operator =(clipping p2)

{ int i;

x = p2.x;

y = p2.y;

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

code[i] = p2.code[i];

}

void swap_points(clipping &p1,clipping &p2)

{ clipping tmp;

tmp = p1;

p1 = p2;

p2 = tmp;

}

void clipping::changex(int winy,float m)

{ x = x + (winy - y) / m;

y = winy;

}

void clipping::changey(int winx,float m)

{ y = y + (winx - x) * m;

x = winx;

}

void main()

{ int driver = DETECT,mode;

initgraph(&driver,&mode,"c:\\tc\\bgi");

clipping p1,p2,tmp;

int left,top,right,bottom,done=0,draw=0;

float m;

fp = fopen("cohensut.in","r");

clearviewport();

p1.getxy("p1");

p2.getxy("p2");

left = getmaxx() / 2 - 50;

right = getmaxx() / 2 + 50;

bottom = getmaxy() / 2 + 50;

top = getmaxy() / 2 - 50;

clearviewport();

rectangle(left,top,right,bottom);

line(p1.getx(),p1.gety(),p2.getx(),p2.gety());

while(done == 0)

{

p1.encode(left,right,bottom,top);

p2.encode(left,right,bottom,top);

if (accept(p1,p2))

{

done = 1;

draw = 1;

}

else if (reject(p1,p2))

{

done = 1;

}

Page 55: CG Lab Manual

else

{

if (p1.point_inside())

swap_points(p1,p2);

m = (p2.gety() - p1.gety()) / (p2.getx() - p1.getx());

if(p1.getcode(0))

p1.changey(left,m);

else if(p1.getcode(1))

p1.changey(right,m);

else if (p1.getcode(2))

p1.changex(bottom,m);

else if (p1.getcode(3))

p1.changex(top,m);

}

cout << "\nPress any key to continue...\n";

getch();

clearviewport();

rectangle(left,top,right,bottom);

line(p1.getx(),p1.gety(),p2.getx(),p2.gety());

}

if (draw)

{

rectangle(left,top,right,bottom);

line(p1.getx(),p1.gety(),p2.getx(),p2.gety());

}

getch();

}

Conclusion: Cohen Sutherland algorithm is easy to implement algorithm to clip the given line against

rectangle window.

2. Liang Barsky Algorithm for Line Clipping: -

LBA Algorithm:

1. Read two endpoints of the line say P1(X1, Y1) and p2(X2, Y2).

2. Read two corners of the window,(left-top and right-bottom) say(Xwmin,Ywmax,Xwmax,Ywmin).

3. Calculate the values of parameters Pi and Qi for i=1,2,3,4 such that

P1 = -∆X Q1 = X1 - Xwmin

P2 = ∆X Q2 = Xwmax - X1

P3 = -∆Y Q3 = Y1 - Ywmin

P4 = ∆Y Q4 = Ywmax - Y1

4. If Pi = 0, then

{

The line is parallel to ith

boundary.

Now, if Qi<0, then

{

Line is completely outside the boundary; hence discard the line segment and goto

stop.

}

Else

{

Page 56: CG Lab Manual

Check wether the line is horizonatal or vertical and accordingly check the line

endpoint with corresponding bounadaries. If line endpoint/s lie within the bounaded area then to

draw line otherwise use boundary co-ordinates to draw line. Go to stop.

}

}

5. Initialize value for t1, t2 as t1 = 0, t2 = 1.

6. Calculate values for Qi/Pi for i=1,2,3,4

7. Select value of Qi/Pi where Pi<0 and assign maximum out of them as t1.

8. Select value of Qi/Pi where Pi>0 and assign minimum out of them as t2.

9. If(t1<t2)

{

Calutte the endpoint of the clipped line as follows:

XX1 = X1+t1∆X

XX2 = X1+t2∆X

YY1 = Y1+t1∆Y

YY2 = Y1+t2∆Y

Draw line (XX1, YY1, XX2, and YY2)

}

10. Stop.

Source Code: - /*

----------------------------------------------------------------

Liang Barsky Algorithm for Line Clipping

----------------------------------------------------------------

*/

#include<stdio.h>

#include<conio.h>

#include<graphics.h>

#include<iostream.h>

#include<stdlib.h>

#include<math.h>

#define false 0

#define true 1

FILE *fin = fopen ("cosuth.in","r");

float u1,u2,dx,dy;

float t1,t2,t3,t4,t5,t6;

class point

{

int x,y;

int code[4];

public:

void getxy()

{

fscanf(fin,"%d %d",&x,&y);

}

void putxy(int x1,int y1)

{

x = x1;

y = y1;

Page 57: CG Lab Manual

}

void friend clipline(point p1,point p2);

int friend cliptest(float p,float q,float *u1,float *u2);

void friend drawline(point p1,point p2);

}p1,p2,pt[20],winmin,winmax;

void clipline(point p1,point p2)

{

rectangle(80,420,426,160);

u1 = 0.0;

u2 = 1.0;

dx = p2.x - p1.x;

t1 = p1.x - winmin.x;

t2 = winmax.x - p1.x;

t3 = p1.y - winmin.y;

t4 = winmax.y - p1.y;

t5 = -1 * dx;

if (cliptest(t5,t1,&u1,&u2) == 1)

{

if (cliptest(dx,t2,&u1,&u2) == 1)

{

dy = float(p2.y - p1.y);

t6 = -1 * dy;

if (cliptest(t6,t3,&u1,&u2) == 1)

{

if (cliptest(dy,t4,&u1,&u2) == 1)

{

if (u1 > 0.0)

{

(int)p1.x = p1.x + (u1 * dx);

(int)p1.y = p1.y + (u1 * dy);

}

if (u2 < 1.0)

{

(int)p2.x = p1.x + (u2 * dx);

(int)p2.y = p1.y + (u2 * dy);

}

}

}

}

}

drawline(p1,p2);

getch();

}

int cliptest(float p,float q,float *u1,float *u2)

{

float r;

int flag;

flag = 1;

Page 58: CG Lab Manual

if (p < 0.0)

{

r = (float) q / p;

if (r > *u2)

{

flag = 0;

}

else

{

if (r > *u1)

{

*u1 = r;

}

}

}

else

{

if (p > 0.0)

{

r = (float) q / p;

if (r < *u1)

{

flag = 0;

}

else

{

if (r < *u2)

{

*u2 = r;

}

}

}

else

{

if (q < 0.0)

{

flag = 0;

}

}

}

return(flag);

}

void drawline(point p1,point p2)

{

line(p1.x,p1.y,p2.x,p2.y);

}

void main()

{

int drv=DETECT,mode,totalpoint,i;

clrscr();

Page 59: CG Lab Manual

printf("\nHow many line will be on the screen : ");

fscanf(fin,"%d",&totalpoint);

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

{

printf("\nEnter their x and y coordinates of %d point:\n",i+1);

pt[i].getxy();

}

initgraph(&drv,&mode,"c:\\Borlandc\\bgi");

winmin.putxy(80,160);

winmax.putxy(420,426);

rectangle(80,420,426,160);

i = 0;

do

{

drawline(pt[i],pt[i+1]);

i++;

}

while(i < totalpoint-1);

getch();

clearviewport();

i = 0;

do

{

clipline(pt[i],pt[i+1]);

i++;

}

while(i < totalpoint-1);

getch();

}

3. Nicol Lee Nicol Algorithm for Line Clipping: -

Write NLN algorithm of particular position of P1 we set up the regions for P2 as listed below:

Case1: for P1 in window: Region is L, T, R, and B

Case 2: for P1 iin edge region: Regions are L, LT, LR and LB

Case3: for P1 in corner region: Region is T, L, TB, LR, or LB

L – Ray intersections left boundary

T – Ray intersections top boundary

B – Ray intersections bottom boundary

R – Ray intersections right boundary

LT – Ray intersections left and top boundary

LR – Ray intersections left and right boundary

LB – Ray intersections left and bottom boundary

TR – Ray intersections top and right boundary

TB – Ray intersections top and bottom boundary

Page 60: CG Lab Manual

Source Code: -

/*

----------------------------------------------------------------

Nicol Lee Nicol Algorithm for Line Clipping

----------------------------------------------------------------

*/

# include <stdio.h>

# include <conio.h>

# include <graphics.h>

# include <math.h>

int xmin,ymin,xmax,ymax;

void main()

{

int x1,y1,x2,y2;

int gdriver = DETECT, gmode, errorcode;

int findRegionP1(int,int);

void clipline1(int,int,int,int);

void clipline2(int,int,int,int);

void clipline3(int,int,int,int);

int ch;

float m;

clrscr();

printf("\nEnter the xmin:->");

scanf("%d",&xmin);

printf("\nEnter the ymin:->");

scanf("%d",&ymin);

printf("\nEnter the xmax:->");

scanf("%d",&xmax);

printf("\nEnter the ymax:->");

scanf("%d",&ymax);

initgraph(&gdriver, &gmode, "C:\\TC\\BGI");

setcolor(15);

rectangle(xmin,ymin,xmax,ymax);

printf("Enter the x1:->");

scanf("%d",&x1);

printf("Enter the y1:->");

scanf("%d",&y1);

printf("Enter the x2:->");

scanf("%d",&x2);

printf("Enter the y2:->");

scanf("%d",&y2);

setcolor(12);

line(x1,y1,xmin,ymin);

line(x1,y1,xmax,ymin);

line(x1,y1,xmax,ymax);

line(x1,y1,xmin,ymax);

getch();

setcolor(3);

line(x1,y1,x2,y2);

getch();

ch=first_end_point_region(x1,y1);

switch(ch)

Page 61: CG Lab Manual

{

case 1:

clipline1(x1,y1,x2,y2);

break;

case 2:

clipline2(x1,y1,x2,y2);

break;

case 3:

clipline3(x1,y1,x2,y2);

break;

default:

printf("\nInvalid select of the option: ");

}

getch();

}

int first_end_point_region(int x,int y)

{

/* u have two equations:-

xmin <= x <= xmax;

ymin <= y <= ymax; */

if(x>=xmin && x<=xmax && y>=ymin && y<=ymax)

return 1;

else if(x<xmin && y>=ymin && y<=ymax)

return 2;

else if(x<=xmin && y<=ymin)

return 3;

else

return 0;

}

/* point p1 is inside the clip window */

void clipline1(int x1,int y1,int x2,int y2)

{

int draw=1;

float m,m1,m2,m3,m4;

int nx1,ny1,nx2,ny2;

/* calculate slopes for all the lines passing thru vertices

and including the input line :- */

m=((float)(y2-y1))/(x2-x1);

m1=((float)(ymin-y1))/(xmin-x1);

m2=((float)(ymin-y1))/(xmax-x1);

m3=((float)(ymax-y1))/(xmax-x1);

m4=((float)(ymax-y1))/(xmin-x1);

nx1=x1;

ny1=y1;

// point p2 is on top

if(((abs(m)>=m1 && x2<x1) || (abs(m)>abs(m2) && x2>x1)) && y1>y2)

{

// point p2 is also inside clip window

if(y2>ymin)

{

Page 62: CG Lab Manual

nx2=x2;

ny2=y2;

}

// point p2 is outside clip window

else

{

ny2=ymin;

nx2=x1+(ymin-y1)/m;

}

}

// point p2 is on right side of clip window

else if(m>m2 && m<m3 && x2>=xmax)

{

// point p2 is inside clip window

if(x2<xmax)

{

nx2=x2;

ny2=y2;

}

// point p2 is outside clip window

else

{

nx2=xmax;

ny2=y1+(xmax-x1)*m;

}

}

// point p2 is on bottom side of clip window

else if((abs(m)>=m3 && x2>x1) || (abs(m)>abs(m4) && x2<x1))

{

// point p2 is inside clip window

if(y2<ymax)

{

nx2=x2;

ny2=y2;

}

// point p2 is outside clip window

else

{

ny2=ymax;

nx2=x1+(ymax-y1)/m;

}

}

// point p2 is on left side of clip window

else if(m>m4 && m<m1)

{

// point p2 is inside the clip window

if(x2>xmin)

{

nx2=x2;

ny2=y2;

}

// point p2 is outside the clip window

else

{

nx2=xmin;

ny2=y1+(xmin-x1)*m;

Page 63: CG Lab Manual

}

}

else

draw=0;

getch();

cleardevice();

setcolor(18);

rectangle(xmin,ymin,xmax,ymax);

if(draw)

{

setcolor(12);

line(x1,y1,xmin,ymin);

line(x1,y1,xmax,ymin);

line(x1,y1,xmax,ymax);

line(x1,y1,xmin,ymax);

setcolor(5);

line(nx1,ny1,nx2,ny2);

}

}

/* Point p1 is in the edge region */

void clipline2(int x1,int y1,int x2,int y2)

{

int draw=1;

float m,m1,m2,m3,m4;

int nx1,ny1,nx2,ny2;

m=((float)(y2-y1))/(x2-x1);

m1=((float)(ymin-y1))/(xmin-x1);

m2=((float)(ymin-y1))/(xmax-x1);

m3=((float)(ymax-y1))/(xmax-x1);

m4=((float)(ymax-y1))/(xmin-x1);

// Point p2 is in Left-Top region

if(m>m1 && m<m2)

{

// Point p2 is inside the clip window

if(y2>ymin)

{

nx1=xmin;

ny1=y1+m*(xmin-x1);

nx2=x2;

ny2=y2;

}

// Point p2 is outside the clip window

else

{

nx1=xmin;

ny1=y1+m*(xmin-x1);

ny2=ymin;

nx2=x1+(ymin-y1)/m;

}

}

// Point p2 is in Left-Right region

else if(m>m2 && m<m3)

{

Page 64: CG Lab Manual

// Point p2 is inside the clip window

if(x2<xmax)

{

nx1=xmin;

ny1=y1+m*(xmin-x1);

nx2=x2;

ny2=y2;

}

// Point p2 is outside the clip window

else

{

nx1=xmin;

ny1=y1+m*(xmin-x1);

nx2=xmax;

ny2=y1+(xmax-x1)*m;

}

}

// Point p2 is in Left-Bottom region

else if(m>m3 && m<m4)

{

// Point p2 is inside the clip window

if(y2<ymax)

{

nx1=xmin;

ny1=y1+m*(xmin-x1);

nx2=x2;

ny2=y2;

}

// Point p2 is outside the clip window

else

{

nx1=xmin;

ny1=y1+m*(xmin-x1);

ny2=ymax;

nx2=x1+(ymax-y1)/m;

}

}

else

draw=0;

getch();

cleardevice();

setcolor(18);

rectangle(xmin,ymin,xmax,ymax);

if(draw)

{

setcolor(12);

line(x1,y1,xmin,ymin);

line(x1,y1,xmax,ymin);

line(x1,y1,xmax,ymax);

line(x1,y1,xmin,ymax);

setcolor(5);

line(nx1,ny1,nx2,ny2);

}

}

/* Point p1 is in the Corner Region */

Page 65: CG Lab Manual

void clipline3(int x1,int y1,int x2,int y2)

{

int draw=1;

float m,m1,m2,m3,m4,tm1,tm2;

int nx1,ny1,nx2,ny2;

int flag,t;

tm1=((float)(ymin-y1))/(xmin-x1);

tm2=((float)(ymax-ymin))/(xmax-xmin); //diagonal slope

m=((float)(y2-y1))/(x2-x1);

m1=((float)(ymin-y1))/(xmax-x1);

m2=((float)(ymax-y1))/(xmax-x1);

m3=((float)(ymin-y1))/(xmin-x1);

m4=((float)(ymax-y1))/(xmin-x1);

// Point p1 is towards the left side of the clip window (case2)

if(tm1<tm2)

{

flag=2;

t=m2;

m2=m3;

m3=t;

}

// Point p1 is towards the top side of the clip window (case1)

else

flag=1;

// Point p2 is in the Top-Right region

if(m>m1 && m<m2)

{

// Point p2 is outside the clip window

if(x2>xmax && y2>ymin)

{

ny1=ymin;

nx1=x1+(ymin-y1)/m;

nx2=xmax;

ny2=y1+m*(xmax-x1);

}

// Point p2 is inside the clip window

else if(y2>ymin && x2<xmax)

{

ny1=ymin;

nx1=x1+(ymin-y1)/m;

ny2=y2;

nx2=x2;

}

}

// Point p2 is Left-Right or Top-Bottom region

else if(m>m2 && m<m3)

{

// Point p2 is in Top-Bottom region (case1)

if(flag==1)

{

// Point p2 is outside the clip window

if(y2>=ymax)

{

Page 66: CG Lab Manual

ny1=ymin;

nx1=x1+(ymin-y1)/m;

nx2=x1+(ymax-y1)/m;

ny2=ymax;

}

// Point p2 is inside the clip window

else if(y2>=ymin)

{

ny1=ymin;

nx1=x1+(ymin-y1)/m;

nx2=x2;

ny2=y2;

}

}

// Point p2 is in Left-Right region (case2)

else

{

// Point p2 is outside the clip window

if(x2>=xmax)

{

nx1=xmin;

ny1=y1+m*(xmin-x1);

nx2=xmax;

ny2=y1+m*(xmax-x1);

}

// Point p2 is inside the clip window

else if(x2>=xmin)

{

nx1=xmin;

ny1=y1+m*(xmin-x1);

nx2=x2;

ny2=y2;

}

}

}

// Point p2 is in Left-Bottom region

else if(m>m3 && m<m4)

{

// Point p2 is outside the clip window

if(y2>=ymax)

{

nx1=xmin;

ny1=y1+m*(xmin-x1);

nx2=x1+(ymax-y1)/m;

ny2=ymax;

}

// Point p2 is inside the clip window

else if(y2>=ymin)

{

nx1=xmin;

ny1=y1+m*(xmin-x1);

ny2=y2;

nx2=x2;

}

}

else

Page 67: CG Lab Manual

draw=0;

getch();

cleardevice();

setcolor(18);

rectangle(xmin,ymin,xmax,ymax);

if(draw)

{

setcolor(12);

line(x1,y1,xmin,ymin);

line(x1,y1,xmax,ymin);

line(x1,y1,xmax,ymax);

line(x1,y1,xmin,ymax);

setcolor(5);

line(nx1,ny1,nx2,ny2);

}

}

4. Sutherland Hodgemann Algorithm for Polygon clipping: -

Sutheland Hodgemann Algorithem:

1. Read co-ordinates of all vetices of the polygon.

2. Read co-ordinates of the clipping window.

3. Consider the left edge of the window.

4. Compare the vetices of each edge of the polygon, individually with the clipping plane.

5. Save the resulting intersections and vertices in the new list of vertices according to four

possible relationships between the edge and the clipping boundary discussed earlier.

6. Repeat the step 4 and 5 for remaining edge of the clipping window. Each time the resultant list

of vertices is successively passed to process the next edge of the clipping window.

7. Stop.

Source Code: -

/*

----------------------------------------------------------------

Sutherland Hodgemann Algorithm for Polygon clipping

----------------------------------------------------------------

*/

#include<stdio.h>

#include<conio.h>

#include<iostream.h>

#include<graphics.h>

#define ROUND(a) ((int)(a+0.5))

#define n 4

#define LEFT_EDGE 0x1

#define RIGHT_EDGE 0x2

#define BOTTOM_EDGE 0x4

#define TOP_EDGE 0x8

#define INSIDE(a) (!a)

#define REJECT(a,b) (a&b)

#define ACCEPT(a,b) (!(a|b))

Page 68: CG Lab Manual

typedef struct wcpt2

{

int x,y;

}wcpt2;

typedef struct dcpt

{

int x,y;

}dcpt;

void main()

{

int gd=DETECT,gm;

int left,top,right,bottom;

int x1,x2,y1,y2;

int maxx, maxy;

/* our polygon array */

int poly[10];

void clipline(dcpt,dcpt,wcpt2,wcpt2);

clrscr();

initgraph(&gd,&gm,"c:\\tc30\\bgi");

maxx = getmaxx()/4;

maxy = getmaxy()/4;

poly[0] = 20; /* 1st vertex */

poly[1] = maxy / 2;

poly[2] = maxx - 10; /* 2nd */

poly[3] = 10;

poly[4] = maxx - 50; /* 3rd */

poly[5] = maxy - 20;

poly[6] = maxx / 2; /* 4th */

poly[7] = maxy / 2;

/* drawpoly doesn't automatically close

the polygon, so we close it.

*/

poly[8] = poly[0];

poly[9] = poly[1];

/* draw the polygon */

drawpoly(5, poly);

rectangle(20,25,80,125);

wcpt2 pt1,pt2;

dcpt winmin,winmax;

winmin.x=20;

winmin.y=25;

winmax.x=80;

winmax.y=125;

Page 69: CG Lab Manual

pt1.x=20;

pt1.y=maxy/2;

pt2.x=maxx-10;

pt2.y=10;

// clipline(winmin,winmax,pt1,pt2);

int i=0;

for(int index=0;index<n;index++)

{

if(index==n-1)

{

pt1.x=poly[i];

pt1.y=poly[i+1];

i=0;

pt2.x=poly[i];

pt2.y=poly[i+1];

clipline(winmin,winmax,pt1,pt2);

}

else

{

pt1.x=poly[i];

pt1.y=poly[i+1];

pt2.x=poly[i+2];

pt2.y=poly[i+3];

clipline(winmin,winmax,pt1,pt2);

}

i+=2;

}

pt1.x=poly[i];

pt1.y=poly[i+1];

clipline(winmin,winmax,pt1,pt2);

getch();

}

unsigned char encode(wcpt2 pt,dcpt winmin,dcpt winmax)

{

unsigned char code=0x00;

if(pt.x < winmin.x)

code=code | LEFT_EDGE;

if(pt.x > winmax.x)

code=code | RIGHT_EDGE;

if(pt.y < winmin.y)

code=code | TOP_EDGE;

if(pt.y > winmax.y)

code=code | BOTTOM_EDGE;

return code;

}

void swappts(wcpt2 *p1,wcpt2 *p2)

{

wcpt2 tmp;

tmp = *p1;

*p1 = *p2;

Page 70: CG Lab Manual

*p2 = tmp;

}

void swapcode(unsigned char *c1,unsigned char *c2)

{

unsigned char tmp;

tmp = *c1;

*c1 = *c2;

*c2 = tmp;

}

void clipline(dcpt winmin,dcpt winmax,wcpt2 p1,wcpt2 p2)

{

unsigned char encode(wcpt2,dcpt,dcpt);

unsigned char code1,code2;

int done = 0 , draw = 0;

float m;

void swapcode(unsigned char *c1,unsigned char *c2);

void swappts(wcpt2 *p1,wcpt2 *p2);

while(!done)

{

code1 = encode(p1,winmin,winmax);

code2 = encode(p2,winmin,winmax);

if(ACCEPT(code1,code2))

{

draw = 1;

done = 1;

}

else if(REJECT(code1,code2))

done = 1;

else if(INSIDE(code1))

{

swappts(&p1,&p2);

swapcode(&code1,&code2);

}

if(code1 & LEFT_EDGE)

{

p1.y += (winmin.x - p1.x) * (p2.y - p1.y) / (p2.x -

p1.x);

p1.x = winmin.x;

}

else if(code1 & RIGHT_EDGE)

{

p1.y += (winmax.x - p1.x) * (p2.y - p1.y) / (p2.x -

p1.x);

p1.x = winmax.x;

}

else if(code1 & TOP_EDGE)

{

if(p2.x != p1.x)

p1.x += (winmin.y - p1.y) * (p2.x - p1.x) / (p2.y -

p1.y);

p1.y = winmin.y;

Page 71: CG Lab Manual

}

else if(code1 & BOTTOM_EDGE)

{

if(p2.x != p1.x)

p1.x += (winmax.y - p1.y) * (p2.x - p1.x) / (p2.y -

p1.y);

p1.y = winmax.y;

}

}

if(draw)

{

setcolor(5);

line(p1.x,p1.y,p2.x,p2.y);

}

}