| Autor |
Beitrag |
Gosa
      
Beiträge: 112
|
Verfasst: 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.
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 Begin 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;
Steigung := (P1.Y - P2.Y) / (P1.X - P2.X); b := P1.Y - (Steigung * P1.X);
If (Steigung < 1) and (Steigung > -1) then 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 >= 1) or (Steigung <= -1) then 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
      
Beiträge: 239
Win98SE, Win2000SP4
D7
|
Verfasst: Mo 15.08.05 16:08
"Canvas.Pixels" ist sau-langsam, richtig.
Schneller ging es wohl mit "ScanLine" - nur eben noch komplizierter.
|
|
alzaimar
      
Beiträge: 2889
Erhaltene Danke: 13
W2000, XP
D6E, BDS2006A, DevExpress
|
Verfasst: 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 
      
Beiträge: 112
|
Verfasst: Di 16.08.05 12:15
Vielen dank! Klappt sehr gut.
|
|
BenBE
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: 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.
|
|
|