[GELÖST] Bilder im Kreis anordnen?

Übersicht BlitzMax, BlitzMax NG Allgemein

Neue Antwort erstellen

 

CO2

ehemals "SirMO"

Betreff: [GELÖST] Bilder im Kreis anordnen?

BeitragFr, Sep 27, 2013 22:12
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo,
Ich habe ein Problem: Für ein Projekt habe ich mir Funktionen erstellt, die mir automatisch aus einem übergebenen Bild (Als Blatt-Modell) einen Baum generieren. Das ganze funktioniert auch schon recht gut - solange der Baum Rechteckig sein soll. Jetzt möchte ich aber auch Bäume erstellen, die rund sind und stehe deshalb gerade etwas auf dem Schlauch.
Hier mal der bisher erstellte Code BlitzMax:
Rem
Autor: Marius Otto
Datum: 27.09.2013
Version: 1.0
End Rem


Private
Function CopyPix:Int(Src:TPixmap, Dest:TPixmap, StartX:Int, StartY:Int, InvisibleARGB:Int = $FF000000)
If(Src <> Null And Dest <> Null)
For Local y:Int = 0 To (PixmapHeight(Src) - 1)
For Local x:Int = 0 To (PixmapWidth(Src) - 1)
If(((StartX + x) < PixmapWidth(Dest)) And ((StartY + y) < PixmapHeight(Dest)))
If(ReadPixel(Src, x, y) <> InvisibleARGB)
WritePixel(Dest, (StartX + x), (StartY + y), ReadPixel(Src, x, y))
EndIf
EndIf
Next
Next
Return 1
Else
Return 0
EndIf
End Function

Public
Const TREESHAPE_ROUND:Int = 0
Const TREESHAPE_RECT:Int = 1

Function CreateTree2D:TImage(LeafModel:TImage, SizeX:Int, SizeY:Int, Pot:Int = 0, Disorder:Int = 0, Shape:Int = TREESHAPE_RECT)
If((Shape = 0 Or Shape = 1) And (LeafModel <> Null) And SizeX > 0 And SizeY > 0 And Pot >= 0 And Disorder >= 0)
Local ReturnMe:TImage = CreateImage(SizeX, SizeY)
If(ReturnMe = Null)
Return Null
EndIf

Local ReturnMePix:TPixmap = LockImage(ReturnMe)
Local LeafModelPix:TPixmap = LockImage(LeafModel)

Local Fac:Float = 1 / (2 ^ Pot)
Local RandX:Int
Local RandY:Int

If(Shape = TREESHAPE_ROUND)
Rem
Wie geht es hier weiter?
End Rem

ElseIf(Shape = TREESHAPE_RECT)
For Local y:Int = 0 To ((PixmapHeight(ReturnMePix) - 1) / (PixmapHeight(LeafModelPix) * Fac))
For Local x:Int = 0 To ((PixmapWidth(ReturnMePix) - 1) / (PixmapWidth(LeafModelPix) * Fac))
RandX = Rand(0, Disorder)
RandY = Rand(0, Disorder)
If(((x * Fac * PixmapWidth(LeafModelPix)) + RandX) < PixmapWidth(ReturnMePix) And ((y * Fac * PixmapHeight(LeafModelPix)) + RandY) < PixmapHeight(ReturnMePix))
CopyPix(LeafModelPix, ReturnMePix, ((x * Fac * PixmapWidth(LeafModelPix)) + RandX), ((y * Fac * PixmapHeight(LeafModelPix)) + RandY))
EndIf
Next
Next
EndIf

UnlockImage(LeafModel)
UnlockImage(ReturnMe)

Return ReturnMe
Else
Return Null
EndIf
End Function

Rem
__COMMENT1__
Graphics(800, 600, 32, 60)

SetMaskColor(255, 0, 255)

Local Leaf:TImage = LoadImage("leaf011.bmp", MASKEDIMAGE)

Local Tree01:TImage = CreateTree2D(Leaf, (15 * ImageWidth(Leaf)), (15 * ImageHeight(Leaf)), 0, 5)
Local Tree03:TImage = CreateTree2D(Leaf, (15 * ImageWidth(Leaf)), (15 * ImageHeight(Leaf)), 1, 5)
Local Tree04:TImage = CreateTree2D(Leaf, (15 * ImageWidth(Leaf)), (15 * ImageHeight(Leaf)), 2)

Local Timer:TTimer = CreateTimer(60)
Repeat
WaitTimer(Timer)
Cls

DrawImage(Tree01, 0, 0)
DrawImage(Tree03, (15 * ImageWidth(Leaf)), 0)
DrawImage(Tree04, 0, (15 * ImageWidth(Leaf)))

Flip 0
Until KeyHit(KEY_ESCAPE)
End
End Rem



Wer es mal ausprobieren möchte: Hier ein Beispiel-Blatt-Modell: https://www.blitzforum.de/upload/file.php?id=12579

Hier auch mal einige Resultate:
Pot = 0, Disorder = 5
user posted image

Pot = 1, Disorder = 5
user posted image

Pot = 2, Disorder = 2
user posted image

(Blattmodell s.o.)

Zur Funktionsweise:
1.) CopyPix:Int(Src:TPixmap, Dest:TPixmap, StartX:Int, StartY:Int, InvisibleARGB:Int = $FF000000)
Diese Funktion Kopiert mir die Dest-Pixmap in die Src-Pixmap und zwar an die Stelle (In der Dest-Pixmap) StartX bzw. StartY.
2.) CreateTree2D:TImage(LeafModel:TImage, SizeX:Int, SizeY:Int, Pot:Int = 0, Disorder:Int = 0, Shape:Int = TREESHAPE_RECT)
Diese Funktion erstellt ein TImage eines Baumes, welcher aus den übergebenen Parametern generiert wird. Dabei bezwecken die Parameter folgendes:
- LeafModel: Das Modell eines Blattes
- SizeX u. SizeY: Die Größe des Resultates in Pixeln
- Pot: 1 / (2 ^ Pot) = Häufigkeit der Blätter im gesamten (1 erzeugt ein Blatt auf der Fläche eines Blattmodells)
- Disorder: Mögliche maximale Versetzung pro Blatt innerhalb des Resultat-Images (0 führt zu "tabellarischer" Anordnung der Blätter)
- Shape: Erzeugt entweder einen Runden Baum oder einen Eckigen

Das Problem ist folgendes: Ich muss ja in die Berechnung mit einfließen lassen, welche Ausmaße das Resultat haben muss (Also der Algorithmus muss auch in der Lage sein Ovale erzeugen zu können), wie groß die maximale Versetzung ist und ich muss das erzeugte Oval bzw. den erzeugten Kreis mit Blättern füllen.
Wie stelle ich das an?
mfG, CO²

Sprachen: BlitzMax, C, C++, C#, Java
Hardware: Windows 7 Ultimate 64-Bit, AMX FX-6350 (6x3,9 GHz), 32 GB RAM, Nvidia GeForce GTX 750 Ti
  • Zuletzt bearbeitet von CO2 am Mo, Sep 30, 2013 14:50, insgesamt einmal bearbeitet

Xeres

Moderator

BeitragFr, Sep 27, 2013 23:28
Antworten mit Zitat
Benutzer-Profile anzeigen
BlitzMax:
RandX = Rand(0, Disorder)
RandY = Rand(0, Disorder)

Klar muss das Rechteckig werden - die Koordinaten werden schließlich aus einem solchen Bereich ausgewählt. Was du für ein Kreis/Oval machen willst, ist einen zufälligen Winkel zu nehmen und die Koordinaten entlang des Bildmittelpunkts zu verschieben:
BlitzMax:
RandW = Rand(0,359)
RandX = MX + Rand(0, Disorder) * Sin(RandW)
RandY = MY + Rand(0, Disorder) * Cos(RandW)
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)

Midimaster

BeitragSa, Sep 28, 2013 10:31
Antworten mit Zitat
Benutzer-Profile anzeigen
gleich noch ein Tipp:

1.
Arbeite nicht mit einem einzigen Kreis.
2.
Legen für Deinen Baum 4 Kreiszentren und Radien fest.
3.
Entscheide dann pro Blatt per Zufall für jeweils einen der Kreise und male das Blatt dort wie Xeress vorschlägt.
4.
Wenn es möglich ist in deinem System: Beginne bei den ersten Blättern zunächst mit dunklerem Grün und steigere dann die Farben ins Hellere. Das gibt Tiefe!

BlitzMax:
SuperStrict
Graphics 800,600

Type Zentrum
Field X%,Y%,R%
End Type

Global Radius:Zentrum[4]

SetRadius 1,30,80,30
SetRadius 2,80,80,40
SetRadius 3,60,45,40

BaumMalen
WaitKey()
End


Function SetRadius(i%,X%,Y%,R%)
Radius[i]=New Zentrum
Radius[i].X=X
Radius[i].Y=Y
Radius[i].R=R
End Function




Function BaumMalen()
SetColor 125,55,0
DrawRect 50,40,20,100
For Local j%=0 To 2000
SetColor (j-1000)/7,j/7,0
BlattMalen
Next
Flip
End Function


Function BlattMalen()
Local i%=Rand(1,3)
Local dist#=Rnd(Radius[i].R)
Local w#=Rnd(0,359)
Local x#=Sin(w)*dist
Local y#=Cos(w)*dist
DrawOval Radius[i].X+x,Radius[i].Y+y,3,5
End Function
Gewinner des BCC #53 mit "Gitarrist vs Fussballer" http://www.midimaster.de/downl...ssball.exe
 

CO2

ehemals "SirMO"

BeitragSo, Sep 29, 2013 12:18
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich habe mal ein wenig rumprobiert, die Bäume bleiben allerdings Rechteckig... Hier mal mein momentaner Code (Ausschnitt) BlitzMax:
If(Shape = TREESHAPE_ROUND)
For y = 0 To ((PixmapHeight(ReturnMePix) - 1) / (PixmapHeight(LeafModelPix) * Fac))
For x = 0 To ((PixmapWidth(ReturnMePix) - 1) / (PixmapWidth(LeafModelPix) * Fac))
Angle = Rand(0, 359)
RandX = (PixmapWidth(ReturnMePix) / 2) + Rand(0, Disorder) * Sin(Angle)
RandY = (PixmapHeight(ReturnMePix) / 2) + Rand(0, Disorder) * Cos(Angle)

CopyPix(LeafModelPix, ReturnMePix, ((x * Fac * PixmapWidth(LeafModelPix)) + RandX), ((y * Fac * PixmapHeight(LeafModelPix)) + RandY), InvisibleARGB)
Next
Next
'[...]
EndIf


Was mache ich falsch?
mfG, CO²

Sprachen: BlitzMax, C, C++, C#, Java
Hardware: Windows 7 Ultimate 64-Bit, AMX FX-6350 (6x3,9 GHz), 32 GB RAM, Nvidia GeForce GTX 750 Ti

Xeres

Moderator

BeitragSo, Sep 29, 2013 12:37
Antworten mit Zitat
Benutzer-Profile anzeigen
Das Problem ist, dass du x und y beim kopieren einmultiplizierst, als wolltest du die Blätter auf einem Gitter verteilen, von dessen Punkten du eben nur eine kleine Abweichung berechnen wolltest.
BlitzMax:
CopyPix (LeafModelPix, ReturnMePix, ..
((x * Fac * PixmapWidth(LeafModelPix)) + RandX), ..
((y * Fac * PixmapHeight(LeafModelPix)) + RandY), ..
InvisibleARGB)


Stattdessen sollten RandX/RandY schon die endgültigen Koordinaten enthalten. Ich sehe durch deine Pot/Fac Berechnung da nicht durch, aber mit genügend großem Disorder geht das schon:
BlitzMax:
CopyPix (LeafModelPix, ReturnMePix, ..
((Fac * PixmapWidth(LeafModelPix)) + RandX), ..
((Fac * PixmapHeight(LeafModelPix)) + RandY), ..
InvisibleARGB)
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)
 

CO2

ehemals "SirMO"

BeitragSo, Sep 29, 2013 19:40
Antworten mit Zitat
Benutzer-Profile anzeigen
Trotz hin und her probieren wollen die Bäume einfach nicht rund werden... Was mache ich den falsch? Gibt es noch andere Methoden Kreise zu erzeugen? Ich brauche ja im Grunde nur einen gefüllten Kreis als Resultat. Hier mal der Code-Ausschnitt, wie er momentan aussieht BlitzMax:
'[...]
For y = 0 To ((PixmapHeight(ReturnMePix) - 1) / (PixmapHeight(LeafModelPix) * Fac))
For x = 0 To ((PixmapWidth(ReturnMePix) - 1) / (PixmapWidth(LeafModelPix) * Fac))
Angle = Rand(0, 359)
RandX = (PixmapWidth(ReturnMePix) / 2) + Rand(0, Disorder) * Sin(Angle)
RandY = (PixmapHeight(ReturnMePix) / 2) + Rand(0, Disorder) * Cos(Angle)
CopyPix(LeafModelPix, ReturnMePix, ((Fac * PixmapWidth(LeafModelPix)) + RandX), ((Fac * PixmapHeight(LeafModelPix)) + RandY))
Next
Next
'[...]
mfG, CO²

Sprachen: BlitzMax, C, C++, C#, Java
Hardware: Windows 7 Ultimate 64-Bit, AMX FX-6350 (6x3,9 GHz), 32 GB RAM, Nvidia GeForce GTX 750 Ti

Xeres

Moderator

BeitragSo, Sep 29, 2013 20:25
Antworten mit Zitat
Benutzer-Profile anzeigen
Der Code erzeugt runde Blätteransammlungen. Nur ist der Parameter Disorder eben kein maß für Unordnung, sondern der maximale Radius eines Kreises. Vielleicht solltest du den anders in die Rechnung einfließen lassen und den Radius auf die Bildbreite/Höhe setzen?
Du müsstest halt definieren, was die Eingabe und die Ausgabe sein soll.
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)
 

CO2

ehemals "SirMO"

BeitragSo, Sep 29, 2013 21:54
Antworten mit Zitat
Benutzer-Profile anzeigen
Gut, habe nun wieder ein wenig rumexperimentiert und ein annehmbares Ergebnis erhalten.

@ Midimaster: Zu 1 - 3: Das ist eine gute Idee, werde es auch versuchen umzusetzen, nur in der momentanen Version reicht mir das Ein-Kreis-System Wink
Zu deinem 4. Punkt: Vor allem beim Rechteckigen Baum ist das etwas kompliziert, da ich diesen nicht "von innen nach außen" aufbaue, sondern eher Reihe für Reihe. Wenn ich dann von Hell nach Dunkel gehe sieht das bescheiden aus...

Nun, wer es braucht, hier der Code BlitzMax:
Rem
Autor: Marius Otto
Datum: 29.09.2013
Version: 1.0
End Rem


Private
SeedRnd(MilliSecs())

Function CopyPix:Int(Src:TPixmap, Dest:TPixmap, StartX:Int, StartY:Int, InvisibleARGB:Int = $FF000000)
If(Src <> Null And Dest <> Null)
For Local y:Int = 0 To (PixmapHeight(Src) - 1)
For Local x:Int = 0 To (PixmapWidth(Src) - 1)
If(((StartX + x) < PixmapWidth(Dest)) And ((StartY + y) < PixmapHeight(Dest)) And (StartX + PixmapWidth(Src)) < PixmapWidth(Dest) And (StartY + PixmapHeight(Src) < PixmapHeight(Dest)))
If(ReadPixel(Src, x, y) <> InvisibleARGB)
WritePixel(Dest, (StartX + x), (StartY + y), ReadPixel(Src, x, y))
EndIf
EndIf
Next
Next

Return 1
Else
Return 0
EndIf
End Function

Public
Const TREESHAPE_ROUND:Int = 0
Const TREESHAPE_RECT:Int = 1

Function CreateTree2D:TImage(LeafModel:TImage, SizeX:Int, SizeY:Int, Pot:Int = 0, Disorder:Int = 0, Shape:Int = TREESHAPE_RECT, InvisibleARGB:Int = $FF000000)
If((Shape = 0 Or Shape = 1) And (LeafModel <> Null) And SizeX > 0 And SizeY > 0 And Pot >= 0 And Disorder >= 0)
Local ReturnMe:TImage = CreateImage(SizeX, SizeY)
If(ReturnMe = Null)
Return Null
EndIf

Local ReturnMePix:TPixmap = LockImage(ReturnMe)
Local LeafModelPix:TPixmap = LockImage(LeafModel)

Local Fac:Float = 1 / (2 ^ Pot)
Local RandX:Float
Local RandY:Float
Local Operation:Int = 0
Local y:Int
Local x:Int

If(Shape = TREESHAPE_ROUND)
For y = 0 To ((PixmapHeight(ReturnMePix) - 1) / (PixmapHeight(LeafModelPix) * Fac))
For x = 0 To ((PixmapWidth(ReturnMePix) - 1) / (PixmapWidth(LeafModelPix) * Fac))
Angle = Rand(0, 359)
RandX = Disorder + (PixmapWidth(ReturnMePix) * (Fac / 2)) + Rand(0, (PixmapWidth(ReturnMePix) / 2)) * Sin(Angle)
RandY = Disorder + (PixmapHeight(ReturnMePix) * (Fac / 2)) + Rand(0, (PixmapHeight(ReturnMePix) / 2)) * Cos(Angle)

If(((Fac * PixmapWidth(LeafModelPix)) + RandX) < PixmapWidth(ReturnMePix) And ((Fac * PixmapWidth(LeafModelPix)) + RandX) > 0 And ((Fac * PixmapHeight(LeafModelPix)) + RandY) < PixmapHeight(ReturnMePix) And ((Fac * PixmapHeight(LeafModelPix)) + RandY) > 0)
CopyPix(LeafModelPix, ReturnMePix, ((Fac * PixmapWidth(LeafModelPix)) + RandX), ((Fac * PixmapHeight(LeafModelPix)) + RandY), InvisibleARGB)
EndIf
Next
Next
ElseIf(Shape = TREESHAPE_RECT)
For y = 0 To ((PixmapHeight(ReturnMePix) - 1) / (PixmapHeight(LeafModelPix) * Fac))
For x = 0 To ((PixmapWidth(ReturnMePix) - 1) / (PixmapWidth(LeafModelPix) * Fac))
RandX = Rand(0, Disorder)
RandY = Rand(0, Disorder)
Operation = Rand(0, 1)

If(Operation = 0) ' Addidition
If(((x * Fac * PixmapWidth(LeafModelPix)) + RandX) < PixmapWidth(ReturnMePix) And ((y * Fac * PixmapHeight(LeafModelPix)) + RandY) < PixmapHeight(ReturnMePix))
CopyPix(LeafModelPix, ReturnMePix, ((x * Fac * PixmapWidth(LeafModelPix)) + RandX), ((y * Fac * PixmapHeight(LeafModelPix)) + RandY), InvisibleARGB)
EndIf
Else
If(((x * Fac * PixmapWidth(LeafModelPix)) - RandX) >= 0 And ((y * Fac * PixmapHeight(LeafModelPix)) - RandY) >= 0)
CopyPix(LeafModelPix, ReturnMePix, ((x * Fac * PixmapWidth(LeafModelPix)) - RandX), ((y * Fac * PixmapHeight(LeafModelPix)) - RandY), InvisibleARGB)
EndIf
EndIf
Next
Next
EndIf

UnlockImage(LeafModel)
UnlockImage(ReturnMe)

Return ReturnMe
Else
Return Null
EndIf
End Function


Und nun ein paar Statistiken:

1.) SizeX: 100; SizeY: 100; Disorder: 0; Pot: 0; Shape: RECT; Zeit in ms: 10
2.) SizeX: 100; SizeY: 100; Disorder: 0; Pot: 0; Shape: ROUND; Zeit in ms: 9
3.) SizeX: 100; SizeY: 100; Disorder: 1; Pot: 1; Shape: RECT; Zeit in ms: 37
4.) SizeX: 100; SizeY: 100; Disorder: 1; Pot: 1; Shape: ROUND; Zeit in ms: 78
5.) SizeX: 100; SizeY: 100; Disorder: 5; Pot: 1; Shape: RECT; Zeit in ms: 233
6.) SizeX: 100; SizeY: 100; Disorder: 1; Pot: 1; Shape: ROUND; Zeit in ms: 89

Ich danke Allen, die halfen und werde das Thema damit als [GELÖST] markieren.
mfG, CO²

Sprachen: BlitzMax, C, C++, C#, Java
Hardware: Windows 7 Ultimate 64-Bit, AMX FX-6350 (6x3,9 GHz), 32 GB RAM, Nvidia GeForce GTX 750 Ti

BladeRunner

Moderator

BeitragMo, Sep 30, 2013 5:44
Antworten mit Zitat
Benutzer-Profile anzeigen
Warum die Funktion Copypix? Ein einfaches Drawimage sollte es doch auch tun (und wesentlich schneller sein)?
Zu Diensten, Bürger.
Intel T2300, 2.5GB DDR 533, Mobility Radeon X1600 Win XP Home SP3
Intel T8400, 4GB DDR3, Nvidia GF9700M GTS Win 7/64
B3D BMax MaxGUI

Stolzer Gewinner des BAC#48, #52 & #92
 

CO2

ehemals "SirMO"

BeitragMo, Sep 30, 2013 14:52
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich arbeite ja nachdem ich einen Baum generiert habe weiter mit DrawImage(Resultat). Also die Bäume brauchen nur beim initialisieren so "lange", das DrawImage des generierten Baumes ist ja recht schnell...
mfG, CO²

Sprachen: BlitzMax, C, C++, C#, Java
Hardware: Windows 7 Ultimate 64-Bit, AMX FX-6350 (6x3,9 GHz), 32 GB RAM, Nvidia GeForce GTX 750 Ti

BladeRunner

Moderator

BeitragMo, Sep 30, 2013 16:17
Antworten mit Zitat
Benutzer-Profile anzeigen
Schon klar,
dennoch ist es doppelt gemoppelt. Du kannst die Leaves ja per drawimage einzeichnen und dann grabben, das spart dir die langsame fUnktion ein.
Zu Diensten, Bürger.
Intel T2300, 2.5GB DDR 533, Mobility Radeon X1600 Win XP Home SP3
Intel T8400, 4GB DDR3, Nvidia GF9700M GTS Win 7/64
B3D BMax MaxGUI

Stolzer Gewinner des BAC#48, #52 & #92
 

CO2

ehemals "SirMO"

BeitragDi, Okt 01, 2013 20:11
Antworten mit Zitat
Benutzer-Profile anzeigen
Ok, dann werd ich mal ein wenig rumexperimentieren Wink Danke für den Vorschlag
mfG, CO²

Sprachen: BlitzMax, C, C++, C#, Java
Hardware: Windows 7 Ultimate 64-Bit, AMX FX-6350 (6x3,9 GHz), 32 GB RAM, Nvidia GeForce GTX 750 Ti

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Allgemein

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group