CK's BLOG
this site the web

Windows is suck! Graphics.h is not supported!

I want to run Cohen-Sutherland using C++ from Wikipedia Link:
http://en.wikipedia.org/wiki/Cohen%E2%80%93Sutherland
Using Turbo C++ but still got an issue that we cannot run application with header file Graphics.h because it is mainly supported only in Unix: So probably I will have to converted it to Java Applet tonight!

[Code]


const int INSIDE = 0; // 0000
const int LEFT = 1;   // 0001
const int RIGHT = 2;  // 0010
const int BOTTOM = 4; // 0100
const int TOP = 8;    // 1000

OutCode ComputeOutCode(double x, double y)
{
        OutCode code;

 code = INSIDE;          // initialised as being inside of clip window

 if (x < xmin)           // to the left of clip window
code |= LEFT;
 else if (x > xmax)      // to the right of clip window
code |= RIGHT;
        if (y < ymin)           // below the clip window
                code |= BOTTOM;
        else if (y > ymax)      // above the clip window
                code |= TOP;

 return code;
}
void CohenSutherlandLineClipAndDraw(double x0, double y0, double x1, double y1)

 OutCode outcode0 = ComputeOutCode(x0, y0);
 OutCode outcode1 = ComputeOutCode(x1, y1);
 bool accept = false;

 while (true) {
if (!(outcode0 | outcode1)) {//Bitwise OR is 0. Trivially accept and get out of loop
accept = true;
break;
} else if (outcode0 & outcode1) {//Bitwise AND is not 0. Trivially reject and get out of loop
                        break;
}
else {

double x, y;

OutCode outcodeOut = outcode0? outcode0 : outcode1;
if (outcodeOut&TOP){           // point is above the clip rectangle
 x = x0 + (x1-x0)*(ymax-y0)/(y1-y0);
 y = ymax;
} else if(outcodeOut & BOTTOM) { // point is below the clip rectangle
 x = x0 + (x1 - x0) * (ymin - y0) / (y1 - y0);
 y = ymin;
} else if (outcodeOut & RIGHT) {  // point is to the right of clip rectangle
 y = y0 + (y1 - y0) * (xmax - x0) / (x1 - x0);
 x = xmax;
} else if (outcodeOut & LEFT) {   // point is to the left of clip rectangle
                                y = y0 + (y1 - y0) * (xmin - x0) / (x1 - x0);
 x = xmin;
                        }

                        if (outcodeOut == outcode0) {
 x0 = x;
                                y0 = y;
 outcode0 = ComputeOutCode(x0, y0);
                        } else {
 x1 = x;
                                y1 = y;
 outcode1 = ComputeOutCode(x1, y1);
                        }
}
               rectangle(xmin, ymin, xmax, ymax);
line(x0, y0, x1, y1);
                getch();
// cleardevice();
        }

        if(accept) {

               rectangle(xmin, ymin, xmax, ymax);
line(x0, y0, x1, y1);
printf("\n\tpoints p0=(%d,%d) p1=(%d,%d)",(int)x0,(int)y0,(int)x1,(int)y1);
 }
}

int main(int argc, char** argv)
{
int gd=DETECT,gm;
initgraph(&gd,&gm,NULL);
outtextxy(300,10,"BEFORE LINE CLIPPING");
rectangle(xmin,ymin,xmax,ymax);
line(10,200,350,300);
getch();
cleardevice();
outtextxy(300,10,"AFTER LINE CLIPPING");
CohenSutherlandLineClipAndDraw(10,200,350,300);
getch();
closegraph();
return 0;
}


[/Code]


Finally I have converted it to Applet application below and the algorithm is exactly like the one from C++ above I like the way it is implemented and I made slightly modification to make people really can understand Cohen-Sutherland by just reading the code implementation below (the differences are just adding mouseListener event MousePressed for capturing coordinates of both endpoints the rest algorithm are almost exactly the same) like I have mentioned before this version was converted from above as we cannot run above C++ within Windows because only Unix OS support Graphics.h:

[Code]


/**
 * @author VIC
* @date 9-6-2012
 * Cohen-SutherLand implementation in steps below in Applet
 * 1- Init add MouseLister for Call back
 *    When there is event mousePressed is received
 * 2- when received capture x,y from Applet windows
 *    for first Coordinate and Last Coordinate
 * 3- And start painting once we get both
 *    first and last point
 * 4- we will always repaint our rectangle
 *    and paint line against Cohen-Sutherland
 *    LineClipping Algorithm
 * 5- Cohen-Sutherland LineClipping
 *    a- Computer OutCode for first Coordinate 
 *    b- Computer OutCode for Last Coordinate
 *    d- In life time While loop [While(true)]
 *       d-1- Check if both outCode first Coordinate
 *            And outCode Last Coordinate == 0
 *            => It is a trivial accepted (both points are
 *            inside rectangle)
 *            so just return true and draw it 
 *            as usual
 *       d-2- Check if outCode 1st Coo. AND 2nd Coo.
 *       != 1 
 *       =>   it is trivial rejected (both points are
 *            outSide rectangle)
 *            so just return false and don't draw it
 *       d-3- In case above 2 cases are not true
 *            that mean LineClipping or at least one coordinate
 *            pair is outside rectangle
 *       =>   Calculate the outer end point against 
 *            Top,Bottom,Right,Left to check if the outer point
 *            is in those area
 *       d-4- Move to the intersection point
 *       =>   Keeping checking it till trivial
 *            Accept or Trivial Reject
 *            And that is it.     
 *   
 */


import java.awt.*;
import java.applet.Applet;
import java.awt.event.*;

//just a simple class to store our coordinate x, y Ex: x1,y1 or x2,y2
class Coordinate {
double x, y;

// Constuctor
Coordinate(double thisx, double thisy) {
x = thisx;
y = thisy;
}
}

// Main Class linceClipper extends Applet (we use Awt not swing if it is swing
// It should have been JApplet)
public class lineClipperCohenSutherland extends Applet {

/**

*/
// ignore this it is generated by Eclipse IDE
private static final long serialVersionUID = -6235793678072658006L;

// Constance variables
// Define Top, Bottom, Right, Left Codes
//       1000,   0100,  0010, 0001    
final static int INSIDE = 0; // 0000
final static int LEFT = 1;   // 0001
final static int RIGHT = 2;  // 0010
final static int BOTTOM = 4; // 0100
final static int TOP = 8;    // 1000

// Ignore these it is just the maximum
// Width and Height of Applet Windows
// They have nothing to do with 
// Cohen-Sutherland Algorithm
final int xMax = 500, yMax = 400;

// These are used to store coordinate the two points
// which will be got from Applet MouseListener of MouseAdapter
// Event mousePressed(MouseEvent evt)
// we initialize firstZeroLastOne with 0
// Because when mouse pressed we track that if it is 0 that 
// means it is the first coordinate
// and increase it by one
// else when pressed the second times => firstZeroLastOne == 1
// will be true and we reset firstZeroLastOne to 0 
// for the next straight line
private int firstX, firstY, lastX, lastY, firstZeroLastOne = 0;

// Our rectangle area or we can say our viewport area or visible area
static double xLeft = 100.0, xRight = 400.0, yBottom = 100.0, yTop = 300.0;

// dimensions of rectangle to clip against
Coordinate C0, C1;

// init() is the starting point
// of Awt applet
public void init() {
resize(xMax, yMax);
this.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent evt) {
if (firstZeroLastOne == 0) {
firstX = evt.getX();
firstY = evt.getY();
firstZeroLastOne++; // increase by one so that 
         // we will know the next 
         // press is the last point
} else if (firstZeroLastOne == 1) {
lastX = evt.getX();
lastY = evt.getY();
firstZeroLastOne = 0; // reset it to Zero for the next line

// Now we got both point0 and Point1
// Or we can say we got first point and last point.
C0 = new Coordinate((double) firstX, (double) firstY);
C1 = new Coordinate((double) lastX, (double) lastY);

// so start painting it:
// we will always paint our rectangle
// but before we draw line we have to
// check it against Cohen-Sutherland algorithm
// for line clipping
paint(getGraphics());
}
}
});
}

public void paint(Graphics g) {
// Always repaint our rectangle area
g.drawRect((int) xLeft, (int) yBottom, (int) (xRight - xLeft),
(int) (yTop - yBottom));

// Before drawing any line check it against 
if (lineClippingCohenSutherland2D(C0, C1))
g.drawLine((int) C0.x, (int) C0.y, (int) C1.x, (int) C1.y);
}

private static int outCodesCompute(Coordinate C) {
int code;

code = INSIDE; // initialised as being inside of clip window

if (C.x < xLeft) // to the left of clip window
code |= LEFT;
else if (C.x > xRight) // to the right of clip window
code |= RIGHT;
if (C.y < yBottom) // below the clip window
code |= BOTTOM;
else if (C.y > yTop) // above the clip window
code |= TOP;

return code;
}

static boolean lineClippingCohenSutherland2D(Coordinate C0, Coordinate C1) {

if (C0 == null && C1 == null) {
return false;
}

// compute outcodes for C0, C1, and whatever point lies outside the clip rectangle
        int outcode0 = outCodesCompute(C0);
        int outcode1 = outCodesCompute(C1);

        while (true) {
                if (outcode0 == 0 && outcode1 == 0) { // Bitwise OR is 0. Trivially accept and get out of loop
                        return true;
                } else if ((outcode0 & outcode1) != 0) { // Bitwise AND is not 0. Trivially reject and get out of loop
                        return false;
                } else {
                        // failed both tests, so calculate the line segment to clip
                        // from an outside point/coordinate to an intersection with clip edge
                        double x =0, y = 0;

                        // At least one end point/coordinate is outside the clip rectangle; pick it.
                        int outcodeOut = outcode0!=0? outcode0 : outcode1;

                        // Now find the intersection point;
                        // use formulas y = y0 + slope * (x - x0), 
                        // Where x can be xRight or xLeft
                        // x = x0 + (1 / slope) * (y - y0)
                        // Where y can be yTop or yBottom
                        
                        // Slope calculation                        
                        double slope = (C1.y - C0.y)/(C1.x - C0.x);
                        
                        if ((outcodeOut & TOP) != 0) {           // point is above the clip rectangle
                                x = C0.x + (1/slope)*(yTop - C0.y) ;
                                y = yTop;
                        } else if ((outcodeOut & BOTTOM) != 0) { // point is below the clip rectangle
                                x = C0.x + (1/slope)*(yBottom - C0.y);
                                y = yBottom;
                        } else if ((outcodeOut & RIGHT) != 0) {  // point is to the right of clip rectangle
                                y = C0.y + slope*(xRight - C0.x) ;
                                x = xRight;
                        } else{ /*if ((outcodeOut & LEFT) != 0) {*/   // point is to the left of clip rectangle
                                y = C0.y + slope*(xLeft - C0.x);
                                x = xLeft;
                        }

                        // Now we move outside point to intersection point to clip
                        // and get ready for next pass.
                        if (outcodeOut == outcode0) {
                                C0.x = x;
                                C0.y = y;
                                outcode0 = outCodesCompute(C0);
                        } else {
                                C1.x = x;
                                C1.y = y;
                                outcode1 = outCodesCompute(C1);
                        }
                }
        }

}
}


[/Code]

Also please be aware that Applet Coordinate is little different than our perspective for:
Y is from Top to Down and
X is from Left to Right
Like following picture:
















This drives me nut yesterday because I click on area 1000 which is Top but it returns that it is in Below and It does return correct that it is below the boundary of Y Axis because we check that if it is less than yBottom that mean it is below bottom of Rectangle Area so it is bottom and that is because Applet Coordinate calculate the Axis Y Top to below.


9 viewports:



0 comments:

Post a Comment

Thanks for commenting...

 

Just An Information

I will updat useful information as frequent as I could...

Technology

Usage Policies