Seite 1 von 1

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

Verfasst: 15.04.2010 23:10
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 ...

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

Verfasst: 15.04.2010 23:18
von Thorium
Ziemlich cool. :allright:

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

Verfasst: 16.04.2010 08:06
von dige
Genial! Danke STARGÅTE

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

Verfasst: 16.04.2010 13:27
von freak
"schnell" ist aber was anderes. Hast du mal die Geschwindigkeit mit dem normalen Circle/LineXY verglichen? ;)

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

Verfasst: 16.04.2010 13:49
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 ...

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

Verfasst: 16.04.2010 13:56
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.

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

Verfasst: 16.04.2010 20:14
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: