Wu's AntiAliasing-Linie
Übersicht BlitzMax, BlitzMax NG Codearchiv & Module
ChaosCoderBetreff: Wu's AntiAliasing-Linie |
So, Apr 20, 2008 4:32 Antworten mit Zitat |
|
---|---|---|
Hallo liebe Community,
nach erfolgloser Forensuche und auch erfolglosem stöbern im englischen Codearchiv nach einer Funktion, die es ermöglicht AntiAliasing-Linien zu zeichnen, habe ich mich mal schlau gemacht und fand den Algorithmus von Xiaolin Wu ganz angemessen. Er ermöglicht eben dieses Zeichnen von Linien mit Kantenglättung. Ein paar Kleinigkeiten hab ich abgeändert und so lässt sich das Ergebnis doch echt sehen. Und hier kommt der Code: Code: [AUSKLAPPEN] Type TLine
Function drawPlot(x:Int, y:Int, c:Float) c = 1 - (Cos(c * 180) + 1) / 2 SetAlpha c Plot(x, y) End Function Function ipart:Int(x:Float) Return Int(x) End Function Function round:Int(x:Float) Return ipart(x + 0.5) End Function Function fpart:Float(x:Float) Return x - Int(x) End Function Function rfpart:Float(x:Float) Return 1 - fpart(x) End Function Function draw(x1:Float, y1:Float, x2:Float, y2:Float) Local lastalpha:Float = GetAlpha() Local tmp:Float Local dx:Int, dy:Int Local gradient:Float Local xend:Int, yend:Int, xgap:Float, ygap:Float Local xpxl1:Float, ypxl1:Float, xpxl2:Int, ypxl2:Int Local ypyl1:Float, xpyl1:Float, ypyl2:Float, xpyl2:Float Local interx:Float, intery:Float If Abs(x2 - x1) > Abs(y2 - y1) If x1 > x2 tmp = x1 x1 = x2 x2 = tmp tmp = y1 y1 = y2 y2 = tmp dx = x2 - x1 dy = y2 - y1 gradient = dy / Float(dx) xend = round(x1) yend = y1 + gradient * (xend - x1) xgap = rfpart(x1 + 0.5) xpxl1 = xend ypxl1 = ipart(yend) drawPlot(xpxl1, ypxl1, rfpart(yend) * xgap * lastalpha) drawPlot(xpxl1, ypxl1 + 1, fpart(yend) * xgap * lastalpha) intery = yend + gradient xend = round(x2) yend = y2 + gradient * (xend - x2) xgap = fpart(x2 + 0.5) xpxl2 = xend ypxl2 = ipart(yend) drawPlot(xpxl2, ypxl2, rfpart(yend) * xgap * lastalpha) drawPlot(xpxl2, ypxl2 + 1, fpart(yend) * xgap * lastalpha) For Local x:Int = xpxl1 + 1 To xpxl2 - 1 drawPlot(x, ipart(intery), rfpart(intery) * lastalpha) drawPlot(x, ipart(intery) + 1, fpart(intery) * lastalpha) intery = intery + gradient Next Else If y1 > y2 tmp = y1 y1 = y2 y2 = tmp tmp = x1 x1 = x2 x2 = tmp dy = y2 - y1 dx = x2 - x1 gradient = dx / Float(dy) yend = round(y1) xend = x1 + gradient * (yend - y1) ygap = rfpart(y1 + 0.5) ypyl1 = yend xpyl1 = ipart(xend) DrawPlot(xpyl1, ypyl1, rfpart(xend) * ygap * lastalpha) DrawPlot(xpyl1, ypyl1 + 1, fpart(xend) * ygap * lastalpha) interx = xend + gradient yend = round(y2) xend = x2 + gradient * (yend - y2) ygap = fpart(y2 + 0.5) ypyl2 = yend xpyl2 = ipart(xend) DrawPlot(xpyl2, ypyl2, rfpart(xend) * ygap * lastalpha) DrawPlot(xpyl2, ypyl2 + 1, fpart(xend) * ygap * lastalpha) For Local y:Int = ypyl1 + 1 To ypyl2 - 1 DrawPlot(ipart(interx), y, rfpart(interx) * lastalpha) DrawPlot(ipart(interx) + 1, y, fpart(interx) * lastalpha) interx = interx + gradient Next EndIf SetAlpha lastalpha End Function End Type Allerdings verwende ich den Befehl "Plot" weshalb die Funktion viiieeeel langsamer ist als die normale DrawLine-Funktion. Man könnte nun natürlich die Funktion abändern, damit sie auf pixmaps mit WritePixel schreibt, wie schnell das ist habe ich noch nicht getestet. Also man sollte es mit der Funktion jedenfalls nicht übertreiben Falls jemand Bock hat das ganze noch weiter zu optimieren, nur zu, ich weiß grad nicht wie man das noch machen könnte... Ich habs jetzt erstmal als Klasse gemacht, wer will kanns natürlich auch als Funktion implementieren, das sollte ja kein Problem sein Damit mans gleich testen kann hier ein Beispielcode (Bitte oben besagten Code hinzufügen): Code: [AUSKLAPPEN] Graphics 400, 400, 0
SetBlend ALPHABLEND SetClsColor 255, 255, 255 SetColor 0, 0, 0 Global angle:Int While Not KeyHit(27) Cls angle = (angle + 1) Mod 360 TLine.draw(200, 200, 200 + Sin(angle) * 180, 200 + Cos(angle) * 180) Flip Wend Viel Spaß damit! MfG chaos |
||
Projekte: Geolaria | aNemy
Webseite: chaosspace.de |
- Zuletzt bearbeitet von ChaosCoder am So, Apr 20, 2008 15:59, insgesamt einmal bearbeitet
amon |
So, Apr 20, 2008 15:42 Antworten mit Zitat |
|
---|---|---|
Du kannst den Code auch mit Plot nochmal um fast 20% beschleunigen:
Du machst sehr viele gleiche Berechnungen innerhalb der Schleifen bzw. innerhalb des DrawPlot Aufrufes. Du kannst die Berechnung des Alphawertes ausserhalb die Schleife verlagern, in ein Variable speichern - und mit dieser Variable innerhalb der Schleife arbeiten und deinem DrawPlot gleich den vorkalkulierten Alphawert mitgeben. |
||
Tankbuster |
Mo, Apr 21, 2008 14:57 Antworten mit Zitat |
|
---|---|---|
Anstatt PLOT kann man das auch per WritePixelFast machen. Dann halt immernur einen Pixel zeichnen. Das ist laut augenzeugen en bissl schneller ^.^ | ||
Twitter
Download Jewel Snake! Windows|Android |
ChaosCoder |
Mo, Apr 21, 2008 15:21 Antworten mit Zitat |
|
---|---|---|
@amon: wie jetzte? versteh ich nicht, wo mach ich denn in den schleifen viele berechnungen?
@tankbuster: schöner versuch aber wir sind hier unter bmax, da gibbet kein WritePixelFast |
||
Projekte: Geolaria | aNemy
Webseite: chaosspace.de |
BtbN |
Mo, Apr 21, 2008 16:36 Antworten mit Zitat |
|
---|---|---|
Code: [AUSKLAPPEN] SuperStrict
Framework BRL.Max2D Import BRL.GLMax2D Import BRL.PolledInput Import PUB.OpenGL SetGraphicsDriver(GlMax2DDriver()) Graphics 800,600,0,0 SetBlend(ALPHABLEND) glEnable(GL_LINE_SMOOTH) glHint(GL_LINE_SMOOTH_HINT, GL_NICEST) Repeat Cls If KeyHit(KEY_Q) Then glEnable(GL_LINE_SMOOTH) If KeyHit(KEY_W) Then glDisable(GL_LINE_SMOOTH) If KeyHit(KEY_A) Then glHint(GL_LINE_SMOOTH_HINT, GL_FASTEST) If KeyHit(KEY_S) Then glHint(GL_LINE_SMOOTH_HINT, GL_NICEST) If KeyHit(KEY_D) Then glHint(GL_LINE_SMOOTH_HINT, GL_DONT_CARE) DrawLine(400,300,MouseX(),MouseY()) Flip Until KeyHit(KEY_ESCAPE) Or AppTerminate() End |
||
ChaosCoder |
Mo, Apr 21, 2008 17:33 Antworten mit Zitat |
|
---|---|---|
mist
naja, dann halt nich |
||
Projekte: Geolaria | aNemy
Webseite: chaosspace.de |
Tankbuster |
Mo, Apr 21, 2008 19:45 Antworten mit Zitat |
|
---|---|---|
Zitat: @tankbuster: schöner versuch aber wir sind hier unter bmax, da gibbet kein WritePixelFast
*dumm aus der wäsche guck* G_G Tut mir leid. Normalerweise lese ich nie im Max Forum, deshalb dachte ich, das ist Basic >.< |
||
Twitter
Download Jewel Snake! Windows|Android |
amon |
Mo, Apr 21, 2008 21:59 Antworten mit Zitat |
|
---|---|---|
amon hat Folgendes geschrieben: Du kannst den Code auch mit Plot nochmal um fast 20% beschleunigen:
Du machst sehr viele gleiche Berechnungen innerhalb der Schleifen bzw. innerhalb des DrawPlot Aufrufes. Du kannst die Berechnung des Alphawertes ausserhalb die Schleife verlagern, in ein Variable speichern - und mit dieser Variable innerhalb der Schleife arbeiten und deinem DrawPlot gleich den vorkalkulierten Alphawert mitgeben. Stimmt, sorry für die Verwirrung - ich hab zu wenig genau geschaut, und eine Codezeile in deiner Hauptschleife übersehen - damit ist mein Ansatz obsolet geworden. |
||
Übersicht BlitzMax, BlitzMax NG Codearchiv & Module
Powered by phpBB © 2001 - 2006, phpBB Group