[SOLVED]FillEllipse() breaks for large ellipses

Jan 25, 2013 at 9:14 PM
Edited Jan 25, 2013 at 9:17 PM

When I try to draw ellipses in the thousands-of-pixels size range, they don't draw properly.

 

I reproduced the problem with the following code:

MainWindow.xaml:

<Window x:Class="EllipseTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <ScrollViewer Name="myScrollViewer">
        <Image Name="mainImage" Stretch="None"/>
    </ScrollViewer>
</Window>

MainWindow.xaml.cs:

using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Imaging;

namespace EllipseTest
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            // set-up huge image
            WriteableBitmap bmp = BitmapFactory.New(8000, 9000);
            bmp.FillRectangle(0, 0, 8000, 9000, Colors.Black);

            // draw a small ellipse
            bmp.FillEllipse(0, 0, 20, 40, Colors.Green);

            // draw a medium ellipse
            bmp.FillEllipse(0, 0, 200, 800, Colors.Yellow);

            // draw a large ellipse
            bmp.FillEllipse(0, 0, 1000, 5000, Colors.Red);

            mainImage.Source = bmp;
            myScrollViewer.HorizontalScrollBarVisibility = ScrollBarVisibility.Visible;
            myScrollViewer.HorizontalScrollBarVisibility = ScrollBarVisibility.Visible;
        }
    }
}

Am I doing something wrong, or is this a bug? Does anyone know of any workarounds?

Coordinator
Jan 28, 2013 at 11:46 AM

What platform are you using?

Can you provide a full repro solution?

Jan 28, 2013 at 3:09 PM

Windows 7 x64 Service Pack 1

Visual Studio 2012 Professional

 

I zipped-up my example solution, not sure how to go about giving it to you.

Coordinator
Jan 28, 2013 at 3:32 PM

I actually mean dev platform. It looks like WPF, right?

Upload it to SkyDrive, DropBox  or any file sharing site you like. 

Jan 28, 2013 at 5:05 PM

Yes, it's a WPF project.

https://www.dropbox.com/s/zk1u6gl2iw8mse1/EllipseTest.zip

Coordinator
Jan 28, 2013 at 5:47 PM

OK, thanks, so it's like I supposed simply an overflow of the 32bit integer. WBX uses some int32 bit twiddling to get best performance and this can of course lead to an overflow. Using such shape sizes like yours is quite rare and I can't remember a single time someone raised such an issue before here during the last 4 years. That'S why I won't change the base code of the library to int64 but you can modify the source code of WBX yourself and use your custom version of it.

Here's the stuff you need to change in the \trunk\Source\WriteableBitmapEx\WriteableBitmapFillExtensions.cs file

 

      public static void FillEllipseCentered(this WriteableBitmap bmp, int xc, int yc, int xr, int yr, int color)
      {
         // Use refs for faster access (really important!) speeds up a lot!
         using (var context = bmp.GetBitmapContext())
         {
            var pixels = context.Pixels;
            int w = context.Width;
            int h = context.Height;

            // Avoid endless loop
            if (xr < 1 || yr < 1)
            {
               return;
            }

            // Init vars
            int uh, lh, uy, ly, lx, rx;
            var x = xr;
            var y = 0;
            long xrSqTwo = (xr * xr) << 1;
            long yrSqTwo = (yr * yr) << 1;
            long xChg = yr * yr * (1L - (xr * 2L));
            long yChg = xr * xr;
            long err = 0;
            long xStopping = yrSqTwo * xr;
            long yStopping = 0;

 

As you can see actually only the variable definitions were changed to long aka int64 and the consts in that one formula.
I verified that this mod works with your sample.

- Rene

Jan 28, 2013 at 6:27 PM
teichgraf wrote:

Using such shape sizes like yours is quite rare and I can't remember a single time someone raised such an issue before here during the last 4 years. That's why I won't change the base code of the library to int64 but you can modify the source code of WBX yourself and use your custom version of it.

Yeah, I searched everywhere and couldn't find anything related to this problem!

Thanks for helping so quickly! I have built and tested the revised writeableBitmapEx.Wpf.dll and it works perfectly. Great job on the library, btw. It's been a lifesaver. Also, your support has been top-notch.

 


Attention, people from the future! Your answer is in this thread, and the following keywords should help you find your way:

WPF WriteableBitmap WriteableBitmapEx FillEllipse FillEllipseCentered DrawEllipse DrawEllipseCentered ellipse not drawing correctly broken too big pixels solved fixed

Feb 10, 2014 at 8:02 AM
I would argue that this fix should be in the official release. Does it have a negative impact on performance?

Drawing large ellipses is not that uncommon nowadays.