Beispiel für einfache Kantenglättung bei Circle und LineXY

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7032
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Beispiel für einfache Kantenglättung bei Circle und LineXY

Beitrag von STARGÅTE »

Tachchen,

Nachdem ich Jahrelang versucht habe Kantenglättung bei Linien und Kreisen "Pixel zu lassen" hatte ich eben n BlitzIdee:
Ich missbrauche die Gradient-Befehle dafür:
Außerdem kann man die Dicke der Linie einstellen mit DrawingThickness()

Hier mal ein Beispiel: (oben ohne Kantenglättung, unten mit Kantenglättung und verschiedener LinienDicke)

Code: Alles auswählen


Global DrawingThickness.f = 1.0
Procedure DrawingThickness(Thickness.f)
  If Thickness > 0 : DrawingThickness = Thickness : EndIf
EndProcedure


Procedure ClearCircle(x, y, Radius.f, Color)
  Protected Alpha.i, Distance.f = (DrawingThickness-1)/2
  Protected Lenght.i = Round(Radius+Distance, #PB_Round_Up)+1
  CircularGradient(x, y, Lenght)
  ResetGradientColors()
    GradientColor(0, Color&$FFFFFF)
    GradientColor((Radius-Distance-1)/Lenght, Color&$FFFFFF)
    If DrawingThickness > 1
      GradientColor((Radius-Distance)/Lenght, Color&$FFFFFF+$FF000000)
      GradientColor((Radius+Distance)/Lenght, Color&$FFFFFF+$FF000000)
    Else
      Alpha = 255*DrawingThickness
      GradientColor(Radius/Lenght, Color&$FFFFFF+Alpha<<24)
    EndIf
    GradientColor((Radius+Distance+1)/Lenght, Color&$FFFFFF)
    GradientColor(1, Color&$FFFFFF)
  Circle(x, y, Radius+DrawingThickness+2)
EndProcedure


Procedure ClearLineXY(x1, y1, x2, y2, Color)
  Protected Alpha.i
  Protected dx = x2-x1 , dy = y2-y1
  Protected Distance.f = (DrawingThickness-1)/2
  Protected Lenght.i = Sqr(dx*dx*4+dy*dy*4)
  LinearGradient(x1+dy, y1-dx, x1-dy, y1+dx)
  ResetGradientColors()
    GradientColor(0, Color&$FFFFFF)
    GradientColor((Lenght/2-Distance-1)/Lenght, Color&$FFFFFF)
    If DrawingThickness > 1
      GradientColor((Lenght/2-Distance)/Lenght, Color&$FFFFFF+$FF000000)
      GradientColor((Lenght/2+Distance)/Lenght, Color&$FFFFFF+$FF000000)
    Else
      Alpha = 255*DrawingThickness
      GradientColor(Lenght/2/Lenght, Color&$FFFFFF+Alpha<<24)
    EndIf
    GradientColor((Lenght/2+Distance+1)/Lenght, Color&$FFFFFF)
    GradientColor(1, Color&$FFFFFF)
  Circle(x1+dx/2, y1+dy/2, Lenght/4)
  ClearCircle(x1, y1, 0, Color)
  ClearCircle(x2, y2, 0, Color)
EndProcedure



Enumeration
 #Window
 #Gadget
 #Image
EndEnumeration



CreateImage(#Image, 200, 300, 32|#PB_Image_Transparent)


StartDrawing(ImageOutput(#Image))
  DrawingMode(#PB_2DDrawing_Transparent|#PB_2DDrawing_AlphaBlend)
  Box(0,0,100,300,$FFFFFFFF)
  Box(100,0,100,300,$FF000000)
  DrawingMode(#PB_2DDrawing_Transparent|#PB_2DDrawing_AlphaBlend|#PB_2DDrawing_Outlined)
  Circle(50, 50, 40, $FF000000)
  Circle(150, 50, 40, $FFFFFFFF)
  LineXY(30, 40, 70, 70, $FF000000)
  LineXY(140, 70, 160, 30, $FFFFFFFF)
  DrawingMode(#PB_2DDrawing_Transparent|#PB_2DDrawing_AlphaBlend|#PB_2DDrawing_Gradient)
  DrawingThickness(1)
  ClearCircle(50, 150, 40, $FF000000)
  ClearCircle(150, 150, 40, $FFFFFFFF)
  ClearLineXY(30, 140, 70, 170, $FF000000)
  ClearLineXY(140, 170, 160, 130, $FFFFFFFF)
  DrawingThickness(6)
  ClearCircle(50, 250, 40, $FF000000)
  ClearCircle(150, 250, 40, $FFFFFFFF)
  ClearLineXY(30, 240, 70, 270, $FF000000)
  ClearLineXY(140, 270, 160, 230, $FFFFFFFF)
StopDrawing()


SetClipboardImage(#Image)


OpenWindow(#Window, 0, 0, ImageWidth(#Image), ImageHeight(#Image), "Image", #PB_Window_MinimizeGadget|#PB_Window_ScreenCentered)
  ImageGadget(#Gadget, 0, 0, ImageWidth(#Image), ImageHeight(#Image), ImageID(#Image))


Repeat
 Event = WaitWindowEvent()
 Select Event
  Case #PB_Event_CloseWindow
   End
 EndSelect
ForEver
Das ganze geht nur bei Images und 32Bit ...

Wenn ich mal wieder etwas Zeit habe, wird daraus vllt ein komplettes Include.

Sodass man später die echten Befehle nutzen kann also Circle, statt ClearCircle
dann aber einen neuen DrawingMode() bekommt.

EDIT: Titel geändert, ist doch nicht schnell, aber eben einfach in der Programmierung ...
Zuletzt geändert von STARGÅTE am 16.04.2010 13:50, insgesamt 2-mal geändert.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
Thorium
Beiträge: 1722
Registriert: 12.06.2005 11:15
Wohnort: Germany
Kontaktdaten:

Re: Beispiel für schnelle Kantenglättung bei Circle und Line

Beitrag von Thorium »

Ziemlich cool. :allright:
Zu mir kommen behinderte Delphine um mit mir zu schwimmen.

Wir fordern mehr Aufmerksamkeit für umfallende Reissäcke! Bild
Benutzeravatar
dige
Beiträge: 1241
Registriert: 08.09.2004 08:53

Re: Beispiel für schnelle Kantenglättung bei Circle und Line

Beitrag von dige »

Genial! Danke STARGÅTE
"Papa, ich laufe schneller - dann ist es nicht so weit."
freak
PureBasic Team
Beiträge: 766
Registriert: 29.08.2004 00:20
Wohnort: Stuttgart

Re: Beispiel für schnelle Kantenglättung bei Circle und Line

Beitrag von freak »

"schnell" ist aber was anderes. Hast du mal die Geschwindigkeit mit dem normalen Circle/LineXY verglichen? ;)
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7032
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Beispiel für schnelle Kantenglättung bei Circle und Line

Beitrag von STARGÅTE »

Jo, habs eben auch mal mit großen Kreisen probiert:

-PB-Kreis: 0,0116ms :o
-Pixel-Kreis mit Kantenglättung: 0,0928ms :|
-Gradient-Kreis: 1,5230ms :oops:

Das problem ist halt das Gradient auch den innenbereich Abtasten muss.

Ich werde mal den Titel ändern in, "einfache" statt schnelle

Es bezogsich auch mehr auf den "kurzen" Code für LineXY oder Circle, ohne viel rechnen ...

aber wo du schon mal hier bist: Wird es das vielleicht eh mal in PB geben ?
also diesen DrawingMode : ClearType oder so ...
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
bobobo
jaAdmin
Beiträge: 3873
Registriert: 13.09.2004 17:48
Kontaktdaten:

Re: Beispiel für einfache Kantenglättung bei Circle und Line

Beitrag von bobobo »

hmm
http://www.purebasic.fr/english/viewtop ... ilit=Cairo

vielleicht geht das ja mal nativ einzubinden irgendwie

wobei ich nix gegen stargates bemühungen gesagt haben will.
meine frau steht auch immer stundenlang vorm spiegel damit sie noch schöner wird.
ich mach das lieber nicht und bleibe hässlich , bin dafür aber auch schneller.
‮pb aktuel 6.2 windoof aktuell und sowas von 10
Ich hab Tinnitus im Auge. Ich seh nur Pfeifen.
Benutzeravatar
hjbremer
Beiträge: 822
Registriert: 27.02.2006 22:30
Computerausstattung: von gestern
Wohnort: Neumünster

Re: Beispiel für einfache Kantenglättung bei Circle und Line

Beitrag von hjbremer »

bobobo hat geschrieben: meine frau steht auch immer stundenlang vorm spiegel damit sie noch schöner wird.
ich mach das lieber nicht und bleibe hässlich , bin dafür aber auch schneller.
:bounce: :D :bounce:

dat kenne ich :lol: :lol: :lol:
Purebasic 5.70 x86 5.72 X 64 - Windows 10

Der Computer hat dem menschlichen Gehirn gegenüber nur einen Vorteil: Er wird benutzt
grüße hjbremer
Antworten