Entwickler-Ecke
Andere .NET-Sprachen - VB.net MandelBrotMenge
LINUS19 - So 15.04.18 00:33
Titel: VB.net MandelBrotMenge
Hallo,
ich wollte in VB.net die MandelBrotMenge zeichnen, nur wird nichts gezeichnet. Die Formel zur Überprüfung ob der Punkt in der MandelBrotMenge liegt müsste eigentlich stimmen.
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96:
| Public Class Form1
Private formGraphics As System.Drawing.Graphics
Private Property P_Position As Point = New Point(0, 0) Private Property P_Color As Color = Color.Black
Public Sub New() ' Dieser Aufruf ist für den Designer erforderlich. InitializeComponent() ' Fügen Sie Initialisierungen nach dem InitializeComponent()-Aufruf hinzu. formGraphics = Me.CreateGraphics() End Sub
''' <summary> ''' Zeichne einen Punkt an der aktuelle Koordinate ''' </summary> ''' <param name="trans_x">X-Koordinate</param> ''' <param name="trans_y">Y-Koordinate</param> ''' <remarks></remarks>
Private Sub SU_DrawPoint(trans_x As Double, trans_y As Double, P_Color As Color) Dim P_Pen = New Pen(Color.White) P_Pen.Color = P_Color formGraphics.DrawRectangle(P_Pen, New Rectangle(P_Position, New Size(1, 1))) End Sub
Private Sub Button_Draw_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
Dim Loc_Ergebnis As Integer = 0 Dim Breite As Double Dim Hoehe As Double Dim x As Integer Dim y As Integer Dim Iterationen As Integer
For Breite = -2 To 2 Step 0.005 '' 4/800
For Hoehe = -1 To 1 Step 0.005 '' 2/400
x = (Breite + 2) * 400 y = (1 - Hoehe) * 200
Loc_Ergebnis = inMandelBrotMenge(Breite, Hoehe, Iterationen)
If (Iterationen <= 50) Then SU_DrawPoint(x, y, Color.Green) End If
If (Loc_Ergebnis = 1) Then
SU_DrawPoint(x, y, Color.Black) End If
Next Next End Sub
''' <summary> ''' ''' </summary> ''' <param name="x_pos"> x-Koordinate Punkt</param> ''' <param name="y_pos"> y-Koordinate Punkt </param> Private Function inMandelBrotMenge(x_pos As Double, y_pos As Double, ByRef Iterationen As Integer) As Integer
Dim c As Double = 0 Dim x As Double = 0 Dim y As Double = 0 Dim xn As Double Dim yn As Double
Dim i As Integer = 0
For i = 0 To 20 '' 20 Iterationen für jeden Punkt
xn = x * x - y * y + x_pos yn = 2 * x * y + y_pos c = Math.Sqrt((xn * xn + yn * yn))
x = xn y = yn
If (c > 2) Then Return 0 '' nicht in MandelBrot End If
If (c < 2) Then Return 1 '' in MandelBrot End If
Next End Function
End Class |
Delete - So 15.04.18 05:33
- Nachträglich durch die Entwickler-Ecke gelöscht -
Ralf Jansen - So 15.04.18 12:39
Den Code zum zeichnen solltest du auch in den Paint Event verschieben beziehungsweise, da du scheinbar direkt auf die Form zeichnest, die OnPaint Methode überschreiben. Windows kann deine Form zu beliebigen Zeitpunkten neu zeichnen. Dann wird OnPaint/Paint aufgerufen und nicht dein Code wodurch du einfach das Standard-Aussehen der Form gekommen würdest. Also Code verschieben. In Paint/OnPaint dann das vorhandene Graphics Object das du über die Parameter bekommst benutzen und kein neues erzeugen wie jetzt und dieses dann zum zeichnen benutzen. Dort wo du gerade zeichnest (Button_Draw_Click) solltest du nur Invalidate() aufrufen das das dann ein neuzeichnen anfordert wodurch die Paint/OnPaint Logik dann durchlaufen wird.
LINUS19 - Mo 16.04.18 16:39
Hallo,
ich habe jetzt noch ein paar Sachen verändert aber das Zeichnen funktioniert immer noch nicht und das Programm beendet sich mit:Das Programm "[10256] MandelBrotMenge.exe" wurde mit Code 0 (0x0) beendet.
Frühlingsrolle hat folgendes geschrieben : |
G
Die Variablen Hoehe und Breite haben bis dato keine Werte, auch wenn du es hier als Kommentar stehen hast.
Deine Methoden sind auf Englisch und die Variablen sind auf Deutsch. Du sollest dich für eins entscheiden
|
Was meinst du mit keine Werte? ich durchlaufe damit doch das Koordinatensystem und wandel es dann in das Fenster Koordinatensystem um. Die Variablen Namen sind gemischt, weil sie auf Englisch so vorgegebn waren.
Hier nochmal der veränderte Code: Hat noch wer einen Tipp wo noch Fehler sind?
Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95:
| Public Class Form1 Private paintThread As System.Threading.Thread Private formGraphics As System.Drawing.Graphics Private run As Boolean = True
Private Property P_Color As Color Private Property P_Pen As Pen
Public Sub New() ' Dieser Aufruf ist für den Designer erforderlich. InitializeComponent() ' Fügen Sie Initialisierungen nach dem InitializeComponent()-Aufruf hinzu. formGraphics = Me.CreateGraphics() End Sub
''' <summary> ''' Zeichne einen Punkt an der angegebenen Koordinat ''' und mit der angegebenen Farbe ''' </summary> ''' <param name="trans_x">X-Koordinate</param> ''' <param name="trans_y">Y-Koordinate</param> ''' <remarks></remarks>
Private Sub SU_DrawPointAt(trans_x As Integer, trans_y As Integer, P_Color As Color) Try Dim Loc_DrawToPoint As Point = New Point(trans_x, trans_y) P_Pen = New Pen(Color.White) P_Pen.Color = P_Color formGraphics.DrawRectangle(P_Pen, New Rectangle(Loc_DrawToPoint, New Size(1, 1))) Catch ex As Exception End Try
End Sub
Private Sub Button_Draw_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click MsgBox("Test") If paintThread Is Nothing Then paintThread = New Threading.Thread(AddressOf Draw) Try paintThread.Start() Catch ewe As Exception
End Try
End Sub ''' <summary> ''' Zeichne MandelBrotMenge ''' </summary> Private Sub Draw() If Me.InvokeRequired = True Then Me.EndInvoke(Me.BeginInvoke(New Action(AddressOf Draw))) Else Try Dim Loc_Ergebnis As Integer = 0
Dim Breite As Double Dim Hoehe As Double Dim x As Integer Dim y As Integer Dim it As Integer = 0 Dim counter As Integer = 0
For Breite = -2 To 2 Step 0.005 '' 4/400 counter += 1 x = (2 + Breite) * 200 For Hoehe = -1 To 1 Step 0.005 '' 2/200 Loc_Ergebnis = inMandelBrotMenge(Breite, Hoehe, it) y = (1 - Hoehe) * 200
If (Loc_Ergebnis = 1) Then MsgBox("Test") SU_DrawPointAt(x, y, Color.Black)
Else If it <= 50 Then SU_DrawPointAt(x, y, Color.Red) Else SU_DrawPointAt(x, y, Color.LimeGreen) End If End If
If (counter Mod 3 = 0) Then Application.DoEvents() End If
If run = False Then Exit For Next If run = False Then Exit For Next Catch ex As Exception
End Try End If
End Sub |
Ralf Jansen - Mo 16.04.18 16:58
Du solltest a.) erstmal den Thread ausbauen und schauen was dann passiert. Das ganze GDI Graphics Subsystem ist nicht threadsicher.
Eigentlich gilt das gleich fürs gesamte Winforms. Zeichnen solltest du nur im Hauptthread. Alles andere, solange es nichts mit dem Anzeigen zu tun hat, kannst du in Thread auslagern.
Ansonsten solltest du deinen Code auch debuggen. Da solltest du näher an die Stelle mit dem Problem kommen als das dein Programm nur abschmiert.
Delete - Di 17.04.18 01:25
- Nachträglich durch die Entwickler-Ecke gelöscht -
LINUS19 - Di 17.04.18 15:19
Danke, jetzt funktioniert es. Es zeichnet nur sehr langsam was wahrscheinlich auch dadran liegt das ich es nicht in einem Thread ausgelagert habe. In Java dauert es nur eine Sekunde die MandelBrot Menge mit gleich vielen Iterationen zu erstellen.
Th69 - Di 17.04.18 16:33
Hast du etwa noch Application.DoEvents() in deiner Berechnung drin? Ansonsten zeige noch mal deine Berechnungsmethode.
Und das Auslagern in einen Thread ist hier nicht nötig.
LINUS19 - Di 17.04.18 18:34
Th69 hat folgendes geschrieben : |
Hast du etwa noch Application.DoEvents() in deiner Berechnung drin? Ansonsten zeige noch mal deine Berechnungsmethode. |
Ja, Application.DoEvents() ist noch drin.
Die Berechnung ob der Punkt in der MandelBrot Menge liegt habe ich nicht verändert.
Th69 - Mi 18.04.18 08:18
Ja und, warum? Wenn du dies entfernst, sollte die Methode schnell genug (ein paar Millisekunden) durchlaufen, um das Bild zu erzeugen (dann brauchst du auch keine Abfrage auf das Beenden der Berechnung).
Und wenn du
SU_DrawPoint noch ein wenig optimierst, dann erst recht.
Benutze
VB.Net
1:
| Dim P_Pen = Pens.White; |
(s.a. mein Beitrag ("PS") in
Mehrere erstellte Images flackern teilweise [
https://www.entwickler-ecke.de/viewtopic.php?p=711938#711938] - jetzt schon ein 2. mal verlinkt ;- )
Und ist es Absicht, daß du nur ein 2-Farben Bild erzeugst (und keinen Verlauf)?
PS: Deine Methode
inMandelBrotMenge ist auch eigenartig (beachte die Schleife und die beiden
return-Anweisungen
innerhalb).
LINUS19 - Fr 20.04.18 12:14
Hallo,
Applikation doEvents hatte ich nur drin damit, sich das Fenster noch verschieben lässt. Jetzt wo ich es rausgenommen habe läuft es deutlich schneller.
Die Funktion inManfelBrot habe ich auch noch Mal überarbeitet.
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2024 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!