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.
-
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.
-
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 namedsqrtOfNumberOfPoints
- You work with fully qualified class names instead of importing them, which makes the code harder to read
- The overlapping check takes O(n) time, where n is the number of previous points
- Altogether, your algorithm is O(n4), where n 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
andy
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.