Rückgabewerte einer (mathematischen) Funktion darstellen

    • VB.NET

    Es gibt 5 Antworten in diesem Thema. Der letzte Beitrag () ist von jvbsl.

      Rückgabewerte einer (mathematischen) Funktion darstellen

      Hallo Forum,
      ich hab vor kurzer Zeit ein kleines Programm geschrieben, dass Rückgabewerte einer Funktion auf einem Panel darstellt. (=Graph der Funktion ;))
      Die Formel kann man zwar nicht direkt im Programm bearbeiten, aber lässt sich relativ bequem im Sourcecode einbauen.

      Ganzer Code

      Dafür benötigt:
      • Timer t_timer
      • Panel Panel1

      (Projektmappe im Anhang ;))

      VB.NET-Quellcode

      1. Public Class Form1
      2. Private Lists As New List(Of List(Of Point))
      3. Private last_x As Integer = 0
      4. Private colors As New List(Of Color)(New Color() {Color.Red, Color.Black, Color.Blue, Color.Black, Color.Orange, Color.Black, Color.Green, Color.Black, Color.Purple, Color.Black, Color.Fuchsia, Color.Black, Color.Olive, Color.Black})
      5. Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
      6. bg = New BufferedGraphicsContext().Allocate(Panel1.CreateGraphics, Panel1.ClientRectangle)
      7. t_timer.Start()
      8. End Sub
      9. Private Sub t_timer_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles t_timer.Tick
      10. last_x += 1
      11. 'Werte holen
      12. Dim values = FetchValues(last_x)
      13. 'Punkte berechnen
      14. Dim points = MakePoints(values, last_x)
      15. 'Punkte in Liste einsortieren
      16. For index = 0 To points.Count - 1
      17. 'Falls keine Liste vorhanden eine erstellen
      18. If Lists.Count = index Then Lists.Add(New List(Of Point))
      19. 'Punkte einsortieren
      20. Lists(index).Add(points(index))
      21. Next
      22. 'Punkte zeichnen
      23. DrawPoints()
      24. End Sub
      25. Function FetchValues(ByVal x As Integer) As List(Of Integer)
      26. Dim values As New List(Of Integer)
      27. 'Werte berechnen
      28. Dim v0 = 200 * Math.Sin(x / 500)
      29. Dim v1 = 200 * Math.Sin(x / 100) ^ 1000
      30. Dim v2 = 200 * Math.Cos(x / 100) ^ Math.Truncate(Math.Abs(v1 / 10)) - v0
      31. values.Add(v2 + 300)
      32. values.Add(300)
      33. values.Add(v0 + v1 + 300)
      34. values.Add(0)
      35. Return values
      36. End Function
      37. Private corr As Single = 0
      38. Function MakePoints(ByVal values As List(Of Integer), ByVal x As Integer) As List(Of Point)
      39. Dim ret As New List(Of Point)
      40. For Each v In values
      41. 'x-achse korrigieren
      42. If x >= Panel1.Width - 25 Then
      43. bg.Graphics.TranslateTransform(-(1 / Lists.Count), 0)
      44. bg.Graphics.Clear(Panel1.BackColor)
      45. corr += (1 / Lists.Count)
      46. End If
      47. 'Jeden Wert (y) mit einem x-Wert versehen
      48. ret.Add(New Point(x, Panel1.Height - v + 25))
      49. Next
      50. Return ret
      51. End Function
      52. Private bg As BufferedGraphics
      53. Sub DrawPoints()
      54. With bg.Graphics
      55. .FillRectangle(New SolidBrush(Panel1.BackColor), Panel1.ClientRectangle)
      56. For index = 0 To Lists.Count - 1
      57. If Lists(index).Count > 1 Then
      58. .DrawLines(New Pen(New SolidBrush(colors(index))), Lists(index).ToArray)
      59. End If
      60. Next
      61. .DrawLine(Pens.Black, PointToClient(New Point(Cursor.Position.X + corr, 0)), PointToClient(New Point(Cursor.Position.X + corr, Panel1.Height + 1000)))
      62. If add Then
      63. grayment += 5
      64. Else
      65. grayment -= 5
      66. End If
      67. If grayment = 100 Or grayment = 255 Then add = Not add
      68. .DrawLine(New Pen(Color.FromArgb(grayment, grayment, grayment)), last_x + 1, 0, last_x + 1, Panel1.Height)
      69. End With
      70. bg.Render()
      71. End Sub
      72. Dim add As Boolean = True
      73. Dim grayment As Byte = 100
      74. Private Sub Panel1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Panel1.Click
      75. t_timer.Enabled = Not t_timer.Enabled
      76. End Sub
      77. End Class



      Interessant ist eigentlich nur:

      VB.NET-Quellcode

      1. Function FetchValues(ByVal x As Integer) As List(Of Integer)
      2. Dim values As New List(Of Integer)
      3. 'Werte berechnen
      4. Dim v0 = 200 * Math.Sin(x / 500)
      5. Dim v1 = 200 * Math.Sin(x / 100) ^ 1000
      6. Dim v2 = 200 * Math.Cos(x / 100) ^ Math.Truncate(Math.Abs(v1 / 10)) - v0
      7. values.Add(v2 + 300)
      8. values.Add(300)
      9. values.Add(v0 + v1 + 300)
      10. values.Add(0)
      11. Return values
      12. End Function

      Hier wird in die Variable values ein Wert eingetragen, der dem Rückgabewert der Funktion entspricht.
      Dabei ist jedes Item ein Rückgabewert einer unterschiedlichen Funktion.
      Jedes zweite Item wird im Graphen schwarz dargestellt. Da viele Funktionen negative Rückgabewerte liefern, muss man diese nach oben versetzen (v2 + 300). Da man dann die Nulllinie nicht mehr erkennen kann, setzt man eine zweite "Funktion" hinzu (values.Add(300)), die schwarz dargestellt wird, und immer den theoretischen Nullwert besitzt. ;)

      Werden die Kurven zu lang, "scrollt" das Programm mit.
      Das Programm ist nur zur Veranschaulichung der Graphen gedacht, aber liefert keine genauen Werte ;)
      Trotzdem eine nette Spielerei ;) Kann natürlich weit ausgebaut werden :rolleyes:
      Dateien
      • Graph.zip

        (66,61 kB, 152 mal heruntergeladen, zuletzt: )
      nein, die Begrenztheit des Programmierers :P
      Es sind die Berechnungen auf der CPU, die das ganze verursachen, wenn du das in DirectX machst und auf der GPU zeichnest aber in der CPU rechnest, wird das so viel schneller auch nicht werden...
      Ich wollte auch mal ne total überflüssige Signatur:
      ---Leer---

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

      guck - ich hab die "Berechnungen" mal wesentlich vereinfacht, und läuft immer noch mit 100% Kernel-Last:

      VB.NET-Quellcode

      1. Function FetchValues(ByVal x As Integer) As List(Of Integer)
      2. Dim values As New List(Of Integer)
      3. ''Werte berechnen
      4. 'Dim v0 = 200 * Math.Sin(x / 500)
      5. 'Dim v1 = 200 * Math.Sin(x / 100) ^ 1000
      6. 'Dim v2 = 200 * Math.Cos(x / 100) ^ Math.Truncate(Math.Abs(v1 / 10)) - v0
      7. 'values.Add(v2 + 300)
      8. 'values.Add(300)
      9. 'values.Add(v0 + v1 + 300)
      10. 'values.Add(0)
      11. values.AddRange({10, 20, 30})
      12. Return values
      13. End Function

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

      war aber falsch formuliert -.- auch wenn du das zeichnen auf der GPU machst, aber das rechnen auf der CPU^^
      Wenn du das ganze bei GDI+ in Threads auslagerst parallel rechnest und lauter solche sachen dann wär das schonmal schneller...

      bzw. größere Schritte nehmen und eben die Punkte verbinden über normale Linien, oder kurven im Fall von Sinus z.B.
      Ich wollte auch mal ne total überflüssige Signatur:
      ---Leer---