Graphen von quadratische Funktionen in VB 2008/2010

  • VB.NET

Es gibt 17 Antworten in diesem Thema. Der letzte Beitrag () ist von RodFromGermany.

    Graphen von quadratische Funktionen in VB 2008/2010

    Hallo liebe Community,


    ich sitze schon seit ner gewissen Zeit am Code. Und zwar möchte ich eine quadratische Funktion grafisch mit einer PictureBox darstellen. Das Programm soll quadratische Funktionen und Gleichungen lösen. Bisher schaut's so aus, ohne dem grafischen Teil (da komm ich überhaupt nicht weiter):


    VB.NET-Quellcode

    1. Imports System.Math
    2. Public Class Form1
    3. Dim a As Double
    4. Dim b As Double
    5. Dim c As Double
    6. Private Sub Button4_Click(ByVal
    7. sender As System.Object,
    8. ByVal e As
    9. System.EventArgs) Handles
    10. Button4.Click
    11. Try
    12. If
    13. TextBox1.Text = "" Then
    14. TextBox1.Text = 1
    15. End
    16. If
    17. If
    18. TextBox1.Text = "0" Then
    19. MsgBox("a darf
    20. nicht 0 sein!", MsgBoxStyle.Critical,
    21. "Fehler bei der Eingabe")
    22. If
    23. TextBox1.CanUndo Then
    24. TextBox1.Undo()
    25. Else
    26. TextBox1.Text = 1
    27. End
    28. If
    29. End
    30. If
    31. If
    32. TextBox2.Text = "" Then
    33. TextBox2.Text = 0
    34. End
    35. If
    36. If
    37. TextBox3.Text = "" Then
    38. TextBox3.Text = 0
    39. End
    40. If
    41. checkindex()
    42. Try
    43. Dim
    44. x1 As Double =
    45. (((-(b)) + (Sqrt((b ^ 2) - (4 * a * c)))) / (2 * a))
    46. Dim
    47. x2 As Double =
    48. (((-(b)) - (Sqrt((b ^ 2) - (4 * a * c)))) / (2 * a))
    49. If
    50. a < 0 Then
    51. If
    52. x1 = x2 Then
    53. TextBox5.Text = "X = " & x1 & vbCrLf &
    54. vbCrLf & "X1 + X2 = " & x1
    55. + x2 & vbCrLf & "X1 * X2 = "
    56. & x1 * x2
    57. Else
    58. TextBox5.Text = "X1 = " & x2 & vbCrLf & "X2 = " & x1 & vbCrLf &
    59. vbCrLf & "X1 + X2 = " & x1
    60. + x2 & vbCrLf & "X1 * X2 = "
    61. & x1 * x2
    62. End
    63. If
    64. ElseIf
    65. a > 0 Then
    66. If x1 = x2 Then
    67. TextBox5.Text = "X = " & x1 & vbCrLf &
    68. vbCrLf & "X1 + X2 = " & x1
    69. + x2 & vbCrLf & "X1 * X2 = "
    70. & x1 * x2
    71. Else
    72. TextBox5.Text = "X1 = " & x1 & vbCrLf & "X2 = " & x2 & vbCrLf &
    73. vbCrLf & "X1 + X2 = " & x1
    74. + x2 & vbCrLf & "X1 * X2 = "
    75. & x1 * x2
    76. End
    77. If
    78. End
    79. If
    80. Catch
    81. ex As Exception
    82. End
    83. Try
    84. Catch
    85. ex As Exception
    86. MsgBox(ex.Message, MsgBoxStyle.Critical, "Syntaxfehler!")
    87. End Try
    88. End Sub
    89. Sub
    90. checkindex()
    91. If
    92. TextBox1.Text.Contains("/") Then
    93. Dim
    94. a1 As String =
    95. TextBox1.Text.Split("/")(0)
    96. Dim
    97. a2 As String =
    98. TextBox1.Text.Split("/")(1)
    99. Double.Parse(a1)
    100. Double.Parse(a2)
    101. a = a1 / a2
    102. Else
    103. a = Double.Parse(TextBox1.Text)
    104. End If
    105. If
    106. TextBox2.Text.Contains("/") Then
    107. Dim
    108. b1 As String =
    109. TextBox2.Text.Split("/")(0)
    110. Dim
    111. b2 As String =
    112. TextBox2.Text.Split("/")(1)
    113. Double.Parse(b1)
    114. Double.Parse(b2)
    115. b = b1 / b2
    116. Else
    117. b = Double.Parse(TextBox2.Text)
    118. End If
    119. If
    120. TextBox3.Text.Contains("/") Then
    121. Dim
    122. c1 As String =
    123. TextBox3.Text.Split("/")(0)
    124. Dim
    125. c2 As String =
    126. TextBox3.Text.Split("/")(1)
    127. Double.Parse(c1)
    128. Double.Parse(c2)
    129. c = c1 / c2
    130. Else
    131. c = Double.Parse(TextBox3.Text)
    132. End If
    133. End Sub


    Der Teil ist ja nur für die Lösung der quadratischen Gleichung (x1 und x2)

    Nun bin ich im Internet auf folgendes gestoßen:

    vbtutor.net/VB_Sample/QGraphplotter.htm


    Und da gab's den Code:

    VB.NET-Quellcode

    1. Private Sub cmd_draw_Click()
    2. Dim a, b, c As Integer
    3. Dim w, v As Single
    4. a = Val(txt_a.Text)
    5. b = Val(txt_b.Text)
    6. c = Val(txt_c.Text)
    7. 'Using a scale of 0.5 cm to represent i unit to draw the graph
    8. ' Need to make some transformation as the coordinates in VB start from top left
    9. For w = 0 To 10 Step 0.001
    10. v = a * (5 - w) ^ 2 - b * (5 - w) + c
    11. pic_graph.PSet (w, 5 - v)
    12. Next w
    13. End Sub
    14. Private Sub Command1_Click()
    15. pic_graph.Cls
    16. txt_a.Text = ""
    17. txt_b.Text = ""
    18. txt_c.Text = ""
    19. End Sub





    Leider wurde dieser aber in VB6 geschrieben. Mit VB6 kann ich rein gar nix anfangen. Meine Frage wäre also jetzt, wie kann ich das in VB 2010 umwandeln bzw. gibt es eine bessere Möglichkeit, den Funktionsgraphen grafisch darzustellen?

    Ich bedanke mich ganz herzlich im Voraus, hoffentlich könnt Ihr mir weiterhelfen :thumbsup:


    Liebe Grüße,


    Kesselwagen
    8| ?( ich versteh nicht mal Bahnhof. Mehr wollte ich ja auch nicht, außer einen ganz einfachen Graphen ohne Beschriftung etc. Also x-Achse, y-Achse und den Graphen. Da versteh ich ja weniger als den VB6-Code oben...


    Vielleicht bin ich unfähig für sowas... :( *kopf hau*

    Aber trotzdem vielen Dank und einen schönen Abend!
    Hi
    nachdem's in VB.Net sein soll: Schau' dir mal
    - die System.Drawing.Graphics-Klasse
    - das System.Windows.Forms.Control.Paint-Ereignis und die Invalidate-Methode (PictureBox erbt von Control und hat diese daher ebenfalls)
    an. Über die kannst du das einfach lösen. Durch Graphics.DrawLine kannst du eine flüssige Linie zeichnen und per Graphics.DrawString Text. Das Paint-Ereignis wird durch Invalidate ausgelöst und du erhältst durch e.Graphics eben das Graphics-Objekt, mit dem du zeichnen kannst.

    VB.NET-Quellcode

    1. Private Sub PictureBox_Paint(ByVal sender As Object, ByVal e As PaintEventArgs) Handles PictureBox.Paint
    2. With e.Graphics
    3. '.DrawLine, ...
    4. End With
    5. End Sub

    IntelliSense sollte dir beim Rest helfen.
    Zu unfähig ist glaub' ich keiner hier im Forum - höchstens zu ungeübt oder lernfaul.
    Wenn du dir eine etwas kompliziertere Variante von Graphen darstellen ansehen willst: [VB.NET] Einfaches Plotten von Funktionen

    Gruß
    ~blaze~
    Dankeschön!!! :)
    Naja, unerfahren. Ich hab mich eig. noch nie mit Graphics etc. beschäftigt. Meistens hab ich nur das geschrieben, was YouTube gezeigt hat...

    Da ich wie gesagt -1 Ahnung habe, hab ich einfach mal den Link von Dir angeklickt und den Inhalt in mein Projekt eingefügt.

    Der "lange" Code klappte problemlos, allerdings weiß ich nicht was ich hinter 'Ziel einsetzen soll und wie ich die Funktion definieren soll (statt Math.Sin(v * v / 10) die quadratische Gleichung.

    VB.NET-Quellcode

    1. Private Sub PictureBox4_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles PictureBox4.Paint Dim g As Graphics = Plot(g, New Range(3, 100), New Range(-1, 1), ClientRectangle, New PointF(0, 0), 1.0, Function(v As Double) Math.Sin(v * v / 10)) End Sub



    Ich hab jetzt willkürlich mal nen Handler mit PictureBox4 (das soll die PictureBox sein wo es eingefügt werden soll) genommen und es eingefügt.

    Und es gibt Fehler, jede Menge...


    Quellcode

    1. Fehler 4 Der Wert vom Typ "Double" kann nicht in "System.Drawing.PointF" konvertiert werden. C:\Users\SammelcenterSLDW\documents\visual studio 2010\Projects\Gleichungslöser\Gleichungslöser\Form1.vb 312 89 GleichungslöserFehler 1 Der Wert vom Typ "Gleichungslöser.Form1.Range" kann nicht in "System.Drawing.Color" konvertiert werden. C:\Users\SammelcenterSLDW\documents\visual studio 2010\Projects\Gleichungslöser\Gleichungslöser\Form1.vb 312 17 GleichungslöserFehler 3 Der Wert vom Typ "System.Drawing.PointF" kann nicht in "System.Drawing.RectangleF" konvertiert werden. C:\Users\SammelcenterSLDW\documents\visual studio 2010\Projects\Gleichungslöser\Gleichungslöser\Form1.vb 312 71 GleichungslöserFehler 2 Der Wert vom Typ "System.Drawing.Rectangle" kann nicht in "Gleichungslöser.Form1.Range" konvertiert werden. C:\Users\SammelcenterSLDW\documents\visual studio 2010\Projects\Gleichungslöser\Gleichungslöser\Form1.vb 312 54 Gleichungslöser



    Tut mir leid wenn ich so destruktiv bin, ich bin wirklich ein totaler Anfänger. Und die Bücher zum Einsteigen versteh ich auch nicht. Ich will aber unbedingt Programmierer werden ;)
    YT-Tutorials sind meist keine guten Quellen, da die Leute, die sie einstellen noch weniger Ahnung haben, als man selber ;).
    Function(v As Double) Math.Sin(v * v / 10) ersetzt du einfach mit einer beliebigen Funktion, die du so anpasst, wie du sie haben willst.
    Function(x As Double) a * x * x + b * x + c a, b, c solltest du dann anderso deklarieren (evtl. auch mit eindeutigen Namen). Hinter Ziel setzt du dann e.Graphics ein und statt ClientRectangle nimmst du PictureBox4.ClientRectangle, da sonst der Clientbereich der Form angenommen wird.

    Gruß
    ~blaze~
    Wow, danke für die äußerst hilfreiche Antwort. Ich hab das Gefühl dass es gleich klappen wird :D

    Jetzt hab ich alles außer einen korrekten Graphen. Ich nehme mal an, dass V die Variable ist f(v), ich hab einfach mal Deine (Ihre) Sinusfunktion als Beispiel genommen.


    Screenshot: s7.directupload.net/file/d/3157/2tnczair_png.htm


    Problem: "a * v ^ 2 + b * v + c" ist ja die Gleichung. Aber leider wird nur ne grade Linie angezeigt. Sobald ich das Fenster verschiebe, hängt sich mein System auf... Haben Sie dafür eine Lösung?
    Kannst mich ruhig duzen.
    Das Verfahren ist leider nicht das performanteste. Je nach gewähltem Intervall sollte es aber effizient genug sein. Wähle den Inverall in x-Richtung dynamisch oder auf Benutzereingaben hin.
    Andere Lösung: Du zeichnest ungenau. Das Verfahren von mir ist halt darauf ausgelegt, dass es vor allem enge Stellen genau zeichnet. Wenn es dir nicht darauf ankommt, verwende einfach DrawLine, um von (x, f(x)) nach (x+1, f(x+1)) zu zeichnen. Das ist vielleicht sogar einfacher so ;). Hast du a, b und c übrigens entsprechend gesetzt? Bei mir funktioniert's.

    Gruß
    ~blaze~
    Okay.
    Also d.h. bei Dir wird eine "normale" gewöhnliche Parabel gezeigt?

    Ich kann Dir auch den ganzen Quellcode mal zeigen, das mit der Funktion steht ganz unten. Die verwendete PictureBox4 ist 377x362 groß, vielleicht hat es damit zu tun?

    Wie geht das mit DrawLine? ;) :D Also Code?

    Wenn es Dir zu umständlich ist, mir alles zu erklären, kann ich ruhig lange warten. Daaaaanke!!! :)
    Versuch dich lieber selber dran. Das sind insgesamt vielleicht 30 Codezeilen. Erst ermittelst du die Werte für a, b und c per Single.TryParse (schau' dir dazu die Funktionen im IntelliSense oder bei einer Suchmaschine deiner Wahl an). Sobald du die Werte hast, verwendest du eine For-Schleife, um von x1 nach x2 zu gehen. Hierbei berechnest du immer den Punkt (x, f(x)) und behältst den alten (x-1, f(x-1)) in einer Variablen (oder berechnest ihn halt neu, ist egal. Den ersten Punkt musst du aber bereits vorberechnen und dann bei x+1 anfangen ;)). Per DrawLine(Pen, pAlt, pNeu) verknüpfst du dann die zwei Punkte.
    Codes sind immer sehr schlechte Lernquellen, da, wenn man nicht weiß, warum etwas funktioniert/nicht funktioniert, man gewillt ist, es einfach hinzunehmen. Außerdem lernst du durch Trial und Error und Buch/Doku lesen viel mehr, als wenn man dir 'nen fertigen Quellcode hinklatscht.

    Gruß
    ~blaze~
    Jop, finde ich auch, Du hast völlig Recht. Danke.

    Ich werde mir das morgen gaaanz genau anschauen und durcharbeiten. (Heute ist zu spät). So einen Ratgeber habe ich mir schon immer gewünscht. Besten Dank, einfach perfekt.

    Liebste Grüße,

    Kesselwagen
    Und um das ganze noch ein wenig ordentlich zu machen:
    Halte Ordnung in der Paint-Funktion. Wenn Du neben dem Graphen noch Achsen, Skalenwerte usw. darstellen willst, mach gleich für jedes eine separate Prozedur, der Du das Graphics-Objekt übergibst.
    Diese Vorgehensweise ist insbesondere dann nützlich, wenn Du dieses Bild drucken willst, da rufst Du diese Prozeduren nicht mit dem Paint-Graphics-Objekt, sondern mit dem Print-Graphics-Objekt auf. :D
    Die Paint-Funktion wird jedes Mal aufgerufen, wenn etwas darzustellen ist, also wenn Du neue Daten hast (per Invalidate()) oder wenn Du das Notepad drüber geschoben hast (Aufruf vom System). Diese Funktion wird also sehr häufig aufgerufen.
    Alle Rechnungen, die "statisch" sind, die Du also nicht für jede Darstellung brauchst, führe also nicht in der Paint-funktion durch, sondern da, wo sich Parameter ändern (z.B. im TextChange-Event einer TextBox).
    Die Ergebnisse merke Dir in der Klasse, die Paint-Funktion holt sie sich dann von dort.
    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!
    Gut, ich hab mir das genaue angeschaut und alles in meinem Programm eingebaut. Nun sieht der Code für PictureBox4_Paint so aus:

    VB.NET-Quellcode

    1. Dim points As New List(Of Point) Dim position As Integer = 10
    2. For x As Integer = -10 To 10
    3. Dim fx As Double
    4. fx = a * x * x + b * x + c
    5. RichTextBox1.Text &= x & " " & fx & vbCrLf
    6. pts.Add(New Point(position, CSng(fx)))
    7. position += 10
    8. Next
    9. e.Graphics.DrawLines(Pens.Black, pts.ToArray)



    Leider kommt statt einer Parabel etwas "urkomisches" raus... Ich weiß auch nicht, wie viel Pixelabstand ich zwischen 0 und 1 auf dem Koordinatensystem nehmen soll...

    Die Richtextbox soll nur zur Kontrolle sein ob die Funktion f(x) stimmt.

    Screenshot: s1.directupload.net/file/d/3158/q794gwvt_png.htm

    Kesselwagen schrieb:

    Leider kommt statt einer Parabel etwas "urkomisches" raus.
    Wie das?
    a = 1; b = 1; c = 1
    Bilder
    • Parabel.jpg

      7,72 kB, 300×293, 163 mal angesehen
    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!
    Nun - Bei Paint-Ereignissen ist oben links die Koordinate (0, 0).
    Wenn Du es mathematisch korrekt haben willst, musst Du die Darstellung höhen-invertieren.
    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!

    Kesselwagen schrieb:

    oder so
    : Höhe - y, damit der Wertebereich im Bild bleibt.
    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!