Creating points in specific size [closed]

Posted on

Problem

The method is in a new class and i use it from form1:
In the top of the new class:

public int numberOfPoints = 100;

The class Init method:

public void Init()
{
    if (IsEmpty(bmpWithPoints) == true)
    {
        bmpWithPoints = GetBitmapWithEllipses(1.0f);
    }
}

Then the method:

private Bitmap GetBitmapWithEllipses(float radius)
{
    Bitmap bmp = new Bitmap(512, 512);

    using (Graphics g = Graphics.FromImage(bmp))
    {
        g.Clear(Color.Black);
        g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;

        //store the Ellipses in a GraphicsPath
        using (System.Drawing.Drawing2D.GraphicsPath gP = new System.Drawing.Drawing2D.GraphicsPath())
        {
            for (int x = 0; x < numberOfPoints; x++)
            {
                for (int y = 0; y < numberOfPoints; y++)
                {
                    Color c = Color.FromArgb(
                        r.Next(0, 256),
                        r.Next(0, 256),
                        r.Next(0, 256));

                    using (SolidBrush sb = new SolidBrush(c))
                    {
                        Point pt = new Point(r.Next(bmp.Width), r.Next(bmp.Height));

                        //clone and widen the path to determine, whether the new point overlaps
                        using (System.Drawing.Drawing2D.GraphicsPath gP2 = (System.Drawing.Drawing2D.GraphicsPath)gP.Clone())
                        {
                            using (Pen pen = new Pen(Brushes.White, radius))
                            {
                                gP2.Widen(pen);
                                while (gP2.IsVisible(pt.X, pt.Y) || gP2.IsOutlineVisible(pt, pen))
                                {
                                    pt = new Point(r.Next(bmp.Width), r.Next(bmp.Height));
                                }
                            }
                        }

                        RectangleF rc = new RectangleF(pt.X - radius, pt.Y - radius, radius * 2, radius * 2);
                        g.FillEllipse(sb, rc);
                        gP.StartFigure();
                        gP.AddEllipse(rc);
                        gP.CloseFigure();
                    }
                }
            }
        }
    }

    return bmp;
}

And in Form1:

public Form1()
{
    InitializeComponent();

    textBox1.Text = trackBar1.Maximum.ToString();
    de.pb1 = pictureBox1;

    de.bmpWithPoints = new Bitmap(512, 512);
    de.numberOfPoints = 20;
    de.randomPointsColors = true;
    de.Init();
}

When i set the number of points in form1 to 10 for example it will work fast the method and return the bmp with 10 points fast.
But if i set in form1 the number of points to 20 it will take about 3-5 seconds.
If i set it to 50 points in form1 it will take some minutes.

  1. What should be the limit maximum points to be able to set ? The size of the image is 512, 512. So it’s logical i will be able to fill all the image with points that’s 512*512 = 262144 logical i mean by the user. The user can set the number of points and the size of them. In this example it’s 1.0f the radius of each point.

  2. How can i make it the method GetBitmapWithEllipses to create the points faster ?

Solution

Your code is unclear.

  • You have a variable called numberOfPoints, but you are drawing ellipses
  • You do the ellipse drawing numberOfPoints * numberOfPoints times, therefore the variable should rather be named sqrtOfNumberOfPoints
  • You work with fully qualified class names instead of importing them, which makes the code harder to read
  • The overlapping check takes O(n)O(n) time, where nn is the number of previous points
  • Altogether, your algorithm is O(n4)O(n4), where nn is the numberOfPoints (which, as I said, is not the number of points, but its square root)
  • It’s obvious that running 100*100*100*100 operations takes much longer than 10*10*10*10.
  • You don’t use the variables x and y during the loop. Since these names have a clear meaning in graphics (they are coordinates), you are confusing the human reader. Rename them to more innocent names. And, more importantly, combine them to a single loop.

Leave a Reply

Your email address will not be published. Required fields are marked *