int ClipLine(int &x1, int &y1, int &x2, int &y2)
{
#define CLIP_CODE_C 0x0000
#define CLIP_CODE_N 0x0008
#define CLIP_CODE_S 0x0004
#define CLIP_CODE_E 0x0002
#define CLIP_CODE_W 0x0001
#define CLIP_CODE_NE 0x000a
#define CLIP_CODE_SE 0x0006
#define CLIP_CODE_NW 0x0009
#define CLIP_CODE_SW 0x0005
int ClippedX1; // init. varibles to clip line to
int ClippedY1;
int ClippedX2;
int ClippedY2;
//init. clip codes
int Point1Code = 0;
int Point2Code = 0;
//figrue out these codes
//point 1 y value
if(y1 < ClipMinY)
Point1Code |= CLIP_CODE_N;
else if(y1 > ClipMaxY)
Point1Code |= CLIP_CODE_S;
//point 1 x value
if(x1 < ClipMinX)
Point1Code |= CLIP_CODE_W;
else if(x1 > ClipMaxX)
Point1Code |= CLIP_CODE_E;
//point 2 y value
if(y2 < ClipMinY)
Point2Code |= CLIP_CODE_N;
else if(y2 > ClipMaxY)
Point2Code |= CLIP_CODE_S;
//point 2 x value
if(x2 < ClipMinX)
Point2Code |= CLIP_CODE_W;
else if(x2 > ClipMaxX)
Point2Code |= CLIP_CODE_E;
//trival rejection
if((Point1Code & Point2Code)) //if both points are off screen
return 2; //in the same manner
//(both north, south, east or west)
if((Point1Code == 0 && Point2Code == 0))
return 1; //they are both on screen
//ok, now we know that one of the two points needs to be clipped.
//do point one first, then point two, clipping them to the
//predefined clipping thing
switch(Point1Code)
{
case CLIP_CODE_C:
//it's inside the clipper
break;
case CLIP_CODE_N:
//it's above the clipper. Bring it down.
ClippedY1 = ClipMinY; //known B/C of geometry
ClippedX1 = x1 + 0.5 + (ClipMinY-y1)*(x2-x1)/(y2-y1);
break;
case CLIP_CODE_S:
ClippedY1 = ClipMaxY; //known because of geometry
ClippedX1 = x1 + 0.5 + (ClipMaxY-y1)*(x2-x1)/(y2-y1);
break;
case CLIP_CODE_W:
ClippedX1 = ClipMinX;
ClippedY1 = y1 + 0.5 + (ClipMinX-x1)*(y2-y1)/(x2-x1);
break;
case CLIP_CODE_E:
ClippedX1 = ClipMaxX;
ClippedY1 = y1 + 0.5 + (ClipMaxX-x1)*(y2-y1)/(x2-x1);
break;
//ok, if we're still in this switch-case thing by now,then
//there is more than one line intersection, in which case we'll
//need to calculate both intersections. (How fun!)
//remember you're still in a switch statement
case CLIP_CODE_NE:
//calculate the north HLine intersection
ClippedY1 = ClipMinY; //easy enough
ClippedX1 = x1 + 0.5 + (ClipMinY-y1)*(x2-x1)/(y2-y1);
//ok, now if that worked, we don't need to clip it again.
//if it didn't, we should.
if(ClippedX1 < ClipMinX || ClippedX1 > ClipMaxX)
{
//there is a east VLine intersection
ClippedX1 = ClipMaxX;
ClippedY1 = y1 + 0.5 + (ClipMaxX-x1)*(y2-y1)/(x2-x1);
}
break; //end CLIP_CODE_NE
case CLIP_CODE_SE:
//South HLine intersection
ClippedY1 = ClipMaxY; //known because of geometry
ClippedX1 = x1 + 0.5 + (ClipMaxY-y1)*(x2-x1)/(y2-y1);
//if it works, great. if not, nuts.
if(ClippedX1 < ClipMinX || ClippedX1 > ClipMaxX)
{
//east VLine intersection
ClippedX1 = ClipMaxX;
ClippedY1 = y1 + 0.5 + (ClipMaxX-x1)*(y2-y1)/(x2-x1);
}
break;
case CLIP_CODE_NW:
// North HLine intersection
ClippedY1 = ClipMinY; //easy enough
ClippedX1 = x1 + 0.5 + (ClipMinY-y1)*(x2-x1)/(y2-y1);
if(ClippedX1 < ClipMinX || ClippedX1 > ClipMaxX)
{
//west VLine intersection
ClippedX1 = ClipMinX;
ClippedY1 = y1 + 0.5 + (ClipMinX-x1)*(y2-y1)/(x2-x1);
}
break;
case CLIP_CODE_SW:
//south HLine intersection
ClippedY1 = ClipMaxY; //known because of geometry
ClippedX1 = x1 + 0.5 + (ClipMaxY-y1)*(x2-x1)/(y2-y1);
if(ClippedX1 < ClipMinX || ClippedX1 > ClipMaxX)
{
//west VLine intersection
ClippedX1 = ClipMinX;
ClippedY1 = y1 + 0.5 + (ClipMinX-x1)*(y2-y1)/(x2-x1);
}
break;
default: break;
}//end point1
//now roll right into point2
//(ya!!)
//determine the clip point for point2
//(this will look alot like the thing above for point1)
switch(Point2Code)
{
case CLIP_CODE_C:
break;
case CLIP_CODE_N:
ClippedY2 = ClipMinY;
ClippedX2 = x2 + (ClipMinY - y2)*(x1-x2)/(y1/y2);
break;
case CLIP_CODE_S:
ClippedY2 = ClipMaxY;
ClippedX2 = x2 + (ClipMinY - y2)*(x1-x2)/(y1/y2);
break;
case CLIP_CODE_W:
ClippedX2 = ClipMinX;
ClippedY2 = y2 + (ClipMinX - x2)*(y1-y2)/(x1-x2);
break;
case CLIP_CODE_E:
ClippedX2 = ClipMaxY;
ClippedY2 = y2 + (ClipMaxX - x2)*(y1-y2)/(x1-x2);
break;
//ok, now for the hard part..
case CLIP_CODE_NE:
//north HLine intersection
ClippedY2 = ClipMinY;
ClippedX2 = x2 + (ClipMinY - y2)*(x1-x2)/(y1/y2);
//IF
if(ClippedX2 < ClipMinX || ClippedX2 > ClipMaxX)
{
//east VLine intersection
ClippedX2 = ClipMaxY;
ClippedY2 = y2 + (ClipMaxX - x2)*(y1-y2)/(x1-x2);
}
break;
case CLIP_CODE_SE:
//south HLine intersection
ClippedY2 = ClipMaxY;
ClippedX2 = x2 + (ClipMinY - y2)*(x1-x2)/(y1/y2);
if(ClippedX2 < ClipMinX || ClippedX2 > ClipMaxX)
{
//east VLine intersection
ClippedX2 = ClipMaxY;
ClippedY2 = y2 + (ClipMaxX - x2)*(y1-y2)/(x1-x2);
}
break;
case CLIP_CODE_NW:
//north HLine intersection
ClippedY2 = ClipMinY;
ClippedX2 = x2 + (ClipMinY - y2)*(x1-x2)/(y1/y2);
if(ClippedX2 < ClipMinX || ClippedX2 > ClipMaxX)
{
//west VLine intersection
ClippedX2 = ClipMinX;
ClippedY2 = y2 + (ClipMinX - x2)*(y1-y2)/(x1-x2);
}
break;
case CLIP_CODE_SW:
//south HLine
ClippedY2 = ClipMaxY;
ClippedX2 = x2 + (ClipMinY - y2)*(x1-x2)/(y1/y2);
if(ClippedX2 < ClipMinX || ClippedX2 > ClipMaxX)
{
//west VLine
ClippedX2 = ClipMinX;
ClippedY2 = y2 + (ClipMinX - x2)*(y1-y2)/(x1-x2);
}
break;
default: break;
}//end switch
//well that was relitively painless...now do a bounds check
if( (ClippedX1 < ClipMinX) || (ClippedX1 > ClipMaxX) ||
(ClippedY1 < ClipMinY) || (ClippedY1 > ClipMaxY) ||
(ClippedX2 < ClipMinX) || (ClippedX2 > ClipMaxX) ||
(ClippedY2 < ClipMinY) || (ClippedY2 > ClipMaxY) )
{
//oops. there are still points outside the clipping region
//give up
return 0;
}
//restore varibles
x1 = ClippedX1;
y1 = ClippedY1;
x2 = ClippedX2;
y2 = ClippedY2;
return 1;
}//end Clipline()
Lines...the're evil aren't they?
ok, i'm trying to clip a line to the screen, but itn't not wroking very well...take a look
whats wrong?
[edited by - MattS423 on January 6, 2003 8:21:27 PM]
Programmers of the world, UNTIE!
Seems a very convoluted way to do a very simple task. Many of the conditions could be eliminated by simply breaking it into a left/right and top/bottom clipping and insuring the order for the two parts. Just swap the points, toggle a flag and if the flag is set at the end do one more swap, i.e. an even number of swaps means you are in the same order as you started.
Keys to success: Ability, ambition and opportunity.
Thats a good idea...
I tried to find an article on GameDev for this, but i couldn''t find one. anybody konw of anything?
also, that monster up there should do SOMETHING, right?
it compiles, runs, and then causes somekind of error, and the program just exits....strange, isn''t it?
well, thanks for your help
I tried to find an article on GameDev for this, but i couldn''t find one. anybody konw of anything?
also, that monster up there should do SOMETHING, right?
it compiles, runs, and then causes somekind of error, and the program just exits....strange, isn''t it?
well, thanks for your help
Programmers of the world, UNTIE!
quote:
Original post by MattS423
also, that monster up there should do SOMETHING, right?
it compiles, runs, and then causes somekind of error, and the program just exits....strange, isn''t it?
The error should give you a clue about what is wrong.
I used my old friend google to do a search on "line clipping," and here is what my friend said:
#1 link:
http://www.cs.brown.edu/courses/cs123/lectures/Clipping.pdf
link with Java demonstration of the algorithm from the #1 link:
http://graphics.lcs.mit.edu/classes/6.837/F99/assignment2/CohenSutherland.html
Link with 3 different algorithms:
http://www.cis.ohio-state.edu/~hwshen/681/0118.pdf
Graham Rhodes
Senior Scientist
Applied Research Associates, Inc.
Graham Rhodes Moderator, Math & Physics forum @ gamedev.net
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement
Recommended Tutorials
Advertisement