GraphicsPath - Kreisbogen

  • VB.NET

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

    GraphicsPath - Kreisbogen

    Hallo..
    Ich habe eine kleines Problem.
    Ich möchte eine round Progress Bar machen, die etwa so aussieht:

    Arc1 und Arc2 bekomme ich noch prima hin.
    Line1 geht auch nocht super.
    Aber bei Line2 hört der Spaß auf.
    Weiss einer wie ich die 2 Koordinaten berechnen kann?
    (Annahme: Das Objekt ist 100 x 100 gross)
    na wenn du arc1 und arc2 hast, hast du doch den Öffnungswinkel...
    Dann kannste doch die Linie zeichen? Einfach mit Winkelfunktion?
    StartPunkt: sin(Öffnungswinkel) ergibt dein Y-Abschnitt, cos(Öffnungswinkel) dein X-Abschnitt
    Die musst Du Dir berechnen.
    Kreis1 = Gerade
    Kreis2 = Gerade
    Kreis1: (x-x1)^2 + (y-y1)^2 = r1^2
    Kreis2: (x-x1)^2 + (y-y1)^2 = r2^2
    Gerade: y = a + b * x

    gegeben: x1, y1, r1, r2, a, b
    gesucht: x, y (Schnittpunkt)
    Kreis2 brauchst Du eigentlich nicht, da die Radius-Differenz bekannt ist.

    Nullpunkt-Transformation: x1 = y1 = 0 (kein Problem, kannst Du hinterher wieder draufaddieren)
    x^2 + y^2 = r1^2
    Kreis1 nach y auflösen:
    y = +-SQRT(r1^2 - x^2) ' +- : 2 Lösungen, musst Du dann entsprechend zuordnen
    mit Gerade gleich setzen:
    a + b * x = +-SQRT(r1^2 - x^2)
    nach x umstellen - fertig.
    je nach +- erhältst Du 2 x-Werte und dazu 2 y-Werte.
    Fertig.
    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!
    Hi
    das übernimmt der GraphicsPath schon automatisch, wenn du in der richtigen Reihenfolge arbeitest. Zum Schluss einfach noch CloseFigure aufrufen, dann passts:

    VB.NET-Quellcode

    1. Dim gp As New Drawing2D.GraphicsPath()
    2. Dim angle As Single = 360.0F * (Value - Minimum) / (Maximum - Minimum)
    3. Dim bounds As Rectangle = ClientRectangle
    4. gp.AddArc(bounds.X, bounds.Y, bounds.Width - 1, bounds.Height - 1, -90.0F, angle)
    5. gp.AddArc(bounds.X + bounds.Width \ 8, bounds.Y + bounds.Height \ 8, bounds.Width - bounds.Width \ 4, bounds.Height - bounds.Height \ 4, -90.0F + angle, -angle)
    6. gp.CloseFigure()


    Gruß
    ~blaze~
    Danke an alle.
    Ich habs am schluss doch noch etwa auf Blazes weg hinbekommen

    VB.NET-Quellcode

    1. myPath.AddArc(New Drawing.Rectangle(0, 0, Me.Width - 1, Me.Height - 1), 270, winkel)
    2. myPath.Reverse()
    3. Dim innerRect As New Drawing.Rectangle(_RoundedWidth, _RoundedWidth, Me.Width - (_RoundedWidth * 2), Me.Height - (_RoundedWidth * 2))
    4. myPath.AddArc(innerRect, 270, winkel)
    5. myPath.Reverse()
    6. myPath.CloseFigure()
    Wozu die Reverses? Im Prinzip ziehst halt einfach nen Bogen mit Radius r und danach noch mal einen mit Radius r' < r in die andere Richtung, da immer von Endpunkt nach Aufpunkt verbunden wird. D.h. wenn du den Winkel a hast, ziehst das eine Ringsegment vom startwinkel aus um a im Uhrzeigersinn und beim anderen halt vom endwinkel (a + startwinkel) um -a, damit du wieder beim Startwinkel bist. Da du oben anfangen willst, musst du noch die zusätzlichen 90° zurück bzw. 270° nach vorne gehen.

    VB.NET-Quellcode

    1. myPath.AddArc(New Drawing.Rectangle(0, 0, Me.Width - 1, Me.Height - 1), 270, winkel)
    2. Dim innerRect As New Drawing.Rectangle(_RoundedWidth, _RoundedWidth, Me.Width - (_RoundedWidth * 2), Me.Height - (_RoundedWidth * 2))
    3. myPath.AddArc(innerRect, 270 + winkel, -winkel)
    4. myPath.CloseFigure()

    sollte so aussehen. Ich habe bisher noch nie Reverse verwendet, aber in dem Fall halte ich das eher für überflüssig, da man ja schon von Anfang an per anderem Winkel arbeiten kann.

    Gruß
    ~blaze~