Es posible que los extremos de un arco no se dibujen correctamente

Este artículo ayuda a resolver el problema por el que no se dibujan puntos de inicio y puntos de conexión en la posición correcta al dibujar un arco con un radio de gran tamaño.

Versión del producto original:   .NET Framework 3,5 Service Pack 1, .NET Framework 3.5.1, .NET Framework 4,5
Número de KB original:   2984519

Síntomas

Cuando se dibuja un arco con un radio grande, es posible que no se dibujen correctamente los puntos de inicio y finalización del arco en función del conjunto de parámetros.

Causa

En los exploradores Web, como Internet Explorer, es posible mostrar gráficos de aplicaciones de WPF que cargan y muestran imágenes representadas en formato SVG (Scalable Vector Graphics), o aplicaciones que muestran imágenes con XAML dinámico (que es la función para cargar y representar el marcado sin compilar).

La visualización de imágenes SVG y el motor de representación de XAML flexible usan DirectX (Direct3D9).

Sin embargo, el procesamiento en DirectX (Direct3D9) se realiza mediante un número de punto flotante de precisión sencilla. Por lo tanto, existe la posibilidad de que se dibuje una imagen inesperada si se usa un número grande que supera el límite del procesamiento.

Por ejemplo, en XAML dinámico, cuando dibuja un arco que tiene un radio grande, usando el A comando del Path marcado, el punto inicial y el extremo no se pueden dibujar en la posición correcta según el valor que se va a establecer.

Estado

Este comportamiento es una limitación del motor de representación que realiza el procesamiento con números de punto flotante de precisión simple.

Solución

Los desarrolladores deben tener en cuenta las limitaciones de las operaciones numéricas al realizar dibujos complejos usando sistemas de gráficos, que no están necesariamente limitados a XAML suelto.

Cuando se dibuja un arco con un radio grande, es posible que no se obtenga el resultado esperado debido a estas limitaciones y que los desarrolladores tomen enfoques alternativos, como reemplazar el arco con una línea, si la diferencia resultante de dicho reemplazo puede pasarse por alto de forma razonable.

Pasos para reproducir este problema

A continuación se indican los pasos para reproducir el caso de dibujar un arco con un radio de gran tamaño mediante el A comando del Path marcado:

Guarde el código siguiente en un archivo de texto con la extensión. XAML para crear un archivo XAML suelto. Al abrir este archivo con Internet Explorer 11, el motor de representación de WPF dibuja el arco rojo y la línea azul, tal y como se muestra en la siguiente captura de pantalla.

<?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>

El código de la línea 10 especifica que se dibuje un arco rojo a partir de una coordenada absoluta (26557,35, 3320,226), que se establece mediante el M comando del Figures atributo dentro de un PathGeometry elemento, en otra coordenada absoluta (26569,29, 3290,773), que se establece mediante el A comando usando un radio de 1703595.

Mientras tanto, el código de la línea 15 dibuja una línea azul a partir de una coordenada absoluta (26557,35, 3320,226), que se establece mediante el M comando, en otra coordenada absoluta (26569,29, 3290,773), que se establece mediante el L comando.

Nota

El arco se dibuja con puntos de conexión mal colocados, aunque el arco y la línea usen el mismo par de puntos de inicio y finalización.

Figura 1: los extremos del arco rojo están mal colocados

Este ejemplo tiene como objetivo conectar dos puntos que tienen 32 píxeles de separación usando un arco con un radio de 1,7 millones píxeles; no es un enfoque significativo porque estos dos valores son astronomically diferentes. Como se muestra en la siguiente captura de pantalla, la desviación máxima del arco (AM'B) de la línea (AMB) es inferior a 0,0001 píxeles (MM '), que sería lo suficientemente pequeña como para ser invisible incluso si esas formas se dibujaron con mayor precisión matemática. Por lo tanto, en situaciones como esta, dibujar una línea entre estos dos puntos sería un enfoque mucho más adecuado porque reduciría la probabilidad de que se alcanzaran las limitaciones numéricas del procesamiento interno.

Figura 2: desviación máxima del arco desde la línea.