2015-07-12 83 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

相關問題