algorytm.org

Implementacja w Delphi/Pascal



Baza Wiedzy
wersja offline serwisu przeznaczona na urządzenia z systemem Android
Darowizny
darowiznaWspomóż rozwój serwisu
Nagłówki RSS
Artykuły
Implementacje
Komentarze
Forum
Bookmarki






Sonda
Implementacji w jakim języku programowania poszukujesz?

Algorytm Cohena-Sutherlanda - Implementacja w Delphi/Pascal
Ocena użytkownikóww: *****  / 1
SłabyŚwietny
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 - Delphi/Cohen_Sutherland.pas:
//Algorytm Cohena-Sutherlanda
//(c) 2009 by Tomasz Lubinski
//www.algorytm.org
unit Cohen_Sutherland;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, ExtCtrls, SHELLAPI;

type
  TForm1 = class(TForm)
    Image1: TImage;
    Label6: TLabel;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    Button1: TButton;
    procedure Label6Click(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Cohen_Sutherland(x1, y1, x2, y2: Integer);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

const
  WIN_LEFT: Integer = 80;
  WIN_RIGHT: Integer = 420;
  WIN_TOP: Integer = 80;
  WIN_BOTTOM: Integer = 320;


implementation

{$R *.DFM}

procedure TForm1.Label6Click(Sender: TObject);
begin
  with (Sender as Tlabel) do
 ShellExecute(Application.Handle,
             PChar('open'),
             PChar(Hint), 
             PChar(0),
             nil,
             SW_NORMAL);
end;

function calcRegCode(x, y: Integer): Integer;
begin
   result := 0;
   if (x < WIN_LEFT)   then result := (result or 1);
   if (x > WIN_RIGHT)  then result := (result or 2);
   if (y > WIN_BOTTOM) then result := (result or 4);
   if (y < WIN_TOP)    then result := (result or 8);
end;

procedure TForm1.Cohen_Sutherland(x1, y1, x2, y2: Integer);
var
   rcode1, rcode2, rcode, x, y: Integer;
begin

   // 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 and rcode2) <> 0) then
   begin
      Image1.Canvas.Pen.Color := clRed;
      Image1.Canvas.MoveTo(x1, y1);
      Image1.Canvas.LineTo(x2, y2);
   end
   // 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 or rcode2) = 0) then
   begin
      Image1.Canvas.Pen.Color := clGreen;
      Image1.Canvas.MoveTo(x1, y1);
      Image1.Canvas.LineTo(x2, y2);
   end
   else
   begin
      // pozostale przypadki - przeciecie z krawedzia okna
      repeat
         if (rcode1 <> 0) then
            rcode := rcode1
         else
            rcode := rcode2;

         // pozostale przypadki - przeciecie z krawedzia okna
         if (rcode and 1) <> 0 then
         begin
            y := y1+(y2-y1)*(WIN_LEFT-x1) div (x2-x1);
            x := WIN_LEFT;
         end
         else if (rcode and 2) <> 0 then
         begin
            y := y1+(y2-y1)*(WIN_RIGHT-x1) div (x2-x1);
            x := WIN_RIGHT;
         end
         else if (rcode and 4) <> 0 then
         begin
            x := x1+(x2-x1)*(WIN_BOTTOM-y1) div (y2-y1);
            y := WIN_BOTTOM;
         end
         else if (rcode and 8) <> 0 then
         begin
            x := x1+(x2-x1)*(WIN_TOP-y1) div (y2-y1);
            y := WIN_TOP;
         end;

         if (rcode = rcode1) then
         begin
            Image1.Canvas.Pen.Color := clYellow;
            Image1.Canvas.MoveTo(x1, y1);
            Image1.Canvas.LineTo(x, y);
            x1 := x;
            y1 := y;
            rcode1 := calcRegCode(x1, y1);
         end
         else
         begin
            Image1.Canvas.Pen.Color := clYellow;
            Image1.Canvas.MoveTo(x2, y2);
            Image1.Canvas.LineTo(x, y);
            x2 := x;
            y2 := y;
            rcode2 := calcRegCode(x2, y2);
         end;
      until (((rcode1 and rcode2) <> 0) or ((rcode1 or rcode2) = 0));

      if ((rcode1 or rcode2) = 0) then
      begin
         Image1.Canvas.Pen.Color := clBlue;
         Image1.Canvas.MoveTo(x1, y1);
         Image1.Canvas.LineTo(x2, y2);
      end
      else
      begin
         Image1.Canvas.Pen.Color := clYellow;
         Image1.Canvas.MoveTo(x1, y1);
         Image1.Canvas.LineTo(x2, y2);
      end;
   end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
   i, x1, y1, x2, y2: Integer;
begin

   // 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(WIN_LEFT, WIN_TOP, WIN_RIGHT, WIN_BOTTOM);

   // losuj odciniki 
   randomize();
   for i:=1 to 20 do
   begin
      x1 := random(Image1.Width);
      y1 := random(Image1.Height);
      x2 := x1 + random(200) - 100;
      y2 := y1 + random(200) - 100;

      Cohen_Sutherland(x1, y1, x2, y2);
   end;
end;

end.
Dodaj komentarz