Seite 1 von 2

AA-Kreis

Verfasst: 06.05.2009 14:43
von KeyKon
Hat zufällig jemand eine Routine parat mit der man einen Kreis weichgezeichnet (Also sozusagen AntiAlaised) erstellen kann, im Codearchiv gibts das ja nur mit Linien...

Edit: Es gibt mir nur um einen Gefüllten Kreis, außerdem muss das ganze nich besonders schnell gehen da nur auf ein Sprite gezeichnet wird...

Verfasst: 06.05.2009 15:21
von STARGÅTE

Code: Alles auswählen


 
 Procedure ColorMix(Color1, Color2, MixFactor.f=0.50)
  Protected R, G, B, InvMixFactor.f
  InvMixFactor = 1-MixFactor
  R =   Red(Color1) * InvMixFactor +   Red(Color2) * MixFactor
  G = Green(Color1) * InvMixFactor + Green(Color2) * MixFactor
  B =  Blue(Color1) * InvMixFactor +  Blue(Color2) * MixFactor
  ProcedureReturn RGB(R,G,B)
 EndProcedure

Procedure ClearCircle(x, y, Radius, Color)
 Circle(x,y,Radius-1,Color)
 For iy = -Radius To Radius
  Pixel = #False
  For ix = -Radius To 0
   r.f = Sqr(ix*ix+ix+iy*iy+iy+0.5)
   d.f = r-Radius+0.5
   If d < 1 And d > -1
    If d < 0 : d = 0 : EndIf
    Point = Point(x+ix, y+iy)
    PlotColor = ColorMix(Color, Point, d)
    Plot(x+ix, y+iy, PlotColor)
    Point = Point(x-ix-1, y+iy)
    PlotColor = ColorMix(Color, Point, d)
    Plot(x-ix-1, y+iy, PlotColor)
    Pixel = #True
   ElseIf Pixel
    Break
   EndIf
  Next
 Next
EndProcedure


CreateImage(0, 768, 256)

StartDrawing(ImageOutput(0))
 DrawingMode(1)
 For n = 0 To 255
  Box(n*3,0,3,256,RGB(n,n,n))
 Next
 DrawingMode(1)
 Restore Color
 r = 40
 For n = 1 To 8
  Read.l Color
  ClearCircle(64*n+64,64,r,Color)
  Circle(64*n+64,192,r,Color)
 Next
StopDrawing()

OpenWindow(0, 0, 0, ImageWidth(0), ImageHeight(0), "Fenster", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
 ImageGadget(0,0,0,ImageWidth(0), ImageHeight(0), ImageID(0))

Repeat
 Event = WaitWindowEvent()
 Select Event
  Case #PB_Event_CloseWindow
   End
 EndSelect
ForEver

DataSection
 Color:
 Data.l $FFFFFF, $FFFF00, $FF0000, $FF00FF, $0000FF, $00FFFF, $00FF00, $000000
EndDataSection

das eine Auskommentierte wäre nur dann erforderlich wenn er nicht gefüllt sein soll.

einfach mal n bisschen was ausprobieren ^^

Oben ist AA (hint hintergrund verschmelzung) unten ohne AA

EDIT: Der Code war eigentlich für nicht gefüllte kreise, habe ih nun etwas verändert, sollte ganz gut sein

Verfasst: 06.05.2009 16:09
von KeyKon
Optimal :allright:
Das sollte unbedingt mal ins CodeArchiv...

Verfasst: 06.05.2009 16:20
von Kiffi
<OT>
STARGÅTE hat geschrieben:Oben ist AA (hint: hintern verschmutzung) unten ohne AA
Bild

</OT>

Verfasst: 06.05.2009 16:33
von KeyKon
:lol:

Ich hab einen Bug entdeckt beim Radius 30 werden mit AA einige Pixel nich ausgemalt...

Verfasst: 06.05.2009 17:27
von STARGÅTE
jo dann schreib hier mal
Circle(x,y,Radius-1,Color)
besser das:
Circle(x,y,Radius,Color)
dann gehts

Verfasst: 06.05.2009 21:28
von KeyKon
Ja, dann isser aber nich mehr so weich :roll:

Verfasst: 06.05.2009 21:34
von STARGÅTE
okee dann so:

Code: Alles auswählen

Procedure ClearCircle(x, y, Radius, Color) 
 Circle(x,y,Radius-1,Color) 
 For iy = -Radius To Radius 
  Pixel = #False 
  For ix = -Radius To 0 
   r.f = Sqr(ix*ix+ix+iy*iy+iy+0.5) 
   d.f = r-Radius+0.5 
   If d < 1 And d > -2 
    If d < 0 : d = 0 : EndIf 
    Point = Point(x+ix, y+iy) 
    PlotColor = ColorMix(Color, Point, d) 
    Plot(x+ix, y+iy, PlotColor) 
    Point = Point(x-ix-1, y+iy) 
    PlotColor = ColorMix(Color, Point, d) 
    Plot(x-ix-1, y+iy, PlotColor) 
    Pixel = #True 
   ElseIf Pixel 
    Break 
   EndIf 
  Next 
 Next 
EndProcedure 
die -1 wieder hin, wie ich es hatte, aber dann muss mehr selber gePlottet werden, deshalt die And d > -2.
Sollte dann gehen ...

Verfasst: 06.05.2009 21:37
von KeyKon
Jo, passt wunderbar :allright:

Verfasst: 06.05.2009 21:39
von NicTheQuick
Man könnte ja auch den Kreis doppelt odervielfach so groß auf ein ebensogroßes Sprite
oder Image malen, dieses dann mit 'Smooth' wieder auf die eigentliche Größe resizen und
dann mit Aphablending dahin malen, wo es sein soll.

Zugegeben eine dumme Idee, aber warum Circle neu erfinden? :wink: