Ellipse Path - Radiusverzerrung bei ~180°

  • WPF

Es gibt 8 Antworten in diesem Thema. Der letzte Beitrag () ist von newcat.

    Ellipse Path - Radiusverzerrung bei ~180°

    Hallo,

    ich habe folgendes Problem:

    Ich zeichne mit einem Pfad einen gefüllten Bogen. Dazu benutze ich einen Pfad, der vom Codebehind ausgerechnet und applied wird. Das funktioniert auch soweit recht gut, wenn allerdings der Winkel des Ellipsenbogens um die 180° ist, wird der Radius "verzerrt", d. h. ich zeichne die Ellipse mit dem gleichen Radius wie immer, aber je näher ich an die 180° komme, desto stärker wird die Ellipse (hauptsächlich in x-Richtung, wenn ich das richtig sehe) verzerrt. Das Problem scheint quadratisch zu steigen. Ich habe ein paar Bilder angehängt, die das ganze verdeutlichen sollten. Im Spoiler steht der Code, der die Pfaddaten erstellt. Ich hoffe, ihr könnt mir sagen, wo das Problem liegt, ich komme leider nicht weiter und im Web habe ich bisher auch noch nichts dazu gefunden.

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Class MainWindow
    2. Dim iC As System.Globalization.CultureInfo = System.Globalization.CultureInfo.InvariantCulture
    3. Private Sub drawSpeed(speed)
    4. Dim data As String = "M88.5,187.5 L79.5,204.5" 'so fängt der Pfad an, ich setze hier den "Cursor" auf den Startpunkt (den Endpunkt des inneren Bogens) und zeichne eine Linie zum Startpunkt des äußeren
    5. Dim deg As Double = (speed / 360) * 300 - 150 'Hier rechne ich den Winkel aus. Zuerst ein kleiner Dreisatz (max. Winkel = 300°), danach -150°, da meine Nullinie ja um 150° gegen den Uhrzeigersinn rotiert ist
    6. Dim largeArc As Integer = 0 'Wird für den Bogen als Parameter gebraucht. Wenn der Winkel des Bogens >180° ist, muss dieser Wert 1 sein, sonst 0
    7. If deg + 150 >= 180 Then largeArc = 1 'Dies wird hier getestet
    8. Dim outerX As Double = Math.Sin(toRad(deg)) * 92 + 125 'Hier rechne ich nun die Koordinaten des Endpunkts vom äußeren Bogen aus. Dabei gilt: r = 92; Mittelpunkt M(125|125)
    9. Dim outerY As Double = 125 - Math.Cos(toRad(deg)) * 92 'Da das Koordinatensystem im Computer von oben nach unten geht, statt wie in der Mathematik üblich von unten nach oben, muss ich hier -cos() rechnen
    10. data += makeEllipseString(92, 92, largeArc, 1, outerX, outerY) 'Hier werden nun die Pfad-Daten aus den berechneten Koordinaten erstellt
    11. Dim innerX As Double = Math.Sin(toRad(deg)) * 73 + 125 's. o., r = 73
    12. Dim innerY As Double = 125 - Math.Cos(toRad(deg)) * 73 's. o.
    13. data += "L" & innerX.ToString(iC) & "," & innerY.ToString(iC) 'Hier wird nun vom Endpunkt des äußeren Bogens die Begrenzungslinie zum inneren Bogen gezogen.
    14. data += makeEllipseString(73, 73, largeArc, 0, 88.5, 187.5) & "Z" 'Anschließend wird ein Ellipsenbogen zurück zum Anfang gezogen und der Pfad geschlossen.
    15. speedPath.Data = System.Windows.Media.Geometry.Parse(data) 'Der fertige Datenstring wird nun applied
    16. End Sub
    17. Private Function toRad(deg) As Double
    18. Return deg * (Math.PI / 180) 'Winkel- zu Bogenmaß Konvertierung
    19. End Function
    20. Private Function makeEllipseString(rx As Double, ry As Double, largeArc As Integer, posDir As Integer, toX As Double, toY As Double) As String
    21. Return "A" & rx.ToString(iC) & "," & ry.ToString(iC) & ",0," & largeArc.ToString & "," & posDir.ToString & "," & toX.ToString(iC) & "," & toY.ToString(iC)
    22. End Function
    23. End Class


    Hier noch der Outline-Pfad mit dem grauen Background:

    XML-Quellcode

    1. <Path Data="M89,187 L79,205 A92.5,92.5,0,1,1,171,205 L161,187 A72.5,72.5,0,1,0,89,187 Z" Stroke="White" StrokeThickness="1" Fill="#2C808080"/>



    Noch nen kleiner Link zum Auffrischen des Pfadmarkups: msdn.microsoft.com/en-us/library/cc189041(v=vs.95).aspx
    Bilder
    • good_less.png

      72,86 kB, 535×385, 213 mal angesehen
    • good_more.png

      83 kB, 535×385, 174 mal angesehen
    • shit_less.png

      83,48 kB, 535×385, 175 mal angesehen
    • shit_more.png

      83,11 kB, 535×385, 166 mal angesehen
    Twitch Viewer Display Chat-, Zuschauer- und Statistiktool für Streamer

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

    Hab ich jetzt mal angemacht, habe mir Gott sei Dank schon angewöhnt die Konvertierungen explizit hinzuschreiben, das Einzige, was ich ändern musste, waren die Funktionsparameter zu definieren, habe ich jetzt gemacht (speed as integer, deg as double), macht aber leider keinen Unterschied.
    Twitch Viewer Display Chat-, Zuschauer- und Statistiktool für Streamer
    Habe mich jetzt nochmal etwas länger damit beschäftigt, bin zwar noch nicht auf die Lösung gekommen, konnte das Problem aber etwas eingrenzen.

    Ich habe mal testweise in einem Projekt zwei Pfade erstellt, der eine zeichnet einen Halbkreis, der andere einen Viertelkreis. Beim einen Kreis somit 180°, also der kritische Punkt, beim anderen 90°, wo noch alles okay ist. Radius der beiden Kreise ist gleich, nur die Endpunkte wurden entsprechend angepasst.
    Code:

    XML-Quellcode

    1. <Path Data="M150,150 A100,100,0,1,1,350,150" Stroke="Blue" StrokeThickness="1" />
    2. <Path Data="M150,150 A100,100,0,0,1,250,50" Stroke="Red" StrokeThickness="1" />


    So sieht das Ergebnis aus:

    Wie man sehen kann - alles gut.

    Somit muss das Problem bei meinen Rechnungen oben liegen. Jedoch ist das Einzige, was ich ausrechne, die Endpunkte des Bogens - aber wie auf den vier Bildern deutlich zu sehen, stimmen diese eigentlich. Das wiederum heißt, dass der Radius tatsächlich verzerrt wird - aber aus welchen Gründen? Ich muss dazu sagen, Ellipsen haben wir im Matheunterricht noch nicht behandelt, aber ehrlichgesagt scheinen mir diese Ellipsen (bzw. deren Parameter) wenig mit mathematischen Ellipsen zu tun zu haben.

    Jetzt habe ich mir mal überlegt, wann der Radius sich denn ändern könnte, obwohl der Radius in den Parametern des Pfades gleich bleibt. Klar: Wenn der Radius kleiner ist, als die Distanz zwischen Start- und Endpunkt KANN gar keine Ellipse gezeichnet werden. Aber siehe da: Wenn ich den Radius auf bspw. 10, 10 ändere, bleibt der Pfad gleich. Wenn ich jetzt nur einen Radius variiere, verändert sich auch die Ellipse entsprechend. Also: Das Verhältnis zwischen x- und y-Radius zählt. Macht ja auch Sinn. Bloß bringt mich das ja nicht wirklich weiter, denn: Das Verhältnis zwischen x- und y-Radius bleibt in meinem Fall konstant 1:1 -> Klar, denn ich möchte ja einen Kreis zeichnen und keine Ellipse. Jedoch wird kein Kreis gezeichnet, sondern eine Ellipse, denn wie auf den Bildern zu sehen, folgt der innere Bogen nicht den äußeren (weißen) Bögen. Diese sollten aber perfekte Kreise sein, da die Endpunkte der Ellipse immer in etwa (kleine Rechenungenauigkeiten vernachlässigt) an den äußeren Bögen liegen. Wären diese äußeren Bogen nicht kreisförmig, so wäre entweder die Berechnung für meine Endpunkte fehlerhaft, oder aber wir müssten Sinus und Cosinus neu definieren.

    Deshalb wäre ich froh, wenn sich vielleicht nochmal jemand die Rechnung genauer anschauen könnte, um sicher auszuschließen, dass es daran liegt. Aber natürlich freue ich mich auch über konstruktive Ideen zur Problemlösung :thumbsup:

    Vielen Dank schonmal
    newcat
    Twitch Viewer Display Chat-, Zuschauer- und Statistiktool für Streamer
    *bump*

    Sieht so aus als hätte keiner eine Lösung... schade. Aber dann frag ich mal so: Gibt es eine Alternative, um einen gefüllten Bogen zu zeichnen?
    Das was ich oben hab ist nur meine erste Idee gewesen, vielleicht kennt ja jemand noch eine elegantere Methode.
    Twitch Viewer Display Chat-, Zuschauer- und Statistiktool für Streamer
    "Life isn't about winning the race. Life is about finishing the race and how many people we can help finish the race." ~Marc Mero

    Nun bin ich also auch soweit: Keine VB-Fragen per PM! Es gibt hier ein Forum, verdammt!
    Das habe ich so ähnlich eigentlich... wie gesagt, die Endpunkte stimmen auf den Bildern auch, aber die Paths haben um 180° herum einen inkorrekten Radius und ich weiß einfach nicht, wo der herkommt.

    EDIT: In einer Stunde hab ich mal Zeit, ein paar Kommentare in meinen Code einzufügen, was ich da eigentlich rechne; ist momentan glaub eher unübersichtlich Kommentare eingefügt!
    Twitch Viewer Display Chat-, Zuschauer- und Statistiktool für Streamer

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

    Letzter Versuch, hier ist das Projekt. Mit dem Slider könnt ihr den Wert anpassen, mit dem oberen der beiden Buttons auf der rechten Seite könnt ihr den Bogen auf etwa 180° setzen, wo das Phänomen am stärksten auftritt.
    Dateien
    • f1t.zip

      (124,11 kB, 129 mal heruntergeladen, zuletzt: )
    Twitch Viewer Display Chat-, Zuschauer- und Statistiktool für Streamer