Autor Beitrag
Gosa
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 112



BeitragVerfasst: Mo 15.08.05 15:44 
Hallo

Ich habe einen Algorithmus geschrieben der das gleiche wie LineTo macht. Ich brauche das, da das pmNotXor bei mir nicht funktioniert da meine Linien auch Linien seinen können die sich überschneiden. (Also es sind Linien die aus mehreren Punkten bestehen die durch LineTo verbunden werden). Das pmNotXor wirkt sich dann normalerweise so aus das der Punkt wo sie sich überschneiden dort bleibt.

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
Procedure TLinie.LinieVonBis(P1, P2 : TPoint);
var i : integer;
    Steigung, b : Extended;
    PixelPunkt : TPoint;
Begin
  With vZielImage.Canvas do //Das ist eigentlich eine Procedure die einem Object ist wo in Zielimage steht wodrauf das gemalt werden soll 
  Begin 
    //erst werden die 4 sonderfälle geprüft also senkrecht und waagerecht in beide richtungen
    If P1.Y = P2.Y then
    Begin
      If P1.X < P2.X then
        For i := P1.X to P2.X do
        Begin
          If (vZielImage.Canvas.pen.mode <> pmNotXor) or (vZielImage.Canvas.Pixels[i, P1.Y] = vZielImage.Canvas.pen.Color) then
            vZielImage.Canvas.Pixels[i , P1.Y] := vZielImage.Canvas.pen.Color;
        End
      else if P2.X < P1.X then
        For i := P2.X to P1.X do
          If (vZielImage.Canvas.pen.mode <> pmNotXor) or (vZielImage.Canvas.Pixels[i, P1.Y] = vZielImage.Canvas.pen.Color) then
            vZielImage.Canvas.Pixels[i , P1.Y] := vZielImage.Canvas.pen.Color;
      Exit;
    End;

    If P1.X = P2.X then
    Begin
      If P1.Y < P2.Y then
        For i := P1.Y to P2.Y do
        Begin
          If (vZielImage.Canvas.pen.mode <> pmNotXor) or (vZielImage.Canvas.Pixels[P1.X , i] = vZielImage.Canvas.pen.Color) then
            vZielImage.Canvas.Pixels[P1.X , i] := vZielImage.Canvas.pen.Color;
        End
      else if P2.Y < P1.Y then
        For i := P2.Y to P1.Y do
          If (vZielImage.Canvas.pen.mode <> pmNotXor) or (vZielImage.Canvas.Pixels[P1.X , i] = vZielImage.Canvas.pen.Color) then
            vZielImage.Canvas.Pixels[P1.X , i] := vZielImage.Canvas.pen.Color;
      Exit;
    End;


    //ab hier dann wenn es keine waagerechte oder senkrechte linie ist
    Steigung := (P1.Y - P2.Y) / (P1.X - P2.X);
    b := P1.Y - (Steigung * P1.X);

    If (Steigung < 1and (Steigung > -1then
    Begin
      If P1.X < P2.X then
        For i := P1.X to P2.X do
        Begin
          PixelPunkt := Point(i , round(Steigung * i + b));
          If (vZielImage.Canvas.pen.mode <> pmNotXor) or (vZielImage.Canvas.Pixels[PixelPunkt.X, PixelPunkt.Y] = vZielImage.Canvas.pen.Color) then
            vZielImage.Canvas.Pixels[PixelPunkt.X, PixelPunkt.Y] := vZielImage.Canvas.pen.Color
        End
      else if P1.X > P2.X then
        For i := P2.X to P1.X do
        Begin
          PixelPunkt := Point(i , round(Steigung * i + b));
          If (vZielImage.Canvas.pen.mode <> pmNotXor) or (vZielImage.Canvas.Pixels[PixelPunkt.X, PixelPunkt.Y] = vZielImage.Canvas.pen.Color) then
            vZielImage.Canvas.Pixels[PixelPunkt.X, PixelPunkt.Y] := vZielImage.Canvas.pen.Color;
        End;
    End
    else if (Steigung >= 1or (Steigung <= -1then
    Begin
      If P1.Y < P2.Y then
        For i := P1.Y to P2.Y do
        Begin
          PixelPunkt := Point(round((i - b) / Steigung) , i);
          If (vZielImage.Canvas.pen.mode <> pmNotXor) or (vZielImage.Canvas.Pixels[PixelPunkt.X, PixelPunkt.Y] = vZielImage.Canvas.pen.Color) then
            vZielImage.Canvas.Pixels[PixelPunkt.X, PixelPunkt.Y] := vZielImage.Canvas.pen.Color
        End
      else if P2.Y < P1.Y then
        For i := P2.Y to P1.Y do
        Begin
          PixelPunkt := Point(round((i - b) / Steigung) , i);
          If (vZielImage.Canvas.pen.mode <> pmNotXor) or (vZielImage.Canvas.Pixels[PixelPunkt.X, PixelPunkt.Y] = vZielImage.Canvas.pen.Color) then
            vZielImage.Canvas.Pixels[PixelPunkt.X, PixelPunkt.Y] := vZielImage.Canvas.pen.Color
        End;
      End;
    End;
  End;
End;


Naja das ist nur leider super langsam.
LigH
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 239

Win98SE, Win2000SP4
D7
BeitragVerfasst: Mo 15.08.05 16:08 
"Canvas.Pixels" ist sau-langsam, richtig.

Schneller ging es wohl mit "ScanLine" - nur eben noch komplizierter.
alzaimar
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2889
Erhaltene Danke: 13

W2000, XP
D6E, BDS2006A, DevExpress
BeitragVerfasst: Mo 15.08.05 21:09 
Check mal den Bresenham-Algorithmus , der macht das optimal schnell. Wenn Du das hinbekommen hast, dann ersetzt Du die Pixel-Eigenschaft durch Scanline. Das sollte performancetechnisch reichen.
Gosa Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 112



BeitragVerfasst: Di 16.08.05 12:15 
Vielen dank! Klappt sehr gut.
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Di 16.08.05 12:56 
Es gibt auch eine API-Funktion LineDDA, die den Brehesem-Algo kapselt und dir per Callback jeden zu setzenden Punkt übergibt. Den dann mit Pixels oder ScanLine zu Zeichnen sollte kein Thema mehr sein. Such einfach mal hier im Forum danach, da gibt es ein gutes Beispiel dafür.

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.