Die Endpunkte eines Bogens werden möglicherweise nicht ordnungsgemäß gezeichnet.

Dieser Artikel hilft Ihnen, das Problem zu beheben, bei dem Startpunkt und Endpunkte möglicherweise nicht an der richtigen Position gezeichnet werden, wenn Sie einen Bogen mit einem großen Radius zeichnen.

Ursprüngliche Produktversion: .NET Framework 3.5 Service Pack 1, .NET Framework 3.5.1, .NET Framework 4.5
Ursprüngliche KB-Nummer: 2984519

Symptome

Wenn Sie einen Bogen mit einem großen Radius zeichnen, werden die Anfangs- und Endpunkte des Bogens abhängig von den festgelegten Parametern möglicherweise nicht ordnungsgemäß gezeichnet.

Ursache

In Webbrowsern wie Internet Explorer ist es möglich, Grafiken von WPF-Anwendungen anzuzeigen, die Bilder laden und anzeigen, die im SVG-Format (Scalable Vector Graphics) dargestellt sind, oder Anwendungen, die Bilder mit Loose XAML anzeigen (die Funktion zum Laden und Rendern des Markups ohne Kompilierung).

Die Anzeige von SVG-Bildern und die Rendering-Engine von Loose XAML verwenden DirectX (Direct3D9).

Die Verarbeitung in DirectX (Direct3D9) erfolgt jedoch mit einer Gleitkommazahl mit einfacher Genauigkeit. Daher besteht die Möglichkeit, dass ein unerwartetes Bild gezeichnet wird, wenn Sie eine große Zahl verwenden, die den Grenzwert der Verarbeitung überschreitet.

Wenn Sie beispielsweise in Loose XAML einen Bogen mit einem großen Radius zeichnen, werden der APath Startpunkt und der Endpunkt je nach festzulegenden Wert möglicherweise nicht an der richtigen Position gezeichnet.

Status

Dieses Verhalten ist eine Einschränkung der Rendering-Engine, die die Verarbeitung mit Gleitkommazahl mit einfacher Genauigkeit ausführt.

Lösung

Entwickler müssen die Einschränkungen numerischer Vorgänge berücksichtigen, wenn sie komplexe Zeichnungen mithilfe von Grafiksystemen ausführen, die nicht unbedingt auf loses XAML beschränkt sind.

Wenn Sie einen Bogen mit einem großen Radius zeichnen, erhalten Sie aufgrund solcher Einschränkungen möglicherweise nicht das erwartete Ergebnis, und die Entwickler werden aufgefordert, alternative Ansätze wie das Ersetzen des Bogens durch eine Linie zu verwenden, wenn die resultierende Differenz einer solchen Ersetzung vernünftigerweise ignoriert werden kann.

Schritte zum Reproduzieren dieses Problems

Im Folgenden finden Sie die Schritte zum Reproduzieren des Falles des Zeichnens eines Bogens mit einem großen Radius mithilfe des A -Befehls des Path Markups:

Speichern Sie den folgenden Code in einer Textdatei mit der Erweiterung .xaml, um eine lose XAML-Datei zu erstellen. Wenn Sie diese Datei mit Internet Explorer 11 öffnen, zeichnet die WPF-Rendering-Engine den roten Bogen und die blaue Linie, wie im folgenden Screenshot gezeigt.

<?xml version="1.0" encoding="utf-8"?>
<Canvas Background="#fff" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Canvas.RenderTransform>
        <TransformGroup>
            <TranslateTransform X="-26000" Y="-3000" />
        </TransformGroup>
    </Canvas.RenderTransform>
    <Path Stroke="#f00" StrokeThickness="1">
        <Path.Data>
            <PathGeometry Figures="M 26557.35, 3320.226 A 1703595, 1703595, 0, 0, 0, 26569.29, 3290.773" />
        </Path.Data>
    </Path>
    <Path Stroke="#00f" StrokeThickness="3">
        <Path.Data>
            <PathGeometry Figures="M 26557.35, 3320.226 L 26569.29, 3290.773" />
        </Path.Data>
    </Path>
</Canvas>

Der Code in Zeile 10 gibt an, dass ein roter Bogen von einer absoluten Koordinate (26557.35, 3320.226), die durch den M Befehl des Figures Attributs innerhalb eines Elements festgelegt wird, auf eine PathGeometry andere absolute Koordinate (26569.29, 3290.773) gezeichnet wird, die vom A Befehl mit einem Radius von 1703595 festgelegt wird.

In der Zwischenzeit zeichnet der Code in Zeile 15 eine blaue Linie von einer absoluten Koordinate (26557,35, 3320.226), die durch den M Befehl festgelegt wird, auf eine andere absolute Koordinate (26569.29, 3290.773), die durch den L Befehl festgelegt wird.

Hinweis

Der Bogen wird mit falsch platzierten Endpunkten gezeichnet, obwohl sowohl der Bogen als auch die Linie das gleiche Paar von Start- und Endpunkten verwenden.

Abbildung: Endpunkte des roten Bogens sind falsch platziert.

In diesem Beispiel sollen zwei Punkte, die 32 Pixel voneinander entfernt sind, mithilfe eines Bogens mit einem Radius von 1,7 Millionen Pixeln verbunden werden. was kein sinnvoller Ansatz ist, da sich diese beiden Werte astronomisch unterscheiden. Wie im folgenden Screenshot gezeigt, beträgt die maximale Abweichung des Bogens (AM'B) von der Linie (AMB) weniger als 0,0001 Pixel (MM'), was klein genug wäre, um unsichtbar zu sein, selbst wenn diese Formen mit höchster mathematischer Genauigkeit gezeichnet würden. Daher wäre in solchen Situationen das Zeichnen einer Linie zwischen diesen beiden Punkten ein weitaus besserer Ansatz, da es die Wahrscheinlichkeit verringern würde, numerische Einschränkungen der internen Verarbeitung zu erreichen.

Abbildung zeigt die maximale Abweichung des Bogens von der Linie.