Drehzahlmesser grafisch visualisiert

  • VB.NET

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

    Drehzahlmesser grafisch visualisiert

    Servus,

    ich bekomme von einem Drehzahlgeber in regelmäßigen Abständen den Input. Ich rechne die Drehzahl aus und möchte sie in einer Picturebox darstellen.
    Ich dachte an einen Kreisring (Donut) mit Segmenten von 0 bis 7. In der Mitte eine Linie als Nadel, die sich bewegt. Ich brauche keine farblichen Hintergründe wie grün über gelb ins Rote.
    Ich kenne mich mit dem Erstellen von solchen Formen nicht so gut aus; ich würde so anfangen:

    ich brauche

    Visual Basic-Quellcode

    1. Dim bm As New Bitmap(220, 220)

    nachdem die Drehzahl berechnet wurde

    VB.NET-Quellcode

    1. PictureBox1.BackgroundImage = Diagramm_erstellen(bm)


    und dann die Prozedur

    VB.NET-Quellcode

    1. Function Diagramm_erstellen(ByVal Image As Image, ByVal Drehzahl as Integer)
    2. '.
    3. bm.SetPixel(xKoordinate, yKoordinate, Color.FromArgb(a, b, c))
    4. '.
    5. PictureBox1.BackgroundImage = bm
    6. Return bm
    7. End Function


    Wahrscheinlich brauche ich auch eine Abfrage, wo die Nadel gerade hinzeigt und dann +Schrittweite.
    Könntet ihr mir bitte einen Ansatz geben?
    An die Neulinge: Nutzt Option Strict On und Option Infer Off. Dadurch kommt ihr mit Datentypumwandlungen nicht durcheinander und der Code verbessert sich um Einiges! Solche Fehler à la Dim Beispiel As Integer = "123" können nicht mehr passieren.
    @Bartosz Ich denke mal, dass Du den Hintergrund, also Farben der Fläche und die Zahlen, selber hinbekommst.
    Sieh Dir dazu die Graphics-Prozeduren DrawPie() und FillPie() an.
    Als Linie malst Du einen dicken Strich vom Mittelpunkt zu der korrekten Umfangs-Position.
    Dazu gibt es zwei Möglichkeiten: Du malst direkt in die PictureBox. Dann musst Du den Platz des alten Striches invalidisieren.
    Lege Du um die Endpunkte des Strichs ein Um-Rechteck plus Linienbreite und PB.Invalidate(DAS_UMRECHTECK)
    oder
    Du malst in eine Bitmap und stellst einfach nur die Bitmap dar.
    Dies ist die eleganter aussehende Lösung.
    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
    ja, diese Befehle kenne ich nicht ;) Danke!
    Ich habe mir diesen Thread durchgelesen.
    Tortendiagramm (pie chart) malen

    Dort werden anhand von 2 Werten die 360° des Kreises durch Dreisatz aufgeteilt.
    Ich will jedoch, dass unten ein bestimmter Bereich komplett (meinetwegen Segment von 90°) unberührt bleibt.
    An die Neulinge: Nutzt Option Strict On und Option Infer Off. Dadurch kommt ihr mit Datentypumwandlungen nicht durcheinander und der Code verbessert sich um Einiges! Solche Fehler à la Dim Beispiel As Integer = "123" können nicht mehr passieren.

    Bartosz schrieb:

    Ich will jedoch
    Wo ist das Problem?
    Winkel 42° entspricht 0 Umdrehungen
    Winkel 183° entspricht max Umdrehungen.
    Ersetze die 360° Deines Posts durch meine beispielhaften 141° und feddich.
    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!
    Ich hab's jetzt so gemacht. Ist n bissl einfacher.

    VB.NET-Quellcode

    1. Private Sub PictureBox_D_Paint(sender As Object, e As PaintEventArgs) Handles PictureBox_D.Paint
    2. x.Paint({50, 200}, e.Graphics)
    3. End Sub
    4. End Class
    5. Public Class myPie
    6. Public Sub Paint(ByVal values() As Double, ByVal g As Graphics)
    7. Dim myPen As Pen = Pens.Black
    8. Dim myRect As New Rectangle(0, 0, 220, 220)
    9. Using myBrush As SolidBrush = New SolidBrush(Color.Red)
    10. Dim colors() As Color = {Color.Red, Color.DimGray}
    11. Dim sum As Double = values.ToList().Sum
    12. Dim Offset As Single = 45 'dreht die Torte im Gesamten um 45° im Uhrzeigersinn
    13. Dim nicht_benutztes_Stueck As Single = 90 'das unten nicht benutze Stück ist schwarz und 90° groß
    14. myBrush.Color = Color.Black
    15. g.FillPie(myBrush, myRect, Offset, nicht_benutztes_Stueck)
    16. Dim Rest As Single = 360 - nicht_benutztes_Stueck
    17. '====================================================================
    18. 'nun können die beiden (ich nenne es mal) Parteien sich den Rest des
    19. 'Kreises aufteilen. Wird mit Dreisatz gemacht.
    20. '===================================================================
    21. Dim Startwinkel As Single = Offset + nicht_benutztes_Stueck
    22. Dim jew_Winkel As Single
    23. Dim Winkel1 As Single
    24. jew_Winkel = CSng(values(0) * (360 - nicht_benutztes_Stueck) / sum)
    25. Winkel1 = jew_Winkel
    26. Dim myColor As Color = colors(0 Mod 2)
    27. myBrush.Color = myColor
    28. g.DrawPie(Pens.Black, myRect, Startwinkel, jew_Winkel)
    29. g.FillPie(myBrush, myRect, Startwinkel, jew_Winkel)
    30. Rest -= jew_Winkel
    31. jew_Winkel = CSng(values(1) * (360 - nicht_benutztes_Stueck - Winkel1) / sum)
    32. g.DrawPie(Pens.Black, myRect, Startwinkel + Winkel1, jew_Winkel + Offset)
    33. Dim myColor2 As Color = colors(1 Mod 2)
    34. myBrush.Color = myColor2
    35. g.FillPie(myBrush, myRect, Startwinkel + Winkel1, jew_Winkel + Offset)
    36. End Using
    37. End Sub
    38. End Class


    Eine Frage hätte ich da noch. Oben wird für

    VB.NET-Quellcode

    1. x.Paint({50, 200}, e.Graphics)
    statt der "50" "Drehzahl" eingesetzt. Wie kann ich die

    VB.NET-Quellcode

    1. Private Sub PictureBox_D_Paint
    aufrufen? oder die

    VB.NET-Quellcode

    1. Public Class myPie
    2. Public Sub Paint(


    edit 19:50 Uhr Ich habe gerade noch ein bisschen rumprobiert. So 100%-ig akkurat ist das nicht. Die Zahlenkombination 50, 200 klappt super. Aber bei 250, 200 fehlt am Ende ein Stück vom Kreis. Wahrscheinlich darf man die Winkel nicht so berechnen? Ich habe es händisch nachgerechnet, das ist wirklich nicht ganz genau.

    50*(360-90)/250 = 54°
    200*(360-90-54)/250 = 172,8°
    360°-90°-45°-172,8°-54° = -1,8° ?(

    edit 20:53 Uhr Ich habe es jetzt so gemacht, dass der Fehler zur Hälfte auf beide Segmente aufgeteilt wird. Nun läuft's!

    VB.NET-Quellcode

    1. Private Sub PictureBox_D_Paint(sender As Object, e As PaintEventArgs) Handles PictureBox_D.Paint
    2. x.Paint({2000, 200}, e.Graphics)
    3. End Sub
    4. End Class
    5. Public Class myPie
    6. Public Sub Paint(ByVal values() As Double, ByVal g As Graphics)
    7. Dim myPen As Pen = Pens.Black
    8. Dim myRect As New Rectangle(0, 0, 220, 220)
    9. Using myBrush As SolidBrush = New SolidBrush(Color.Red)
    10. Dim colors() As Color = {Color.Red, Color.DimGray}
    11. Dim sum As Double = values.ToList().Sum
    12. Dim Offset As Single = 45 'dreht die Torte im Gesamten um 45° im Uhrzeigersinn
    13. Dim nicht_benutztes_Stueck As Single = 90 'das unten nicht benutze Stück ist schwarz und 90° groß
    14. myBrush.Color = Color.Black
    15. g.FillPie(myBrush, myRect, Offset, nicht_benutztes_Stueck) '135° weg. 135° ist der Startwert für das nächste Segment
    16. Dim Rest As Single = 360 - nicht_benutztes_Stueck 'trotzdem sind de facto noch 270° über, die bemalt werden können
    17. '====================================================================
    18. 'nun können die beiden (ich nenne es mal) Parteien sich den Rest des
    19. 'Kreises aufteilen. Wird mit Dreisatz gemacht.
    20. '===================================================================
    21. Dim Startwinkel As Single = Offset + nicht_benutztes_Stueck
    22. Dim Winkel1 As Single = CSng(values(0) * (360 - nicht_benutztes_Stueck) / sum)
    23. Rest -= Winkel1
    24. Dim Winkel2 As Single = CSng(values(1) * (360 - nicht_benutztes_Stueck - Winkel1) / sum)
    25. '=================================================================
    26. 'trotz Dreisatzrechnung und Kommazahlen gibt es immer noch einen
    27. 'kleinen Restfehler. Ein Beispiel:
    28. '50*(360-90)/250 = 54°
    29. '200*(360-90-54)/250 = 172,8°
    30. '360°-90°-45°-172,8°-54° = -1,8
    31. 'Dieser Rest wird auf beide Segmente zur Hälfte aufgeteilt
    32. '=================================================================
    33. Dim Rest3 As Single = 360 - Offset - nicht_benutztes_Stueck - Winkel1 - Winkel2
    34. Dim myColor As Color = colors(0 Mod 2)
    35. Dim myColor2 As Color = colors(1 Mod 2)
    36. If Rest3 < CSng(0.0) Then
    37. myBrush.Color = myColor
    38. g.DrawPie(Pens.Red, myRect, Startwinkel, Winkel1 - CSng((Rest3 * 0.5)))
    39. g.FillPie(myBrush, myRect, Startwinkel, Winkel1 - CSng((Rest3 * 0.5)))
    40. myBrush.Color = myColor2
    41. g.DrawPie(Pens.Yellow, myRect, Startwinkel + Winkel1, Rest - CSng((Rest3 * 0.5)))
    42. g.FillPie(myBrush, myRect, Startwinkel + Winkel1, Rest - CSng((Rest3 * 0.5)))
    43. ElseIf Rest > CSng(0.0) Then
    44. myBrush.Color = myColor
    45. g.DrawPie(Pens.Red, myRect, Startwinkel, Winkel1 + CSng((Rest3 * 0.5)))
    46. g.FillPie(myBrush, myRect, Startwinkel, Winkel1 + CSng((Rest3 * 0.5)))
    47. myBrush.Color = myColor2
    48. g.DrawPie(Pens.Yellow, myRect, Startwinkel + Winkel1, Rest + CSng((Rest3 * 0.5)))
    49. g.FillPie(myBrush, myRect, Startwinkel + Winkel1, Rest + CSng((Rest3 * 0.5)))
    50. Else
    51. End If
    52. End Using
    53. End Sub
    54. End Class

    Bleibt nur noch die Frage, wie ich

    VB.NET-Quellcode

    1. ​ x.Paint({2000, 200}, e.Graphics)
    von außen aufrufen kann.
    An die Neulinge: Nutzt Option Strict On und Option Infer Off. Dadurch kommt ihr mit Datentypumwandlungen nicht durcheinander und der Code verbessert sich um Einiges! Solche Fehler à la Dim Beispiel As Integer = "123" können nicht mehr passieren.

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Bartosz“ ()

    Bartosz schrieb:

    Wie kann ich die
    Private Sub PictureBox_D_Paint
    aufrufen? oder die
    Da hast Du noch etwas Verständnis-Defizit über das Malen unter .NET.
    Solo gar nicht, das läuft alles über .Invalidate() des Containers.
    • Empfang eines neuen Wertes
    • Bereitstellung der entsprechenden Variablen
    • .Invalidate()
    Feddich.
    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!
    Gegenvorschlag:

    VB.NET-Quellcode

    1. Public Class myPie
    2. Public Sub Paint(values As Double(), g As Graphics)
    3. Dim myRect As New Rectangle(0, 0, 200, 200)
    4. Dim sum = values.Sum
    5. Dim Offset = 45 'dreht die Torte im Gesamten um 45° im Uhrzeigersinn
    6. Dim nicht_benutztes_Stueck = 90 'das unten nicht benutze Stück ist schwarz und 90° groß
    7. Dim Startwinkel As Single = Offset + nicht_benutztes_Stueck
    8. Dim Winkel1 As Single = CSng(values(0) * (360 - nicht_benutztes_Stueck) / sum)
    9. Dim Winkel2 As Single = CSng(values(1) * (360 - nicht_benutztes_Stueck) / sum)
    10. g.FillPie(Brushes.Black, myRect, Offset, nicht_benutztes_Stueck)
    11. g.FillPie(Brushes.Green, myRect, Startwinkel, Winkel1)
    12. g.FillPie(Brushes.Red, myRect, Startwinkel + Winkel1, Winkel2)
    13. End Sub
    14. End Class

    Und zur anderen Frage:

    VB.NET-Quellcode

    1. PictureBox_D.Invalidate


    ##########

    Uiuiui, da kam ich aber etwas spät.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    @RodFromGermany @VaporiZed Danke für die Antworten! Also ich bin jetzt in der Form1-Klasse in einem Sub. Hier schreibe ich

    VB.NET-Quellcode

    1. PictureBox_D.Invalidate()
    . Ich weiß gerade nicht, wo die neue Drehzahl übergeben wird
    An die Neulinge: Nutzt Option Strict On und Option Infer Off. Dadurch kommt ihr mit Datentypumwandlungen nicht durcheinander und der Code verbessert sich um Einiges! Solche Fehler à la Dim Beispiel As Integer = "123" können nicht mehr passieren.
    So gar nicht. Das Invalidate führt nur dazu, dass das PicBox_Paint-Event gefeuert wird. Daher wäre es sinnvoll, wenn Du in Deiner myPie-Klasse noch eine Sub mit Wertzuweisung machst:

    VB.NET-Quellcode

    1. Public Class Form1
    2. Private myPie As New myPie
    3. Public Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    4. myPie.SetValues({100, 200})
    5. End Sub
    6. '...
    7. Public Class myPie
    8. Private values As Double() = {0, 0}
    9. Public Sub SetValues(values As Double())
    10. Me.values = values
    11. End Sub
    12. Public Sub Paint(g As Graphics)
    13. 'sonst Code wie oben
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

    Bartosz schrieb:

    wo die neue Drehzahl übergeben wird

    RodFromGermany schrieb:

    Bereitstellung der entsprechenden Variablen
    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!