MiniBCC #6 Auswertung

Übersicht Sonstiges Projekte

Neue Antwort erstellen

Wer hat die schönste Umsetzung der Drachenkruve?
BlitzMoritz 76% 76% 16 Stimmen
LordCoder 14% 14% 3 Stimmen
Thunder 9% 9% 2 Stimmen
Insgesamt 21 Stimmen

Ana

Betreff: MiniBCC #6 Auswertung

BeitragMo, Jan 14, 2013 1:26
Antworten mit Zitat
Benutzer-Profile anzeigen
Diesmal haben wir drei Abgaben, die Ergebnisse sehen natürlich durch die Aufgabenstellung sehr gleich aus.

Aber durch den vielen Code für die kleine Aufgabe gab es ja jede Menge Möglichkeiten schön zu coden. Also möge der Beste gewinnen!

Ende der Abstimmung ist nächster Sonntag (20.1.13)


Die Downloads
BlitzMoritz
Thunder

Und der jeweilige Code

BlitzMoritz
BlitzMax: [AUSKLAPPEN]
SuperStrict

'Mit OpenGL erschien es mir schneller, daher den entspr. Treiber laden:
Framework BRL.GLMax2D
Import BRL.Timer
Import BRL.PNGLoader
SetGraphicsDriver GLMax2DDriver()

'Wegen der Animation unabdingbar, der Prozessor-schonende Timer:
Global timer:TTimer = CreateTimer(60)

'Ausnahmsweise ein Vollbildschirm des vorhandenen PC's:
Global scx% = DesktopWidth(), scy% = DesktopHeight()
Graphics scx, scy, DesktopDepth()

'die kompletten Regenbogenfarben als Spektrum mit entspr. RGB-Daten definieren:
Global Red%[1536], Green%[1536], Blue%[1536]
For Local i% = 0 To 255
Red[i] = 255
Green[i] = i
Red[256+i] = 255 - i
Green[256+i] = 255
Green[512+i] = 255
Blue[512+i] = i
Green[768+i] = 255 - i
Blue[768+i] = 255
Blue[1024+i] = 255
Red[1024+i] = i
Blue[1280+i] = 255 - i
Red[1280+i] = 255
Next

'Als erstes soll ein der individuellen Bildschirmgroesse optimal
'angepasster weisser Drache gezeichnet werden. Die Startposition,
'die maximale Ordnung und die Anfangsrichtung sind Erfahrungswerte:
If scy < 850 Then
white_dragon(0.5*scx-214, 0.5*scy+84, 17, 0)
ElseIf scx < 1535 Or scy < 1023 Then
white_dragon(0.5*scx-172, 0.5*scy+256, 18, 3)
Else
white_dragon(0.5*scx-430, 0.5*scy+170, 19, 3)
End If
DrawText "Mit Mausklick weiter zur animierten Reise", 10, 30
DrawText "durch den Regenbogendrachen 20.Ordnung", 10, 50
Flip

'Warten auf die Benutzereingaben, bis es weitergeht ...
Repeat
WaitTimer(timer)
If MouseDown(1) Or MouseDown(2) Then Exit
If KeyDown(KEY_ESCAPE) Then End
Forever

'Für die folgende Berechnung könnte u.U. einige Zeit vergehen, darum ...
Cls
DrawText "Bitte warten: Reisevorbereitungen ...",scx/2-152, scy/2-10
Flip

'Nun wird das Bild eines farbigens Drache 20.Ordnung erstellt,
'welcher mit den Maßen 2047 x 1707 in der Regel für jeden Bild-
'schirm zu groß ist, darum wird er aus einzelnen Teilen zusammengesetzt:
Local dragon:TImage = load_bigdragonimage()
MidHandleImage(dragon)

'Am Ende der folgenden Animation soll der (zu große) farbige Drache geringst-
'möglich verkleinert werden, damit er komplett in den Bildschirm (mit
'ein bisschen Abstand) passt, darum hier die Berechnung der Skalierung:
Local start_scale# = 2 + Min(scx/2068.0, scy/1727.0)

'Zeit messen:
Local time% = MilliSecs()
'und Maus verstecken (die stört nur den Anblick):
HideMouse()
'und es folgt die Animationsschleife:
Repeat
Cls

'die "Reise" soll eine halbe Minute dauern, darum hier der Fortschritt:
Local value# = (MilliSecs() - time) / 30000.0

'der Drachen soll insgesamt eine halbe Drehung machen:
SetRotation value*180

'die Reise führt spiralförmig durch den Drachen, um seine eigene Ent-
'stehung mit Hilfe des Farbspektrums nachvollziehen zu können, darum
'soll der Abstand vom Zentrum (quadratisch) immer kleiner werden:
Local distance# = 750 - value*value*750
'ausgehend vom Startwinkel 115° (da wo ungefähr der Anfang liegt)
Local angle# = 115 + 420*value*value

'die "Flughöhe" soll kontinuierlich bis zum bereits errechneten
'Endwert ansteigen, so dass am Anfang viel Detail und am Ende
'die Totale des Regenbogendrachens zu sehen sein wird:
Local scale# = start_scale - 2*value
SetScale scale, scale

'Die Drehung und Betrachtung soll immer zentriert sein, darum:
SetImageHandle dragon, 1024 + distance*Cos(angle), 853 + distance*Sin(angle)
DrawImage dragon, 0.5*scx, 0.5*scy

'zum Schluss ein paar Hinweise ...
SetScale 1,1
SetRotation 0
DrawText "Regenbogen-Drachenkurve 20.Ordnung", 10, 10
DrawText "Mit Escape abbrechen", 10, 30
Flip
WaitTimer(timer)
If KeyDown(KEY_ESCAPE) Then End
If value >= 1 Then Exit 'Reise zu Ende!
Forever
'Am Ende der animierten Reise ein automatisches Abspeichern der Drachenkurve:
SavePixmapPNG(LockImage(dragon), "BlitzMoritz-Regenbogendrachen 20.Ordnung.png")
'Warten auf das Ende ...
Repeat
WaitTimer(timer)
If KeyDown(KEY_ESCAPE) Then End
Forever

'Nun folgenden die eigentlichen Algorithmen für die Drachenkurven
'----------------------------------------------------------------

'Die folgende Funktion malt eine Drachenkurve beliebiger Ordnung,
'die von ihrem Anfang bis zum Ende die Regenbogenfarben einmal durchläuft.

'Die Argumente x und y geben die Startposition des Fraktals an,
'der Wert max_2exp die Ordnung der Kurve bzw. ihre immanente Zweierpotenz,
'die "start_direction bestimmt", in welche Richtung der erste Schritt geht.

Function rainbow_dragon(x%, y%, max_2exp%, start_direction%)

Local sum% 'zählt als Laufvariable alle gezeichneten Schritte
Local totalsum# = 2*2^max_2exp 'ist die erwartete Gesamtzahl aller Schritte

Local direction%[] = [start_direction] 'ist ein Array, der sich alle Schritte einer Ordnung merkt.
Local next_direction%[] 'ist jener Array, der die vorigen Schritte rückwärts durchläuft und dreht.

Local x_step%[] = [0,1,0,-1] 'hier werden die vier Bewegungsrichtungen festgelegt:
Local y_step%[] = [-1,0,1,0] '0 = nach Oben, 1 = nach Rechts, 2 = nach Unten, 3 = nach Links.

Local count% = 1 'merkt sich die Größe des direction-Arrays

'Nun leitet sich jede weitere Ordnung aus der vorigen ab (bis zur definierten Zielordnung.)
For Local e% = 0 To max_2exp
next_direction = New Int[count]

'jeder Schritt der vorigen Ordnung kommt zum Tragen:
For Local i% = 0 Until count

'die Indexposition innerhalb des Regenbogenspektrums:
Local RGB_Index% = sum / totalsum * 1536

'damit Details sichtbar werden, hier eine periodische Abstufung der Helligkeit,
'wobei der Wert 543210 nichts besonderes bedeutet, als dass es gut aussieht:
Local brigthness# = 0.7 + 0.3 * Sin(sum / totalsum * 543210)
SetColor brigthness*Red[RGB_Index], brigthness*Green[RGB_Index], brigthness*Blue[RGB_Index]
sum:+1 'Zählung aller Punkte

Plot x,y

'die neuen Punkte der nächsten Ordnung laufen die alten umgekehrt durch,
'und werden durch die Addition + 1 um 90° gedreht:
next_direction[i] = (direction[count-1-i] + 1) Mod 4

'Update der Position:
x = x + x_step[next_direction[i]]
y = y + y_step[next_direction[i]]
Next

'Nun wird aus den beiden Teilen der neue Array zusammengefügt:
direction = direction + next_direction

'und die Zweierpotenz weitergezählt:
count:*2
Next
End Function


'der weiß-schattierte Drachen enthält nichts Neues, sondern re-
'duziert nur die Farbgebung und ergänzt die Messung der Rechenzeit:

Function white_dragon(x%, y%, max_2exp%, start_direction%)
Local sum%, totalsum# = 2*2^max_2exp
Local next_direction%[], direction%[] = [start_direction]
Local x_step%[] = [0,1,0,-1]
Local y_step%[] = [-1,0,1,0]
Local count% = 1, time% = MilliSecs()
For Local e% = 0 To max_2exp
next_direction = New Int[count]
For Local i% = 0 Until count
Local brigthness# = 179 + 77.0 * Sin(sum / totalsum * 543210)
sum:+1
SetColor brigthness, brigthness, brigthness
Plot x,y
next_direction[i] = (direction[count-1-i] + 1) Mod 4
x = x + x_step[next_direction[i]]
y = y + y_step[next_direction[i]]
Next
direction = direction + next_direction
count:*2
Next
SetColor 200,200,200
DrawText "Weisse Drachenkurve " + max_2exp + ".Ordnung in " + (MilliSecs()-time) + " Millisekunden.", 10, 10
End Function


'In der abschließenden Funktion wird ein Bild, das für den Bildschirm
'eigentlich zu groß ist, aus mehreren Drachenzeichnungen zusammengefügt:

Function load_bigdragonimage:TImage()

'In der Hoffnung, dass solch kleine Auflösung heute nicht mehr verwendet werden:
If scx < 1024 Or scy < 569 Then RuntimeError("Die Bildschirmaufloesung ist zu niedrig!")

'Die Gesamtpixmap mit der Größe 2048 x 1707 Pixel:
Local TotalPixmap:TPixmap = CreatePixmap(2048, 1707, PF_BGRA8888)

'und der jeweils gegrabbte Teil:
Local Part:TPixmap


'Abhängig von der Bildschirmauflösung werden jetzt 5 bzw. 4 oder 3 Drachen 20.Ordnung
'mit variabler Position gezeichnet und gegrabbt, das dauert ein wenig ....

If scy < 854 Then '(die Hälfte der vertikalen Tiefe 1707 Pixel)
For Local i% = 0 To 1
For Local j% = 0 To 2
'Ganz Rechts unten befindet sich eine leere Zeichenlücke,
If i+j = 3 Then Exit 'die darum nicht gegrabbt werden muss.
Cls
'Drachen malen ...
rainbow_dragon(682 - i*1024, 1366 - j*569, 20, 2)
'Teil grabben ...
Part = GrabPixmap(0,0,1024,569)
'In Gesamtbild einkleben ...
TotalPixmap.Paste(Part, i*1024, j*569)
Next
Next
Else
For Local i% = 0 To 1
For Local j% = 0 To 1
'Eventuell befindet sich auch hier Rechts unten eine leere Zeichenlücke,
If i+j = 2 And scy >= 1023 Then Exit 'die darum nicht gegrabbt werden muss.
Cls
'Drachen malen ...
rainbow_dragon(682 - i*1024, 1366 - j*scy, 20, 2)
'Teil grabben ...
If j = 0 Then
Part = GrabPixmap(0,0,1024,scy)
Else 'die unteren Teile drüfen zum pasten nicht zu groß sein:
Part = GrabPixmap(0,0,1024,1707-scy)
End If
'In Gesamtbild einkleben ...
TotalPixmap.Paste(Part, i*1024, j*scy)
Next
Next
End If
SetColor 255,255,255
'Das Gesamtbild soll keinen schwarzen Hintergrund haben:
TotalPixmap = MaskPixmap(TotalPixmap,0,0,0)
'Rückgabe des erstellten Gesamtbilds als TImage:
Return LoadImage(TotalPixmap)
End Function






LordCoder
BlitzBasic: [AUSKLAPPEN]
AppTitle("Drachenkurven")
Graphics 649,480, 0,2
dragon(100,200,400,200,1,20)
Function dragon(x1,y1,x2,y2,dir,n)
If(n<1)
Line x1,y1,x2,y2
Else
If dir=1 ;uhrzeigersinn-knicks
dragon(x1,y1, x1+(x2-x1)/2+(y2-y1)/2,y1+(y2-y1)/2-(x2-x1)/2,1,n-1)
dragon(x1+(x2-x1)/2+(y2-y1)/2,y1+(y2-y1)/2-(x2-x1)/2, x2,y2,2,n-1)
Else If dir=2 ; gegenuhrzeigersin-knicks
dragon(x1,y1, x1+(x2-x1)/2-(y2-y1)/2,y1+(y2-y1)/2+(x2-x1)/2,1,n-1)
dragon(x1+(x2-x1)/2-(y2-y1)/2,y1+(y2-y1)/2+(x2-x1)/2, x2,y2,2,n-1)
EndIf
EndIf
End Function
WaitKey
End


Thunder
BlitzMax: [AUSKLAPPEN]
Strict
Framework brl.blitz
Import brl.max2d
Import brl.timer
Import brl.pngloader
?Win32
Import brl.d3d9max2d
?Not Win32
Import brl.glmax2d
?

Graphics 800,600

Global ORDER = 20 ' Ordnung



If AppArgs.length>1 And AppArgs[1] Then ORDER = Int(AppArgs[1])

Global info:String

AutoMidHandle True
Local pix:TPixmap = CreateCurve(ORDER)
Local img:TImage
Local px = GraphicsWidth()/2, py = GraphicsHeight()/2
Local mpx = px, mpy = py
Local mxs, mys, mzs, size# = 1
Local timer:TTimer = CreateTimer(50)

img = LoadImage(pix)

Repeat
Cls

If KeyHit(KEY_RETURN) Then
SavePixmapPNG pix, "curve.png",3
addinfo "Saved."
EndIf

mxs = MouseXSpeed()
mys = MouseYSpeed()
mzs = MouseZSpeed()

If MouseDown(MOUSE_MIDDLE) Then SetScale 1, 1; size = 1; px = mpx; py = mpy
If MouseDown(MOUSE_LEFT) Then px:+mxs ; py:+mys
If mzs Then size:+mzs/30.0

SetScale size, size
DrawImage img, px, py
drawinfo

Flip 0
WaitTimer timer
Until KeyHit(KEY_ESCAPE) Or AppTerminate()
End

Function drawinfo()
Local s:String = info, y = -6
SetScale 1,1
Repeat
y:+16
s = s[s.find("~n")+1..]
DrawText s[..s.find("~n")], 10, y
If s.find("~n")<0 Then Exit
Forever
DrawText s, 10, y
EndFunction

Function addinfo(s:String)
info:+"~n"+s
drawinfo
EndFunction

Function CreateCurve:TPixmap(o)
Local t:TTurtle = New TTurtle
Local x, y, w, h, time

time = MilliSecs()
Cls
addinfo "Creating Curve String ..."
Flip
t.drawing = CreateCurveString(o)

Cls
addinfo "Analyzing Curve ..."
Flip
AnalyzeCurve t.drawing, x, y, w, h

Cls
addinfo "Width: " + w + " Height: " + h
addinfo "Drawing Curve ... 0%"
Flip
t.x = x
t.y = y
DebugLog "W: "+ w
DebugLog "H: "+ h
t.pixmap = CreatePixmap(w, h, PF_RGB888)


t.drawtopixmap
time = MilliSecs() - time

addinfo "Finished. Time needed : "+time+ " ms"
addinfo "Press Return to save."
Return t.pixmap
EndFunction

Function curve:String(o)
Local s:String, g:String
If o = 1 Then
Return "R"
Else
g = curve(o-1)
s = g + "R" + g[..g.length/2] + "L" + g[g.length/2+1..]
Return s
EndIf
EndFunction

Function CreateCurveString:String(o)
Return curve(o)
EndFunction

Function AnalyzeCurve(c:String, xc Var, yc Var, width Var, height Var)
Local x, y, i, w = 270
Local maxx, maxy
Local minx, miny
For i = 1 Until c.length-1 Step 2
Select c[i-1]
Case Asc "R"
w:+90
Case Asc "L"
w:-90
EndSelect
Select w Mod 360
Case 0
x:+1
Case 90
y:+1
Case 180
x:-1
Case 270
y:-1
EndSelect
Select c[i]
Case Asc "R"
w:+90
Case Asc "L"
w:-90
EndSelect
Select w Mod 360
Case 0
x:+1
Case 90
y:+1
Case 180
x:-1
Case 270
y:-1
EndSelect
If x > maxx Then maxx = x
If x < minx Then minx = x
If y > maxy Then maxy = y
If y < miny Then miny = y
Next
xc = -minx+1
yc = -miny+1
maxx :- minx
maxy :- miny
width = maxx + maxx Mod 2 + 2
height = maxy + maxy Mod 2 + 2
EndFunction

Type TTurtle
Field x#,y#
Field w
Field pixmap:TPixmap

Field drawing:String

Method New()
w = 270
x = GraphicsWidth()/2
y = GraphicsHeight()/2
EndMethod

Method drawtopixmap()
Global r#=256, g#=256, b#=256, rgb
Local x1, y1
Local i, e
Local width = PixmapWidth(pixmap)
Local height = PixmapHeight(pixmap)
Local p1, p2
ClearPixels pixmap, $010101

For i = 1 Until drawing.length-1 Step 2
x1 = x ; y1 = y

p1 = 100.0*i/drawing.length
If p1 > p2 Then
info = info[..info.length-3]
If p1<10 Then info:+" "
info :+ String(p1)+"%"
p2 = p1
Cls
drawinfo
Flip
EndIf

r = r + w/144000.0
b = 128 + Sin(e*36)*127
g = g + 0.005
While r > 255 ; r:-156 ; Wend
While g > 255 ; g:-176 ; Wend
While b > 255 ; b:-196 ; Wend
rgb = (Int(r) Shl 16) | (Int(g) Shl 8) | Int(b)


Select drawing[i-1]
Case Asc "R"
w:+90
Case Asc "L"
w:-90
EndSelect
Select w Mod 360
Case 0
If y > 0 Then WritePixel pixmap, x, y-1, rgb
x:+1
Case 90
If x < width-1 Then WritePixel pixmap, x+1, y, rgb
y:+1
Case 180
If y < height-1 Then WritePixel pixmap, x, y+1, rgb
x:-1
Case 270
If x > 0 Then WritePixel pixmap, x-1, y, rgb
y:-1
EndSelect

Select drawing[i]
Case Asc "R"
w:+90
Case Asc "L"
w:-90
EndSelect
Select w Mod 360
Case 0
x:+1
Case 90
y:+1
Case 180
x:-1
Case 270
y:-1
EndSelect
WritePixel pixmap, x, y, rgb
WritePixel pixmap, x1, y1, rgb

Next
info = info[..info.length-3]+"100%"
Cls
drawinfo
Flip
EndMethod
EndType
  • Zuletzt bearbeitet von Ana am Di, Jan 15, 2013 18:39, insgesamt einmal bearbeitet

BlitzMoritz

BeitragMo, Jan 14, 2013 12:36
Antworten mit Zitat
Benutzer-Profile anzeigen
Evil or Very Mad Ich Trottel hab' doch tatsächlich vergessen, dass ich die Pixel ja gleich in die Pixmap hätte schreiben können, statt den Drachen mehrfach zu zeichnen, dümmlich zu grabben und zusammen zu kleben, so ein shit! Das werde ich natürlich noch nachkorrigieren, auch wenn's hier zu spät erfolgt. Aber eigentlich kam's ja mehr auf die Algorithmus-Schnelligkeit und Ästhetik der Drachenkurve an. (...auf Nachsicht hoff'...)

Edit: So, hier noch der korrigierte Nachtrag ohne das unsägliche Grabben in meiner load_bigdragonimage-Funktion. Sonst bleibt alles beim Alten, nur die Wartezeit vor der Animation verkürzt sich deutlich Wink.
Hier bei Bedarf der neue Exe-Download und der Code:
BlitzMax: [AUSKLAPPEN]
SuperStrict

'Mit OpenGL erschien es mir schneller, daher den entspr. Treiber laden:
Framework BRL.GLMax2D
Import BRL.Timer
Import BRL.PNGLoader
SetGraphicsDriver GLMax2DDriver()

'Wegen der Animation unabdingbar, der Prozessor-schonende Timer:
Global timer:TTimer = CreateTimer(60)

'Ausnahmsweise ein Vollbildschirm des vorhandenen PC's:
Global scx% = DesktopWidth(), scy% = DesktopHeight()
Graphics scx, scy, DesktopDepth()

'die kompletten Regenbogenfarben als Spektrum mit entspr. RGB-Daten definieren:
Global Red%[1536], Green%[1536], Blue%[1536]
For Local i% = 0 To 255
Red[i] = 255
Green[i] = i
Red[256+i] = 255 - i
Green[256+i] = 255
Green[512+i] = 255
Blue[512+i] = i
Green[768+i] = 255 - i
Blue[768+i] = 255
Blue[1024+i] = 255
Red[1024+i] = i
Blue[1280+i] = 255 - i
Red[1280+i] = 255
Next

'Als erstes soll ein der individuellen Bildschirmgroesse optimal
'angepasster weisser Drache gezeichnet werden. Die Startposition,
'die maximale Ordnung und die Anfangsrichtung sind Erfahrungswerte:
If scy < 850 Then
white_dragon(0.5*scx-214, 0.5*scy+84, 17, 0)
ElseIf scx < 1535 Or scy < 1023 Then
white_dragon(0.5*scx-172, 0.5*scy+256, 18, 3)
Else
white_dragon(0.5*scx-430, 0.5*scy+170, 19, 3)
End If
DrawText "Mit Mausklick weiter zur animierten Reise", 10, 30
DrawText "durch den Regenbogendrachen 20.Ordnung", 10, 50
Flip

'Warten auf die Benutzereingaben, bis es weitergeht ...
Repeat
WaitTimer(timer)
If MouseDown(1) Or MouseDown(2) Then Exit
If KeyDown(KEY_ESCAPE) Then End
Forever

'Nun wird das Bild eines farbigens Drache 20.Ordnung erstellt,
Local dragon:TImage = load_bigdragonimage()
MidHandleImage(dragon)

'Am Ende der folgenden Animation soll der (zu große) farbige Drache geringst-
'möglich verkleinert werden, damit er komplett in den Bildschirm (mit
'ein bisschen Abstand) passt, darum hier die Berechnung der Skalierung:
Local start_scale# = 2 + Min(scx/2068.0, scy/1727.0)

'Zeit messen:
Local time% = MilliSecs()
'und Maus verstecken (die stört nur den Anblick):
HideMouse()
'und es folgt die Animationsschleife:
Repeat
Cls

'die "Reise" soll eine halbe Minute dauern, darum hier der Fortschritt:
Local value# = (MilliSecs() - time) / 30000.0

'der Drachen soll insgesamt eine halbe Drehung machen:
SetRotation value*180

'die Reise führt spiralförmig durch den Drachen, um seine eigene Ent-
'stehung mit Hilfe des Farbspektrums nachvollziehen zu können, darum
'soll der Abstand vom Zentrum (quadratisch) immer kleiner werden:
Local distance# = 750 - value*value*750
'ausgehend vom Startwinkel 115° (da wo ungefähr der Anfang liegt)
Local angle# = 115 + 420*value*value

'die "Flughöhe" soll kontinuierlich bis zum bereits errechneten
'Endwert ansteigen, so dass am Anfang viel Detail und am Ende
'die Totale des Regenbogendrachens zu sehen sein wird:
Local scale# = start_scale - 2*value
SetScale scale, scale

'Die Drehung und Betrachtung soll immer zentriert sein, darum:
SetImageHandle dragon, 1024 + distance*Cos(angle), 853 + distance*Sin(angle)
DrawImage dragon, 0.5*scx, 0.5*scy

'zum Schluss ein paar Hinweise ...
SetScale 1,1
SetRotation 0
DrawText "Regenbogen-Drachenkurve 20.Ordnung", 10, 10
DrawText "Mit Escape abbrechen", 10, 30
Flip
WaitTimer(timer)
If KeyDown(KEY_ESCAPE) Then End
If value >= 1 Then Exit 'Reise zu Ende!
Forever
'Am Ende der animierten Reise ein automatisches Abspeichern der Drachenkurve:
SavePixmapPNG(LockImage(dragon), "BlitzMoritz-Regenbogendrachen 20.Ordnung.png")
'Warten auf das Ende ...
Repeat
WaitTimer(timer)
If KeyDown(KEY_ESCAPE) Then End
Forever

'Nun folgenden die eigentlichen Algorithmen für die Drachenkurven
'----------------------------------------------------------------

'Die folgende Funktion malt eine Drachenkurve beliebiger Ordnung,
'die von ihrem Anfang bis zum Ende die Regenbogenfarben einmal durchläuft.

'Die Argumente x und y geben die Startposition des Fraktals an,
'der Wert max_2exp die Ordnung der Kurve bzw. ihre immanente Zweierpotenz,
'die "start_direction bestimmt", in welche Richtung der erste Schritt geht.

Function rainbow_dragon(x%, y%, max_2exp%, start_direction%)

Local sum% 'zählt als Laufvariable alle gezeichneten Schritte
Local totalsum# = 2*2^max_2exp 'ist die erwartete Gesamtzahl aller Schritte

Local direction%[] = [start_direction] 'ist ein Array, der sich alle Schritte einer Ordnung merkt.
Local next_direction%[] 'ist jener Array, der die vorigen Schritte rückwärts durchläuft und dreht.

Local x_step%[] = [0,1,0,-1] 'hier werden die vier Bewegungsrichtungen festgelegt:
Local y_step%[] = [-1,0,1,0] '0 = nach Oben, 1 = nach Rechts, 2 = nach Unten, 3 = nach Links.

Local count% = 1 'merkt sich die Größe des direction-Arrays

'Nun leitet sich jede weitere Ordnung aus der vorigen ab (bis zur definierten Zielordnung.)
For Local e% = 0 To max_2exp
next_direction = New Int[count]

'jeder Schritt der vorigen Ordnung kommt zum Tragen:
For Local i% = 0 Until count

'die Indexposition innerhalb des Regenbogenspektrums:
Local RGB_Index% = sum / totalsum * 1536

'damit Details sichtbar werden, hier eine periodische Abstufung der Helligkeit,
'wobei der Wert 543210 nichts besonderes bedeutet, als dass es gut aussieht:
Local brightness# = 0.7 + 0.3 * Sin(sum / totalsum * 543210)
SetColor brightness*Red[RGB_Index], brightness*Green[RGB_Index], brightness*Blue[RGB_Index]
sum:+1 'Zählung aller Punkte

Plot x,y

'die neuen Punkte der nächsten Ordnung laufen die alten umgekehrt durch,
'und werden durch die Addition + 1 um 90° gedreht:
next_direction[i] = (direction[count-1-i] + 1) Mod 4

'Update der Position:
x = x + x_step[next_direction[i]]
y = y + y_step[next_direction[i]]
Next

'Nun wird aus den beiden Teilen das neue Array zusammengefügt:
direction = direction + next_direction

'und die Zweierpotenz weitergezählt:
count:*2
Next
End Function


'der weiß-schattierte Drachen enthält nichts Neues, sondern re-
'duziert nur die Farbgebung und ergänzt die Messung der Rechenzeit:

Function white_dragon(x%, y%, max_2exp%, start_direction%)
Local sum%, totalsum# = 2*2^max_2exp
Local next_direction%[], direction%[] = [start_direction]
Local x_step%[] = [0,1,0,-1]
Local y_step%[] = [-1,0,1,0]
Local count% = 1, time% = MilliSecs()
For Local e% = 0 To max_2exp
next_direction = New Int[count]
For Local i% = 0 Until count
Local brightness# = 179 + 77.0 * Sin(sum / totalsum * 543210)
sum:+1
SetColor brightness, brightness, brightness
Plot x,y
next_direction[i] = (direction[count-1-i] + 1) Mod 4
x = x + x_step[next_direction[i]]
y = y + y_step[next_direction[i]]
Next
direction = direction + next_direction
count:*2
Next
SetColor 200,200,200
DrawText "Weisse Drachenkurve " + max_2exp + ".Ordnung in " + (MilliSecs()-time) + " Millisekunden.", 10, 10
End Function


'Die abschließende (nachträglich korrigierte) Funktion stellt nur eine Variante von 'rainbow_dragon':
'Statt mit plot in den Backbuffer wird mit Writepixel in eine Pixmap geschrieben.
Function load_bigdragonimage:TImage()
'Die Gesamtpixmap mit der Größe 2048 x 1707 Pixel:
Local Pixmap:TPixmap = CreatePixmap(2048, 1707, PF_BGRA8888)
Local x% = 682, y% = 1366, max_2exp% = 20, sum%, totalsum# = 2097152
Local next_direction%[], direction%[] = [2]
Local x_step%[] = [0,1,0,-1], y_step%[] = [-1,0,1,0], count% = 1
For Local e% = 0 To max_2exp
next_direction = New Int[count]
For Local i% = 0 Until count
Local RGB_Index% = sum / totalsum * 1536
Local brightness# = 0.7 + 0.3 * Sin(sum / totalsum * 543210)
sum:+1 'Zählung aller Punkte
WritePixel(Pixmap, x, y, (-16777216+ Int(brightness*Red[RGB_Index])*$10000+ Int(brightness*Green[RGB_Index])*$100+ Int(brightness*Blue[RGB_Index])))
next_direction[i] = (direction[count-1-i] + 1) Mod 4
x = x + x_step[next_direction[i]]
y = y + y_step[next_direction[i]]
Next
direction = direction + next_direction
count:*2
Next
'Das Gesamtbild soll keinen schwarzen Hintergrund haben:
Pixmap = MaskPixmap(Pixmap,0,0,0)
'Rückgabe des erstellten Gesamtbilds als TImage:
Return LoadImage(Pixmap)
End Function

Thunder

BeitragMo, Jan 14, 2013 22:11
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich finde ja deine Version, BlitzMoritz, äußerst schön! Die Idee mit der Farbgebung und dann die tolle Kamerafahrt! Very Happy
Und sogar kommentiert!
Gönne ich dir sehr wenn/dass du gewinnst Wink

Deins, LordCoder, besticht mit seiner Kürze. Das ist auch ordentlich!

Mein Beispiel ist eher, was kriegt man hin, wenn man sich noch nie mit dem Thema beschäftigt hat und versucht eine einigermaßen schöne Farbgebung zu erreichen. Sieht man auch an meinem Code. Ich bin offenbar der einzige, der das Erstellen der Kurve unterteilt hat in Stringerstellung (für meine Schildkröte), Analyse (um das Bild zu zentrieren und zu schauen, wie groß es ist) und Zeichnen (was den String benützt). Zugegeben, der Code ist nicht schön unterteilt - ich habe nur geschaut, dass ich mich halbwegs auskenne.
Meine Sachen: https://bitbucket.org/chtisgit https://github.com/chtisgit

BlitzMoritz

BeitragMi, Jan 16, 2013 18:18
Antworten mit Zitat
Benutzer-Profile anzeigen
Danke, Thunder Smile - und wer mir mit seinem Code meine Grab-Dusseligkeit vor Augen geführt hat, kannst du dir denken ... Wink
Mich hat's übrigens immer noch nicht losgelassen, und so möchte ich zum Abschluss noch ein Programm nachliefern, mit dem man auf Tastendruck die Drachenkurve anwachsen lassen kann, die Farbgebung variieren, mit der Maus verschieben (wie bei Thunder) und per Mausrad zoomen kann: Hier der Download.
Die Ordnung habe ich auf maximal 25 beschränkt, doch wird die meiste Hardware schon vorher aufgegeben haben. Wenn's dann abstürzt oder nur noch eine weiße oder schwarze Pixmap zu sehen ist, dass liegt's nicht am Programm! Wer ahnt, dass seine Hardware es nicht schaffen wird, kann ja schon vorher aufhören. Immerhin ist bereits die 24.Ordnung schon 8192 x 6827 Pixel groß. Auch bei meinem besten Rechner klappte die 25.Ordnung nur mit Glück ein paar mal.
Immerhin sind 10% davon hier verewigt, wobei das Original-PNG-Monster dort schlummert.

Ana

BeitragMi, Jan 16, 2013 20:52
Antworten mit Zitat
Benutzer-Profile anzeigen
Wie schön, dass es dir scheinbar Spaß macht Smile

Um ehrlich zu sein, hatte ich auch zumindest auf Zoombarkeit auch gehofft
Don't only practice your art,
but force your way into its secrets,
for it and knowledge
can raise human to divine

PSY

BeitragFr, Jan 18, 2013 14:22
Antworten mit Zitat
Benutzer-Profile anzeigen
@blitzmoritz

sehr schoenes teil.
24. ordnung ist noch kein ding bei mir (5 secs), 25. dauert 9 secs und liefert falsche bilder, zb.

http://pheryllt.de/_misc/blitz...kurven.png


PSY
PSY LABS Games
Coders don't die, they just gosub without return

Ana

BeitragSa, Jan 19, 2013 8:05
Antworten mit Zitat
Benutzer-Profile anzeigen
Das ist glaube ich aber ein BMax Problem, jedenfalls hatte ich das auch bei Fotos, wenn die sehr groß sind und man sie stark verkleinert, dass sie dann rechts und unten den letzte pixelreihe ewig lang ziehen.
Don't only practice your art,
but force your way into its secrets,
for it and knowledge
can raise human to divine

PSY

BeitragSa, Jan 19, 2013 19:30
Antworten mit Zitat
Benutzer-Profile anzeigen
@Ana

Ah,

auch ne Moeglichkeit Smile

Deine Quote lautet uebrigens so im Original:

Don’t only practice your art
but force your way into its secrets
for it and knowledge
can raise men to the divine

nice weekend,
PSY
PSY LABS Games
Coders don't die, they just gosub without return

Ana

BeitragSa, Jan 19, 2013 22:56
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich weiß, aber mit Men konnte ich mich nicht so wirklich identifizieren, deshalb musste das ein wenig angepasst werden
Don't only practice your art,
but force your way into its secrets,
for it and knowledge
can raise human to divine

Ana

BeitragSo, Jan 20, 2013 8:22
Antworten mit Zitat
Benutzer-Profile anzeigen
Damit haben wir einen deutlichen Sieger =)

Herzlichen Glückwunsch

BlitzMoritz

Du hast die Ehre in 11 Tagen (1.02.13) den nächsten MiniBCC leiten zu dürfen.

Vielen Dank an alle Teilnehmenden und Bewertenden, für den interessanten MiniBCC.
Es freut mich besonders das es diesmal sogar 3 Abgaben waren, alleine macht das weniger freude, wie ich aus Erfahrung weiß Wink

In dem Sinne ein schönes Wochenende und alle Niedersachsen, wählen nicht vergessen Wink
Don't only practice your art,
but force your way into its secrets,
for it and knowledge
can raise human to divine

PSY

BeitragSo, Jan 20, 2013 19:38
Antworten mit Zitat
Benutzer-Profile anzeigen
Herzlichen Glückwunsch Blitzmoritz Smile

@Ana
jo, konnt ich mir denken hehe Smile
Aber human ist singular und men plural. Deswegen entweder a human, oder humanity/mankind/humans/mortals. Wobei humanity oder mankind am besten passt. Und vor divine muss ein Artikel (the).



l8er,
PSY
PSY LABS Games
Coders don't die, they just gosub without return

ZEVS

BeitragMo, Jan 21, 2013 19:12
Antworten mit Zitat
Benutzer-Profile anzeigen
Eine kleine Anmerkung: Als ich eben die Seite aufrief, konnte ich noch meine Stimme abgeben (obwohl der Sieger schon gekürt ist). Vielleicht sollte man dies noch ausschalten.

ZEVS

Neue Antwort erstellen


Übersicht Sonstiges Projekte

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group