Nadesłany przez Tomasz Lubiński, 12 grudnia 2009 01:00
Kod przedstawiony poniżej przedstawia główną część rozwiązania problemu.Pobierz pełne rozwiązanie.
Jeżeli nie odpowiada Ci sposób formatowania kodu przez autora skorzystaj z pretty printer'a i dostosuj go automatycznie do siebie.
Algorytm Cohena-Sutherlanda - C++/Cohen_Sutherland.cpp:
//---------------------------------------------------------------------------
//Algorytm Cohena-Sutherlanda
//(c) 2009 by Tomasz Lubinski
//www.algorytm.org
#include <vcl.h>
#pragma hdrstop
#include "Cohen_Sutherland.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Label6Click(TObject *Sender)
{
ShellExecute(Application->Handle,
"open",
"http://www.algorytm.org",
NULL,
NULL,
SW_NORMAL);
}
#define LEFT 80
#define RIGHT 420
#define TOP 80
#define BOTTOM 320
unsigned char calcRegCode(int x, int y)
{
unsigned char result = 0;
if (x < LEFT) result |= 0x1;
if (x > RIGHT) result |= 0x2;
if (y > BOTTOM) result |= 0x4;
if (y < TOP) result |= 0x8;
return result;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Cohen_Sutherland(int x1, int y1, int x2, int y2)
{
unsigned char rcode1, rcode2, rcode;
int x, y;
/* Algorytm Cohena-Sutherlanda */
/* 1. Zakoduj końce odcinka zgodnie z kodami obszarów */
rcode1 = calcRegCode(x1, y1);
rcode2 = calcRegCode(x2, y2);
/* 2. Jeżeli iloczyn logiczny (AND) tych kodów <>0,
to odcinek może być pominięty (w całości poza
oknem) - zaznacz go na czerwono */
if (rcode1 & rcode2)
{
Image1->Canvas->Pen->Color = clRed;
Image1->Canvas->MoveTo(x1, y1);
Image1->Canvas->LineTo(x2, y2);
}
/* 3. Jeżeli suma logiczna (OR)tych kodów = 0,
to odcinek w całości mieści się w okienku
- zaznacz go na zielono */
else if ((rcode1 | rcode2) == 0)
{
Image1->Canvas->Pen->Color = clGreen;
Image1->Canvas->MoveTo(x1, y1);
Image1->Canvas->LineTo(x2, y2);
}
else
{
/* pozostale przypadki - przeciecie z krawedzia okna */
do
{
if (rcode1 != 0)
{
rcode = rcode1;
}
else
{
rcode = rcode2;
}
/* pozostale przypadki - przeciecie z krawedzia okna */
if (rcode & 0x1)
{
y = y1+(y2-y1)*(LEFT-x1)/(x2-x1);
x = LEFT;
}
else if (rcode & 0x2)
{
y = y1+(y2-y1)*(RIGHT-x1)/(x2-x1);
x = RIGHT;
}
else if (rcode & 0x4)
{
x = x1+(x2-x1)*(BOTTOM-y1)/(y2-y1);
y = BOTTOM;
}
else if (rcode & 0x8)
{
x = x1+(x2-x1)*(TOP-y1)/(y2-y1);
y = TOP;
}
if (rcode == rcode1)
{
Image1->Canvas->Pen->Color = clYellow;
Image1->Canvas->MoveTo(x1, y1);
Image1->Canvas->LineTo(x, y);
x1 = x;
y1 = y;
rcode1 = calcRegCode(x1, y1);
}
else
{
Image1->Canvas->Pen->Color = clYellow;
Image1->Canvas->MoveTo(x2, y2);
Image1->Canvas->LineTo(x, y);
x2 = x;
y2 = y;
rcode2 = calcRegCode(x2, y2);
}
} while ((rcode1 & rcode2) == 0 && (rcode1 | rcode2) != 0);
if ((rcode1 | rcode2) == 0)
{
Image1->Canvas->Pen->Color = clBlue;
Image1->Canvas->MoveTo(x1, y1);
Image1->Canvas->LineTo(x2, y2);
}
else
{
Image1->Canvas->Pen->Color = clYellow;
Image1->Canvas->MoveTo(x1, y1);
Image1->Canvas->LineTo(x2, y2);
}
}
}
void __fastcall TForm1::Button1Click(TObject *Sender)
{
int i, x1, y1, x2, y2;
/* wyczysc wszystko */
Image1->Canvas->Pen->Color = clBlack;
Image1->Canvas->Pen->Width = 2;
Image1->Canvas->Brush->Color = clWhite;
Image1->Canvas->Rectangle(0, 0, Image1->Width, Image1->Height);
/* narysuj okno */
Image1->Canvas->Brush->Color = clLtGray;
Image1->Canvas->Rectangle(LEFT, TOP, RIGHT, BOTTOM);
/* losuj odciniki */
randomize();
for (i=0; i<20; i++)
{
x1 = random(Image1->Width);
y1 = random(Image1->Height);
x2 = x1 + random(200) - 100;
y2 = y1 + random(200) - 100;
Cohen_Sutherland(x1, y1, x2, y2);
}
}
//---------------------------------------------------------------------------

