Hopalong - Fraktal

    • VB.NET

    Es gibt 84 Antworten in diesem Thema. Der letzte Beitrag () ist von zn-gong.

      Hopalong - Fraktal

      Also ich habe es hinbekommen, so wie ich in meinem Post #7 meinte :D

      Hier mal die ganze Projektmappe, damit das vllt einfacher zu verstehen ist :)
      Danke für die Hilfe!

      ---> Hopalong.zip <---
      »There's no need to "teach" atheism. It's the natural result of education without indoctrination.« — Ricky Gervais

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „ErfinderDesRades“ ()

      Übergib der Draw-Prozedur die entsprechende Graphics-Instanz, wo sie reinzeichnen soll.
      Wenn Du das Programm minimierst und wieder normalisierst, sieht es so aus:
      Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
      Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
      Ein guter .NET-Snippetkonverter (der ist verfügbar).
      Programmierfragen über PN / Konversation werden ignoriert!
      @RodFromGermany:
      Also sollen die PaintEventArgs des PB-Paintevents in die Draw-Sub übergeben werden?
      »There's no need to "teach" atheism. It's the natural result of education without indoctrination.« — Ricky Gervais

      ThePlexian schrieb:

      PaintEventArgs ... übergeben ... ?
      Nein.
      Mach es z.B. so:

      VB.NET-Quellcode

      1. Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
      2. Dim bmp As New Bitmap(256, 256)
      3. Dim g As Graphics = Graphics.FromImage(bmp)
      4. g.Clear(Color.White)
      5. Draw(g)
      6. ' Bitmap speichern
      7. bmp.Save("c:\Temp\xxx.png")
      8. End Sub
      9. Private Sub Form1_Paint(sender As System.Object, e As System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint
      10. Draw(e.Graphics)
      11. End Sub
      12. Private Sub Draw(g As Graphics)
      13. ' Bildinhalt darstellen
      14. g.DrawEllipse(Pens.Black, New Rectangle(10, 10, 200, 100))
      15. End Sub
      Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
      Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
      Ein guter .NET-Snippetkonverter (der ist verfügbar).
      Programmierfragen über PN / Konversation werden ignoriert!

      ThePlexian schrieb:

      Aber dann
      hast Du wohl geglaubt, ich poste Dir fertigen Code? In meinem Beispiel ging es lediglich darum, wie ein Control und eine Bitmap mit derselben Paunt-Routine befüllt werden können.
      Wann und in welchem Zusammenhang Du schrittweise malst und da ein entsprechendes Invalidate aufrufst, ist nicht Bestandteil meines Codes, das kannst Du aber alles noch hinzufügeb.
      Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
      Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
      Ein guter .NET-Snippetkonverter (der ist verfügbar).
      Programmierfragen über PN / Konversation werden ignoriert!
      @RodFromGermany:
      Nein, eigentlich nicht, ich muss ehrlich sein, ich habe jetzt auch erst den Vorteil deines Codes verstanden :s ^^

      Also ich habe jetzt zur Sub Draw den Parameter g As Graphics hinzugefügt --> Private Sub Draw(gAs Graphics)
      Im Sub steht jetzt nicht mehr graph und fractal (die Bitmap), sondern nur noch g.
      Vorher hatte ich die Me.Paint Sub und die btn.Click Sub, wo jeweils Draw aufgerufen wurde.
      Jetzt wird in jeden Draw einmal mit PaintEventArgs.Graphics und einmal mit Graphics.FromImage() --> Nur zur Übersicht, ist jetzt ja genau dasgleiche wie vorher.

      Siehe hier:
      Spoiler anzeigen

      VB.NET-Quellcode

      1. Dim drawing_enabled As Boolean = False
      2. Dim fractal As Bitmap
      3. Private Sub Main_Load(sender As Object, e As EventArgs) Handles Me.Load
      4. fractal = New Bitmap(DrawingField.Width, DrawingField.Height)
      5. End Sub
      6. Private Sub btn_Draw_Click(sender As Object, e As EventArgs) Handles btn_Draw.Click
      7. drawing_enabled = True
      8. Draw(DrawingField.CreateGraphics)
      9. Draw(Graphics.FromImage(fractal))
      10. drawing_enabled = False
      11. End Sub
      12. Private Sub Main_Paint(sender As Object, e As PaintEventArgs) Handles Me.Paint
      13. If drawing_enabled Then
      14. Draw(Graphics.FromImage(fractal))
      15. Draw(e.Graphics)
      16. End If
      17. End Sub
      18. REM ***** DRAWING *****
      19. Private Sub Draw(graph As Graphics)
      20. Dim num As Integer = Integer.Parse(tb_iter.Text.Replace(".", ","))
      21. Dim a As Double = Double.Parse(tb_a.Text.Replace(".", ","))
      22. Dim b As Double = Double.Parse(tb_b.Text.Replace(".", ","))
      23. Dim c As Double = Double.Parse(tb_c.Text.Replace(".", ","))
      24. Dim zoom As Double = ncd_zoom.Value
      25. Dim colorjump As Integer = Integer.Parse(tb_colorjump.Text)
      26. graph.Clear(Color.Black)
      27. Dim x As Double = 0
      28. Dim y As Double = 0
      29. Dim dist_hor As Double = DrawingField.Width / 2
      30. Dim dist_ver As Double = DrawingField.Height / 2
      31. Dim colorcounter As Integer = 0
      32. For i As Integer = 1 To num
      33. If colorcounter > 255 Then colorcounter = 1
      34. Dim sb As New SolidBrush(getColor(cb_load.SelectedIndex, colorcounter)) 'Funktion, um je nach Auswahl der Combobox eine Farbe ausrechnen zu können
      35. Dim ptx As Single = CSng(x * zoom + dist_hor) 'CSng(10 * x / zoom + dist_hor)
      36. Dim pty As Single = CSng(y * zoom + dist_ver) 'CSng(10 * y / zoom + dist_ver)
      37. graph.FillRectangle(sb, ptx, pty, 1, 1)
      38. DrawingField.Invalidate(New Rectangle(CInt(ptx), CInt(pty), 1, 1))
      39. Dim xx As Double = y - Math.Sign(x) * Math.Sqrt(Math.Abs(b * x - c))
      40. Dim yy As Double = a - x
      41. If Math.Abs(x - xx) < colorjump Then colorcounter += 1
      42. x = xx
      43. y = yy
      44. Next
      45. DrawingField.Image = fractal
      46. End Sub


      Scheint soweit zu funktionieren, aber:
      - Ich benutze in Zeile 4 .CreateGraphics, irgendwer wird mich dafür umbringen (Warum eig ?)
      - In Zeile 60 habe ich .Invalidate(rc As Rectangle), das sieht mir so unnötig kompliziert aus :D ?


      @faxe1008:
      Darauf Komme ich gern nochmal zurück, das will ich auch gerne einführen, nur leider habe ich keine Ahnung wie man Threads einsetzt, das muss ich mir erst noch aneignen :D


      Desweiteren habe ich nach erstmaligem Erstellen des Fraktals keine Blinker mehr in den Textboxen... :o
      »There's no need to "teach" atheism. It's the natural result of education without indoctrination.« — Ricky Gervais

      ThePlexian schrieb:

      Scheint soweit zu funktionieren
      Was soll beim Klick auf den Button btn_Draw eigentlich passieren?
      Ich sehe im Augenblick nur 2 Draw-Ziele: Das Control, wo Du im Takt invalidisierst und die Bitmap, die Du speicherst.
      Für beide ist CreateGraphics(...) nicht erforderlich.
      Invalidate(...) hat mehrere Überladungen, die z.B. dafür sorgen, dass nur die winzig kleine Stelle, die im großen Gesamtbild geändert wurde auch neu gezeichnet wird. Damit sieht der dynamische Output flüssiger aus.
      Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
      Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
      Ein guter .NET-Snippetkonverter (der ist verfügbar).
      Programmierfragen über PN / Konversation werden ignoriert!
      @RodFromGermany
      Sry ich hab momentan so ein komplettes Blackout, und finde mich jetzt nichtmal mehr in meinem eigenen Code zurecht -.- :(

      Also ich habe den Draw Sub, mit dem i.was schrittweise in eine PB gezeichnet wird.
      Damit das ganze beim Refreshen nicht verschwindet, wird nachdem zeichnen eine bitmap genutzt, getoggelt wird das über eine Flag (Globaler Bool oder ?)
      Und dann kommt da noch der Button, also soll alles erst auf ButtonClick gestartet werden.

      I'm confused, sorry oO

      Kann mir iwer wieder einen Denkansatz verpassen ?
      »There's no need to "teach" atheism. It's the natural result of education without indoctrination.« — Ricky Gervais

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „ThePlexian“ ()

      Okay ich habe den Code etwas überarbeitet, und wollte jetzt auch BGW einbauen, damit die Form halt nicht einfriert.

      Sieht so aus, funktioniert logischerweise nicht, sonst wäre ich ja nicht hier :D
      Also, wo genau ist mein Fail mit den BGWs ? (Es sind 2 Stück, da einmal auf die PB und einmal auf die Bitmap gemalt werden soll)

      Spoiler anzeigen

      VB.NET-Quellcode

      1. Private Sub Main_Load(sender As Object, e As EventArgs) Handles Me.Load
      2. fractal = New Bitmap(DrawingField.Width, DrawingField.Height)
      3. End Sub
      4. Private Sub DrawingField_Paint(sender As Object, e As PaintEventArgs) Handles DrawingField.Paint
      5. If redraw_commited Then
      6. bgw.RunWorkerAsync(e.Graphics)
      7. bgw2.RunWorkerAsync(Graphics.FromImage(fractal))
      8. Else
      9. DrawingField.Image = fractal 'Ist das notwendig ?
      10. End If
      11. End Sub
      12. Private Sub btn_Draw_Click(sender As Object, e As EventArgs) Handles btn_Draw.Click
      13. TogglePermitDrawing(True)
      14. DrawingField.Refresh()
      15. TogglePermitDrawing(False)
      16. DrawingField.Refresh()
      17. End Sub
      18. REM ***** DRAWING *****
      19. Dim redraw_commited As Boolean = False
      20. Dim fractal As Bitmap
      21. Dim WithEvents bgw As New System.ComponentModel.BackgroundWorker
      22. Dim WithEvents bgw2 As New System.ComponentModel.BackgroundWorker
      23. Private Sub DoDrawing(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles bgw.DoWork, bgw2.DoWork
      24. Dim num As Integer = Integer.Parse(tb_iter.Text.Replace(".", ","))
      25. Dim a As Double = Double.Parse(tb_a.Text.Replace(".", ","))
      26. Dim b As Double = Double.Parse(tb_b.Text.Replace(".", ","))
      27. Dim c As Double = Double.Parse(tb_c.Text.Replace(".", ","))
      28. Dim zoom As Double = ncd_zoom.Value
      29. Dim colorjump As Integer = Integer.Parse(tb_colorjump.Text)
      30. Dim graph As Graphics = CType(e.Argument, Graphics)
      31. Algorithm(graph, a, b, c, num, zoom, colorjump)
      32. End Sub
      33. Private Sub Algorithm(graph As Graphics, a As Double, b As Double, c As Double, num As Integer, zoom As Double, colorjump As Integer)
      34. graph.Clear(Color.Black)
      35. Dim x As Double = 0
      36. Dim y As Double = 0
      37. Dim dist_hor As Double = DrawingField.Width / 2
      38. Dim dist_ver As Double = DrawingField.Height / 2
      39. Dim colorcounter As Integer = 0
      40. For i As Integer = 1 To num
      41. If colorcounter > 255 Then colorcounter = 1
      42. Dim sb As New SolidBrush(getColor(cb_load.SelectedIndex, colorcounter))
      43. Dim ptx As Single = CSng(x * zoom + dist_hor)
      44. Dim pty As Single = CSng(y * zoom + dist_ver)
      45. graph.FillRectangle(sb, ptx, pty, 1, 1)
      46. Dim xx As Double = y - Math.Sign(x) * Math.Sqrt(Math.Abs(b * x - c))
      47. Dim yy As Double = a - x
      48. If Math.Abs(x - xx) < colorjump Then colorcounter += 1
      49. x = xx
      50. y = yy
      51. Next
      52. End Sub
      53. Private Sub TogglePermitDrawing(bool As Boolean)
      54. redraw_commited = bool
      55. btn_Draw.Enabled = Not bool
      56. btn_Save.Enabled = Not bool
      57. gb_parameter.Enabled = Not bool
      58. cb_load.Enabled = Not bool
      59. End Sub


      Das Problem ist, das a) das zeichnen nicht funktioniert, und b) beim Loaden die Buttons nicht geladen werden (andere Ctrls schon) ?(
      »There's no need to "teach" atheism. It's the natural result of education without indoctrination.« — Ricky Gervais
      @ThePlexian:: Schreib bitte mal dazu, was die im Designer angelegten Controls für welche sind. Bei den "tb_*" kann man das noch erahnen.
      Vielleicht ist es sinnvoll, Du lässt zunächst die Namen vom Designer stehen.
      Bei den TextBoxen ist es sinnvoll, NumericUpDowns zu verwenden, da sind die Grenzen, Schrittweiten und Werte klar, keiner kommt auf die Idee, "Roulade mit Klößen" reinzuschreiben.
      Außerdem solltest Du in der Form_Load die Controls mit sinnvollen Initialwerten belegen.
      Wofür Du 2 BGW brauchst, kann ich nicht erkennen, einer sollte reichen.
      Bereite mal den Code hier so auf, dass er Deinen Effekt reproduziert, wenn er per C&P in eine leere Form mit Controls Deiner Vorgabe eingefügt wurde.
      Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
      Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
      Ein guter .NET-Snippetkonverter (der ist verfügbar).
      Programmierfragen über PN / Konversation werden ignoriert!
      Mir fehlt die Peilung, was hier grad das Konzept sein soll.
      Beide ERstausgabe verstehe ich noch: Da läuft eine Schleife bis zB. 100000, und in jeder Runde wird ein Pixel gemalt. Und dabei kann man erfreulicherweise zugucken, aber leider freezt das Form dabei.

      Das zu entfreezen ist aufwändig, und erfordert einen ganz neuen Plan.
      Zunächstmal könnte man das hoppeln in einen Nebenthread verlegen, und mit Control.Invoke die Zeichung in den Mainthread verlegen. Ich vermute aber, das wird total langsam.
      Aber man sollte es mal ausprobieren.

      Als nächstes kann man richtig entkoppeln, also gehoppelt wird im NebenThread - aber an welchen Stellen soll die Zeichnung stattfinden? Bitte nicht bei jedem Pixel.
      Alternative wäre ein Timer im MainThread, der sich alle 100ms den aktuellen Stand abholt und darstellt.
      Dann kann der Nebenthread hoppeln, dass die Fetzen nurso fliegen - möglicherweise entsteht das Problem, dass der NebenThread nun zu schnell ist.
      Also muß man glaub tatsächlich da noch eine vom User einstellbare Bremse einbauen, mit Thread.Sleep.

      So meine Gedanken - alles unausgegoren, und um das umzusetzen ist vmtl. eine Heidenarbeit zu investieren.

      Ob sich das lohnt?
      Weil so wies ist ist doch garnet so schlecht - von dem Gefreeze mussichnich weinen.
      Okay vielen vielen Dank!

      Ich werde mich morgen darum kümmern, ich habe momentan keinen Zugriff auf meinen Code (bin nicht zuhause).

      ErfinderDesRades schrieb:

      Weil so wies ist ist doch garnet so schlecht

      Wow, erstes Lob, thank you ! ^^
      »There's no need to "teach" atheism. It's the natural result of education without indoctrination.« — Ricky Gervais
      Hört sich doch alles garnicht mal so schlecht an :)

      Ich will mir mal die Mühe machen mit den Threads, schließlich lerne ich ja nix wenn ich immer nur sage "zu schwer".

      Ich habe mir also das Rohgerüst von MSDN nachgebaut (--> hier), und den Draw Sub als AdressOf angegeben. Gestartet wird der Thread im ButtonClick-Event.

      Problem: Im Draw Sub verweise ich auf eine Funktion:

      VB.NET-Quellcode

      1. '...
      2. Dim sb As New SolidBrush(getColor(cb_load.SelectedIndex, colorcounter))
      3. '...
      4. Private Function getColor(i As Integer, cc As Integer) As Color
      5. Select Case i
      6. Case 0
      7. Return Color.FromArgb(255 - cc, cc, CInt(127 + cc / 2))
      8. Case 1
      9. Return Color.FromArgb(255 - cc, CInt(127 + cc / 2), cc)
      10. Case 2
      11. Return Color.FromArgb(cc, CInt(127 + cc / 2), 255 - cc)
      12. Case 3
      13. Return Color.FromArgb(cc, 255 - cc, CInt(127 + cc / 2))
      14. Case 4
      15. Return Color.FromArgb(CInt(127 + cc / 2), cc, 255 - cc)
      16. Case 5
      17. Return Color.FromArgb(CInt(127 + cc / 2), 255 - cc, cc)
      18. Case Else
      19. Return Color.FromArgb(255 - cc, cc, CInt(127 + cc / 2))
      20. End Select
      21. End Function

      Ist zwar nur ein kleicnes Feature, würde ich aber trotzdem gerne nutzen.
      Muss ich jetzt die Funktion in den Draw Sub einbauen, oder gibt es auch die Möglichkeit, die Funktion im selben Thread zu nutzen (Invoke ?) ?



      ErfinderDesRades schrieb:

      Alternative wäre ein Timer im MainThread, der sich alle 100ms den aktuellen Stand abholt und darstellt.
      Dann kann der Nebenthread hoppeln, dass die Fetzen nurso fliegen - möglicherweise entsteht das Problem, dass der NebenThread nun zu schnell ist.
      Also muß man glaub tatsächlich da noch eine vom User einstellbare Bremse einbauen, mit Thread.Sleep.
      Meinst du damit, das ich im Intervall von 10ms bspw. PB.Image = fractal setzen soll oder wie ?
      »There's no need to "teach" atheism. It's the natural result of education without indoctrination.« — Ricky Gervais

      ThePlexian schrieb:

      die Funktion im selben Thread zu nutzen (Invoke ?)
      Invoked werden müssen Funktionen, die Set-Properties in Controls eines anderen Threads aufrufen, solche kommen in Deinem Code nicht vor.
      Wie sieht denn der aufrufende Code aus?
      Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
      Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
      Ein guter .NET-Snippetkonverter (der ist verfügbar).
      Programmierfragen über PN / Konversation werden ignoriert!
      @RodFromGermany
      Ich weiß nicht mal ob der akzeptabel ist... :S

      VB.NET-Quellcode

      1. Dim drawingthread As New Threading.Thread(AddressOf Me.DrawFractal)
      2. Private Sub btn_Draw_Click(sender As Object, e As EventArgs) Handles btn_Draw.Click
      3. TogglePermitDrawing(True)
      4. drawingthread.Start()
      5. drawingthread.Join() 'Damit warte ich bis der Thread fertig ist oder ?
      6. TogglePermitDrawing(False)
      7. DrawingField.Refresh()
      8. End Sub
      9. REM ***** DRAWING *****
      10. Private Sub DrawFractal()
      11. Dim num As Integer = Integer.Parse(tb_iter.Text.Replace(".", ","))
      12. Dim a As Double = Double.Parse(tb_a.Text.Replace(".", ","))
      13. Dim b As Double = Double.Parse(tb_b.Text.Replace(".", ","))
      14. Dim c As Double = Double.Parse(tb_c.Text.Replace(".", ","))
      15. Dim zoom As Double = ncd_zoom.Value
      16. Dim colorjump As Integer = Integer.Parse(tb_colorjump.Text)
      17. Algorithm(a, b, c, num, zoom, colorjump) 'Das funktioniert scheinbar
      18. End Sub
      19. Private Sub Algorithm(a As Double, b As Double, c As Double, num As Integer, zoom As Double, colorjump As Integer)
      20. Dim graph As Graphics = Graphics.FromImage(fractal)
      21. graph.Clear(Color.Black)
      22. Dim x As Double = 0
      23. Dim y As Double = 0
      24. Dim dist_hor As Double = DrawingField.Width / 2
      25. Dim dist_ver As Double = DrawingField.Height / 2
      26. Dim colorcounter As Integer = 0
      27. For i As Integer = 1 To num
      28. If colorcounter > 255 Then colorcounter = 1
      29. Dim sb As New SolidBrush(getColor(cb_load.SelectedIndex, colorcounter)) 'Hier wird die Exception geworfen (siehe unten)
      30. Dim ptx As Single = CSng(x * zoom + dist_hor)
      31. Dim pty As Single = CSng(y * zoom + dist_ver)
      32. graph.FillRectangle(sb, ptx, pty, 1, 1)
      33. Dim xx As Double = y - Math.Sign(x) * Math.Sqrt(Math.Abs(b * x - c))
      34. Dim yy As Double = a - x
      35. If Math.Abs(x - xx) < colorjump Then colorcounter += 1
      36. x = xx
      37. y = yy
      38. 'DrawingField.Invalidate()
      39. Next
      40. End Sub
      41. Private Function getColor(i As Integer, cc As Integer) As Color
      42. Select Case i
      43. Case 0
      44. Return Color.FromArgb(255 - cc, cc, CInt(127 + cc / 2))
      45. Case 1
      46. Return Color.FromArgb(255 - cc, CInt(127 + cc / 2), cc)
      47. Case 2
      48. Return Color.FromArgb(cc, CInt(127 + cc / 2), 255 - cc)
      49. Case 3
      50. Return Color.FromArgb(cc, 255 - cc, CInt(127 + cc / 2))
      51. Case 4
      52. Return Color.FromArgb(CInt(127 + cc / 2), cc, 255 - cc)
      53. Case 5
      54. Return Color.FromArgb(CInt(127 + cc / 2), 255 - cc, cc)
      55. Case Else
      56. Return Color.FromArgb(255 - cc, cc, CInt(127 + cc / 2))
      57. End Select
      58. End Function


      "System.InvalidOperationException" : Zusätzliche Informationen: Ungültiger threadübergreifender Vorgang: Der Zugriff auf das Steuerelement cb_load erfolgte von einem anderen Thread als dem Thread, für den es erstellt wurde.
      »There's no need to "teach" atheism. It's the natural result of education without indoctrination.« — Ricky Gervais

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „ThePlexian“ ()

      ThePlexian schrieb:

      Ungültiger threadübergreifender Vorgang
      Das geht immer genau so:

      VB.NET-Quellcode

      1. Dim index As Integer
      2. Me.Invoke(Sub() index = cb_load.SelectedIndex)
      Überleg mal, die Parameter nicht über TextBoxen, sondern über NumericUpDowns zu setzen.
      Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
      Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
      Ein guter .NET-Snippetkonverter (der ist verfügbar).
      Programmierfragen über PN / Konversation werden ignoriert!
      @RodFromGermany , @ErfinderDesRades:
      So, ich habe jetzt die TBs zu NUDs geändert, und ein / zwei Layout Änderungen vorgenommen, aber es gibt trotzdem noch Probleme ;(

      Mein bisheriger Code sieht so aus, und das Problem ist, das sobald ich auf den Button klicke, die Form freezt und nichts mehr passiert (Ich vermute das liegt an dem Join oder ? :

      Spoiler anzeigen

      VB.NET-Quellcode

      1. Public Class Hopalong
      2. Dim redraw_commited As Boolean = False
      3. Dim fractal As Bitmap
      4. Private Sub Main_Load(sender As Object, e As EventArgs) Handles Me.Load
      5. cb_load.SelectedIndex = 0
      6. fractal = New Bitmap(DrawingField.Width, DrawingField.Height)
      7. Graphics.FromImage(fractal).Clear(Color.FromKnownColor(KnownColor.Control))
      8. End Sub
      9. Private Sub DrawingField_Paint(sender As Object, e As PaintEventArgs) Handles DrawingField.Paint
      10. End Sub
      11. Dim drawingthread As New Threading.Thread(AddressOf Me.DrawFractal) With {.IsBackground = True} 'Das ist auch neu
      12. Private Sub btn_Draw_Click(sender As Object, e As EventArgs) Handles btn_Draw.Click
      13. TogglePermitDrawing(True)
      14. drawingthread.Start()
      15. drawingthread.Join()
      16. TogglePermitDrawing(False)
      17. DrawingField.Refresh()
      18. End Sub
      19. REM ***** DRAWING *****
      20. Private Sub DrawFractal()
      21. Dim num As Integer = Integer.Parse(nud_iter.Text)
      22. Dim a As Double = Double.Parse(nud_a.Text)
      23. Dim b As Double = Double.Parse(nud_b.Text)
      24. Dim c As Double = Double.Parse(nud_c.Text)
      25. Dim zoom As Double = nud_zoom.Value
      26. Dim colorjump As Integer = Integer.Parse(nud_colorjump.Text)
      27. Dim colorformula As Integer
      28. Me.Invoke(Sub() colorformula = cb_load.SelectedIndex) 'Ich verstehe nicht warum ich nur das Invoken muss ?(
      29. Algorithm(a, b, c, num, zoom, colorjump, colorformula)
      30. End Sub
      31. Private Sub Algorithm(a As Double, b As Double, c As Double, num As Integer, zoom As Double, colorjump As Integer, colorformula As Integer)
      32. Dim graph As Graphics = Graphics.FromImage(fractal)
      33. graph.Clear(Color.Black)
      34. Dim x As Double = 0
      35. Dim y As Double = 0
      36. Dim dist_hor As Double = DrawingField.Width / 2
      37. Dim dist_ver As Double = DrawingField.Height / 2
      38. Dim colorcounter As Integer = 0
      39. For i As Integer = 1 To num
      40. If colorcounter > 255 Then colorcounter = 1
      41. Dim sb As New SolidBrush(getColor(colorformula, colorcounter))
      42. Dim ptx As Single = CSng(x * zoom + dist_hor)
      43. Dim pty As Single = CSng(y * zoom + dist_ver)
      44. graph.FillRectangle(sb, ptx, pty, 1, 1)
      45. Dim xx As Double = y - Math.Sign(x) * Math.Sqrt(Math.Abs(b * x - c))
      46. Dim yy As Double = a - x
      47. If Math.Abs(x - xx) < colorjump Then colorcounter += 1
      48. x = xx
      49. y = yy
      50. 'DrawingField.Invalidate()
      51. Next
      52. End Sub
      53. Private Function getColor(i As Integer, cc As Integer) As Color
      54. Select Case i
      55. Case 0
      56. Return Color.FromArgb(255 - cc, cc, CInt(127 + cc / 2))
      57. Case 1
      58. Return Color.FromArgb(255 - cc, CInt(127 + cc / 2), cc)
      59. Case 2
      60. Return Color.FromArgb(cc, CInt(127 + cc / 2), 255 - cc)
      61. Case 3
      62. Return Color.FromArgb(cc, 255 - cc, CInt(127 + cc / 2))
      63. Case 4
      64. Return Color.FromArgb(CInt(127 + cc / 2), cc, 255 - cc)
      65. Case 5
      66. Return Color.FromArgb(CInt(127 + cc / 2), 255 - cc, cc)
      67. Case Else
      68. Return Color.FromArgb(255 - cc, cc, CInt(127 + cc / 2))
      69. End Select
      70. End Function
      71. REM Events
      72. Private Sub TogglePermitDrawing(bool As Boolean)
      73. redraw_commited = bool
      74. btn_Draw.Enabled = Not bool
      75. btn_Save.Enabled = Not bool
      76. gb_parameter.Enabled = Not bool
      77. gb_layout.Enabled = Not bool
      78. cb_load.Enabled = Not bool
      79. End Sub
      80. Private Sub cb_load_SelectedIndexChanged(sender As Object, e As EventArgs) Handles cb_load.SelectedIndexChanged
      81. cb_load.Refresh()
      82. fractal = New Bitmap(DrawingField.Width, DrawingField.Height)
      83. Graphics.FromImage(fractal).Clear(Color.Black)
      84. End Sub
      85. End Class
      »There's no need to "teach" atheism. It's the natural result of education without indoctrination.« — Ricky Gervais