Linefunktion (mit/ohne Füllung) schnell
Übersicht

zimtstern#3Betreff: Linefunktion (mit/ohne Füllung) schnell |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Das ist die schnellste line funktion für Mit und Ohne Füllung die mir bis jetzt untergekommen ist. Wurde von einem Freund von mir basierend auf dem Bresenham Algorithmuss geschrieben. Ich hoffe sie kann einigen von euch weiter helfen.
Läuft unter B2d und B+ im Unlocked Buffer. Code: [AUSKLAPPEN] Graphics 800,600,16,2 SetBuffer BackBuffer() ClsColor 255,255,255 Color 255,0,0 radius = 50 Dim pixelup(1) Dim pixeldown(1) füll = 1 While Not KeyHit(1) Cls If MouseHit(1) Then beg = beg + 1 If beg > 1 Then beg = 0 EndIf If MouseHit(2) Then füll = füll + 1 If füll > 1 Then füll = 0 EndIf If MouseZ()+50 >= 0 Then radius = MouseZ() + 50 Linie4(400,300,MouseX(),MouseY(),radius,beg,füll) Flip Wend End Function linie4(X1,Y1,X2,Y2,radius#, begrenzung=0, gefüllt=1) Local rgb=ColorRed()*$10000 + ColorGreen()*$100 + ColorBlue() Local a,b,c,d Local X,Y,P Local alpha#,cosalpha#,sinalpha# Local dx#,dy#,dx1,dy1,dx2,dy2 Local m#,e#,f# dx = (X2 - X1) dy = (Y2 - Y1) If dx=0 Or dy=0 Then;horizontal oder vertikal/////////////////////////////////////////////////// If begrenzung = 0 And gefüllt = 0 Then;nicht gefüllt und kreisförmig If dx=0 Then If Y2<Y1 Then a=Y1 Y1=Y2 Y2=a EndIf Line X1-radius, Y1, X2-radius, Y2 Line X1+radius, Y1, X2+radius, Y2 Else If X2<X1 Then a=X1 X1=X2 X2=a EndIf Line X1, Y1-radius, X2, Y2-radius Line X1, Y1+radius, X2, Y2+radius EndIf a = 4 b = 4 c = 4 X = 0 Y = radius P = 3 - (radius * a) While X < Y WritePixel X1 - X,Y1 - Y,rgb WritePixel X2 + X,Y1 - Y,rgb WritePixel X1 - Y,Y1 - X,rgb WritePixel X2 + Y,Y1 - X,rgb WritePixel X1 - X,Y2 + Y,rgb WritePixel X2 + X,Y2 + Y,rgb WritePixel X1 - Y,Y2 + X,rgb WritePixel X2 + Y,Y2 + X,rgb If P < 0 Then P = P + (X * 4) + 6 Else P = P + ((X - Y) * 4) + 12 Y = Y - 1 EndIf X = X + 1 Wend If X = Y Then WritePixel X1 - X,Y1 - Y,rgb WritePixel X2 + X,Y1 - Y,rgb WritePixel X1 - X,Y2 + Y,rgb WritePixel X2 + X,Y2 + Y,rgb EndIf EndIf If begrenzung = 0 And gefüllt = 1 Then;gefüllt und kreisförmig If dx=0 Then If Y2<Y1 Then a=Y1 Y1=Y2 Y2=a EndIf Line X1-radius, Y1, X2-radius, Y2 Line X1+radius, Y1, X2+radius, Y2 Else If X2<X1 Then a=X1 X1=X2 X2=a EndIf Line X1, Y1-radius, X2, Y2-radius Line X1, Y1+radius, X2, Y2+radius EndIf a = 4 b = 4 c = 4 X = 0 Y = radius P = 3 - (radius * a) While X < Y Rect X1-X, Y1-Y, -X1+X2+2*X, -Y1+Y2+2*Y Rect X1-Y, Y1-X, -X1+X2+2*Y, -Y1+Y2+2*X If P < 0 Then P = P + (X * 4) + 6 Else P = P + ((X - Y) * 4) + 12 Y = Y - 1 EndIf X = X + 1 Wend EndIf Else;schiefe linein///////////////////////////////////////////// If begrenzung = 0 And gefüllt = 0 Then;nicht gefüllt und kreisförmig a = 4 b = 4 c = 4 X = 0 Y = radius P = 3 - (radius * a) alpha = ATan2(Y2-Y1,X2-X1) cosalpha = Cos(alpha) sinalpha = Sin(alpha) While X <= Y dx1 = ( cosalpha * Y + sinalpha*x) dy1 = ( sinalpha * Y - cosalpha*x) dx2 = ( cosalpha * Y - sinalpha*x) dy2 = (-sinalpha * Y - cosalpha*x) WritePixel X1-dx1, y1-dy1, rgb WritePixel X1-dx2, y1+dy2, rgb WritePixel X1+dy1, y1-dx1, rgb WritePixel X1+dy2, Y1+dx2, rgb WritePixel X2+dx1, y2+dy1, rgb WritePixel X2+dx2, y2-dy2, rgb WritePixel X2-dy1, y2+dx1, rgb WritePixel X2-dy2, Y2-dx2, rgb If P < 0 Then P = P + (X * b) + 6 Else P = P + ((X - Y) * c) + 12 Y = Y - 1 EndIf X = X + 1 Wend Line X1+sinalpha*radius, Y1+cosalpha*-radius, X2+sinalpha*radius, Y2+cosalpha*-radius Line X1+sinalpha*-radius, Y1+cosalpha*radius, X2+sinalpha*-radius, Y2+cosalpha*radius EndIf If begrenzung = 0 And gefüllt = 1 Then;gefüllt und kreisförmig If Abs(X1)>Abs(X2) Then;vertauscht die koordinaten so, dass die linien immer von "rechts" nach "links" geht a=X1 X1=X2 X2=a a=Y1 Y1=Y2 Y2=a EndIf dx = (X2 - X1) dy = (Y2 - Y1) If Abs(dy)>Abs(dx) Then;vertauscht die koordinaten so, dass dx kleiner dy a=X1 X1=Y1 Y1=a a=X2 X2=Y2 Y2=a vertauscht=1 EndIf dx = (X2 - X1) dy = (Y2 - Y1) a = 4 b = 4 c = 4 X = 0 Y = radius P = 3 - (radius * a) radius = radius+1;! Dim pixelup(2*radius) Dim pixeldown(2*radius) ;radius = radius-1;! alpha = ATan2(Y2-Y1,X2-X1) cosalpha = Cos(alpha) sinalpha = Sin(alpha) m=dy/dx While X <= Y;schreibt den kreisförmigen Teil der linie in das arrey dx1 = ( cosalpha * Y + sinalpha*x) dy1 = ( sinalpha * Y - cosalpha*x) dx2 = ( cosalpha * Y - sinalpha*x) dy2 = (-sinalpha * Y - cosalpha*x) ;If Abs(dx1) <= radius And Abs(dx2) <= radius And Abs(dy1) <= radius And Abs(dy2) <= radius Then If -dy1 < pixelup(radius - dx1) Then pixelup(radius - dx1) = -dy1 If -dy1 > pixeldown(radius - dx1) Then pixeldown(radius - dx1) = -dy1 If +dy2 < pixelup(radius - dx2) Then pixelup(radius - dx2) = +dy2 If +dy2 > pixeldown(radius - dx2) Then pixeldown(radius - dx2) = +dy2 If -dx1 < pixelup(radius + dy1) Then pixelup(radius + dy1) = -dx1 If -dx1 > pixeldown(radius + dy1) Then pixeldown(radius + dy1) = -dx1 If +dx2 < pixelup(radius + dy2) Then pixelup(radius + dy2) = +dx2 If +dx2 > pixeldown(radius + dy2) Then pixeldown(radius + dy2) = +dx2 ;EndIf If P < 0 Then P = P + (X * b) + 6 Else P = P + ((X - Y) * c) + 12 Y = Y - 1 EndIf X = X + 1 Wend For n=1 To radius;füllt vom bresenham nicht gesetzte teile des arreys auf If pixelup(n)=0 Then pixelup(n)=pixelup(n-1) If pixelup(2*radius-n)=0 Then pixelup(2*radius-n)=pixelup(2*radius-n+1) If pixeldown(n)=0 Then pixeldown(n)=pixeldown(n-1) If pixeldown(2*radius-n)=0 Then pixeldown(2*radius-n)=pixeldown(2*radius-n+1) Next g=0 If Abs(dx) < Abs(2*(sinalpha*radius)) Then;vermeidet das überstehen/"duchstechen" der lnien g = Abs(2*sinalpha*radius) - Abs(dx) EndIf e = sinalpha*radius If m>0 Then;schreibt den durch geraden begrenzten teil in das arrey For n=-e To e - g Step 1 pixeldown(n+radius) = (n+radius-(radius-sinalpha*radius))*m + cosalpha*radius Next Else For n=-e To e - g Step 1 pixeldown(-n+radius) = -((n+radius-(radius-sinalpha*radius))*m + cosalpha*radius) Next For n=-e To e + g Step -1 pixelup(-n+radius) = -((n+radius-(radius-sinalpha*radius))*m + cosalpha*radius);???????? Next EndIf If vertauscht=0;zeichnet je nach Vertauschung das arrey auf den bildschirm For n=0 To 2*radius Step 1 Rect n+x1-radius, pixelup(n)+y1, 1, pixeldown(n)+y1 - (pixelup(n)+y1) Rect -n+x2+radius, -pixeldown(n)+y2, 1, Abs(-pixeldown(n)+y2 - (-pixelup(n)+y2)) Next Else For n=0 To 2*radius Step 1 Rect pixelup(n)+y1, n+x1-radius, pixeldown(n)+y1 - (pixelup(n)+y1), 1 Rect -pixeldown(n)+y2, -n+x2+radius, Abs(-pixeldown(n)+y2 - (-pixelup(n)+y2)), 1 Next EndIf If g=0 Then a = Sgn(dx)*Sgn(dy) b = (2*radius)/cosalpha X1 = X1 + sinalpha*radius*a X2 = X2 - sinalpha*radius*a If a=1 Then Y1 = Y1 - radius*cosalpha Y2 = Y2 - b + radius*cosalpha Else If dx<0 Then Y2 = Y2 + b - radius*cosalpha Y1 = Y1 + radius*cosalpha Else Y2 = Y2 - radius*cosalpha Y1 = Y1 - b + radius*cosalpha EndIf EndIf If vertauscht=1 Then dx = (X2 - X1) dy = (Y2 - Y1) b = Abs(b) m = dy/dx a=X1 X1=Y1 Y1=a a=X2 X2=Y2 Y2=a For n=0 To b-1 Line x1+n,y1,x2+n,y2 Next Else dx = (X2 - X1) dy = (Y2 - Y1) b = Abs(b) m = dy/dx For n=0 To b-1 Line x1,y1+n,x2,y2+n Next EndIf EndIf EndIf EndIf End Function |
||
![]() |
diGGaGruppenKaspar |
![]() Antworten mit Zitat ![]() |
---|---|---|
da entsteht son weisser kasten in der mitte wenn man die maus leicht nach rechts zieht.. is das beabsichtigt? | ||
Gestern Nacht Schlug der Regen an mein Fenster
Ich ging durch das dunkle Zimmer und glaubte im Licht der Straßenlampe Den Geist unseres jahrhunderts auf der Straße zu sehen Der uns sagte, daß wir alle am Rande des Abgrunds stehen. - Al Steward Athlon 64 3000+ / Radeon 9600 / 1024mb ddram |
zimtstern#3 |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Oh.. das passiert wenn man der Abstand der beiden Punkte kleiner als der doppelte Radius ist... falls das der fall sein sollte muss man das weise rechteck halt noch füllen lassen | ||
Hot-BitSieger des B2D Retro Wettbewerb / Aug 04 |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Hoi.
Der schnellste vielleicht, den du gesehen hast ![]() Ich kenne schnellere, und dazu noch Bug-freie ![]() Da gehört noch einiges verbessert. Fahr zB mal in eine Ecke mit der Maus. Da werden etliche Pixel nicht gezeichnet ..... Außerdem ist das Prog doch recht groß ... Toni |
||
... ..... .i.. ...
*** Sieger des BB-Gameboy-Contest 2004 Sieger des Blitzbaster 2D-Minigolf-Contest 2005 *** |
zimtstern#3 |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Du kennst schnellere ...?
Welche denn? Sowas ist verdammt schwierig zu finden. Ich dachte ich hätte alle ausprobiert. Das die Pixel in der Ecke nicht gezeichnet werden ist richtig. Liegt aber an BB wieso das so ist hab ich noch nicht rausgefunden. aber alle Winkel funktionieren solange man den Rand nicht berührt. Irgendwas stimmt dann mit den Winkelfunktionen nichtmehr. |
||
![]() |
stfighter01 |
![]() Antworten mit Zitat ![]() |
---|---|---|
bresenham, sinus- cosinus ? stirnrunzel
ich kenn nur den bresenham kreiszeichenalgo, und das schöne an ihm war das kein sin u. cos darin vorkam und deshalb war er so stark optimiert. wies bei solcherart linen aussieht weiss ich nicht, aber auch hier sollte eine sinusfunktion überflüssig sein. trotzdem ganz nett, aber ich würd das mit den pixelfehlern noch fixen. mfg stfighter |
||
Denken hilft! |
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group