2015-07-12 85 views
-1

请帮我解决这个Cohen-Sutherland算法实现的代码。你能告诉我Cohen-Sutherland算法的这种实现有什么问题吗?

The theory is here at Page-91。

Here is the entire project.

#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); 

      Coordinates2d::Draw(tempLine); 
     } 

     return tempLine; 
    } 
}; 

#define LINENUM 3 

int main() 
{ 
    Line2d ln(Point2d(-120, -40), Point2d(270, 160)); 
    Rectangle2d rect(Point2d(0, 0), Point2d(170, 120)); 

    Coordinates2d::ShowWindow("Cohen-Sutherland Line Clipping"); 
    Coordinates2d::Draw(ln); 
    Coordinates2d::Draw(rect); 

    ClippingLine2d clip(rect, ln); 

    Line2d clippedLine = clip.GetClippedLine(); 

    Coordinates2d::Draw(clippedLine); 

    Coordinates2d::Wait(); 

    return 0; 
} 

GetClippedLine()卡在无限循环。堂妹,线的终点的第3位始终保持1 ..


下,选民和近距离的选民,请小心发表评论。

回答

1

==运营商在你的点点类包含了一个错误:

bool operator == (Bits & b) 
{ 
    bool b1 = bit1 == b.bit1; 
    bool b2 = bit2 == b.bit2; // <-- change bit1 to bit2 
    bool b3 = bit3 == b.bit3; // <-- change bit1 to bit3 
    bool b4 = bit4 == b.bit4; // <-- change bit1 to bit4 

    if(b1==true && b2==true && b3==true && b4==true) return true; 
    else return false; 
} 

操作功能从IsClippingCandidate()称为内GetClippedLine()

此外,您的剪裁试验比较为零,并返回1(如果线条的终点大于或等于剪切线,这意味着如果它完全剪切到线条上,它将始终为1.因此,请将比较结果改为大于大于或等于。

int Sign(int a) 
{ 
    if(a>0) return 1; 
    else return 0; 
} 

另外,如果你得到的结果不准确,你可以尝试做裁剪浮点,而不是整数,在这种情况下,你应该改变的a类型float或double,并添加一个小的耐受性比较例如if(a > 0.0001f)

削波函数应该只要有在开始或结束设置的位执行,于是改变IsClippingCandidate到或两者一起,当该结果为零时返回false(没有比特被在任一组)和否则真:

bool IsClippingCandidate(Bits & bits) 
{ 
    Bits zeroBits; 
    Bits orredBits = *this | bits; 

    if(orredBits == zeroBits) return false; 
    else return true; 
} 

您还可以测试线路是否完全裁剪区域外,可以丢弃这样的:

bool IsInvisible(Bits & bits) 
{ 
    Bits zeroBits; 
    Bits andedBits = *this & bits; 

    if(andedBits == zeroBits) return false; 
    else return true; 
} 

如果这两点是给定的裁剪线之外,那么线是看不见的。

+0

它的工作原理,但问题是,该算法是否正确实施?我怀疑while循环实际上并不需要实现该算法。你怎么看? – anonymous

+0

在一次通过循环后,可能会设置一些削波位,但我认为您还需要测试来完全丢弃该行。如果你和他们和结果是非零,那么这条线完全在裁剪区域之外。 – samgak

相关问题