Please, review the following implementation of Cohen-Sutherland line clipping algorithm (p-91):
Bits.cpp
class Bits
{
public:
int bit1;
int bit2;
int bit3;
int bit4;
public:
Bits()
{
bit1 = bit2 = bit3 = bit4 = 0;
}
Bits(Bits & b)
{
*this = b;
}
Bits & operator & (Bits & b)
{
bit1 = bit1 & b.bit1;
bit2 = bit2 & b.bit2;
bit3 = bit3 & b.bit3;
bit4 = bit4 & b.bit4;
return *this;
}
Bits & operator | (Bits & b)
{
bit1 = bit1 | b.bit1;
bit2 = bit2 | b.bit2;
bit3 = bit3 | b.bit3;
bit4 = bit4 | b.bit4;
return *this;
}
Bits & operator = (Bits & b)
{
bit1 = b.bit1;
bit2 = b.bit2;
bit3 = b.bit3;
bit4 = b.bit4;
return *this;
}
bool operator == (Bits & b)
{
if(bit1 == b.bit1 && bit2 == b.bit2 && bit3 == b.bit3 && bit4 == b.bit4) return true;
else return false;
}
private:
int Sign(double a)
{
if(a>0.01f) return 1;
else return 0;
}
int GetBit1(double y, double yMax)
{
return Sign(y - yMax);
}
int GetBit2(double y, double yMin)
{
return Sign(yMin - y);
}
int GetBit3(double x, double xMax)
{
return Sign(x - xMax);
}
int GetBit4(double x, double xMin)
{
return Sign(xMin - x);
}
public:
void PointToBits(Point2d & clipMax, Point2d & clipMin, Point2d & pnt)
{
bit1 = GetBit1(pnt.y, clipMax.y);
bit2 = GetBit2(pnt.y, clipMin.y);
bit3 = GetBit3(pnt.x, clipMax.x);
bit4 = GetBit4(pnt.x, clipMin.x);
}
bool IsClippingCandidate(Bits & bits)
{
Bits zeroBits;
Bits andedBits = *this | bits;
if(andedBits == zeroBits) return false;
else return true;
}
};
ClippingLine2d.cpp
#include "Line2d.h"
#include "Rectangle2d.h"
#include "Coordinates2d.h"
class ClippingLine2d
{
private:
Rectangle2d rectangle;//clipping rectangle
Line2d line;//line to be clipped
private:
Bits startPointBits;//bits for start point of line
Bits endPointsBits;//bits for end point of line
public:
ClippingLine2d(Rectangle2d rect, Line2d line)
{
this->rectangle = rect;
this->line = line;
}
private:
Line2d GetClippedLine(std::vector<Line2d> clippingRegionLines, Line2d ln)
{
Point2d start = ln.GetStart();
Point2d end = ln.GetEnd();
if(startPointBits.bit4 == 1)
{
start = ln.GetIntersection(clippingRegionLines[3]);//DA
}
else if(startPointBits.bit3 == 1)
{
start = ln.GetIntersection(clippingRegionLines[1]);//BC
}
else if(startPointBits.bit2 == 1)
{
start = ln.GetIntersection(clippingRegionLines[0]);//AB
}
else if(startPointBits.bit1 == 1)
{
start = ln.GetIntersection(clippingRegionLines[2]);//CD
}
if(endPointsBits.bit4 == 1)
{
end = ln.GetIntersection(clippingRegionLines[3]);//DA
}
else if(endPointsBits.bit3 == 1)
{
end = ln.GetIntersection(clippingRegionLines[1]);//BC
}
else if(endPointsBits.bit2 == 1)
{
end = ln.GetIntersection(clippingRegionLines[0]);//AB
}
else if(endPointsBits.bit1 == 1)
{
end = ln.GetIntersection(clippingRegionLines[2]);//CD
}
return Line2d(start.Round(), end.Round());
}
public:
Line2d GetClippedLine()
{
Point2d min = rectangle.GetStart();
Point2d max = rectangle.GetEnd();
startPointBits.PointToBits(max, min, line.GetStart());
endPointsBits.PointToBits(max, min, line.GetEnd());
std::vector<Line2d> clippingRegionLines = rectangle.GetLines();
Line2d tempLine = this->line;
Bits start = startPointBits;
Bits end = endPointsBits;
while(start.IsClippingCandidate(end))
{
tempLine = GetClippedLine(clippingRegionLines, tempLine);
Point2d startP = tempLine.GetStart();
Point2d endP = tempLine.GetEnd();
start.PointToBits(max, min, startP);
end.PointToBits(max, min, endP);
}
return tempLine;
}
};
int main()
{
Line2d ln(Point2d(-120, -40), Point2d(270, 160));
Rectangle2d rect(Point2d(20, 20), Point2d(160, 120));
Coordinates2d::ShowWindow("Cohen-Sutherland Line Clipping");
Coordinates2d::Draw(ln, Red);
Coordinates2d::Draw(rect, LightGreen);
ClippingLine2d clip(rect, ln);
Line2d clippedLine = clip.GetClippedLine();
Coordinates2d::Draw(clippedLine, Yellow);
Coordinates2d::Wait();
return 0;
}
The whole Visual C++ 2008 Express source code can be found here.