2016-12-23 65 views
-1

该方法是在一个新的类和我用它从Form1中: 在新类的顶部:有没有什么办法让创建特定大小点的方法更快?

public int numberOfPoints = 100; 

类Init方法:

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

然后,该方法:

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; 
     } 

而且在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(); 
     } 

当我将form1中的点数设置为10时,例如它将快速运行该方法并快速返回10点的bmp。 但是,如果我在form1中将点数设置为20,则需要大约3-5秒。 如果我在form1中将其设置为50分,则需要几分钟的时间。

  1. 什么应该是可以设置的限制最大值点?图像的大小是512,512。所以这是合乎逻辑的,我将能够填充所有图像的点,这是512 * 512 = 262144逻辑我的意思是用户。用户可以设置点的数量和大小。在这个例子中,它是每个点的半径的1.0倍。

  2. 我该如何使GetBitmapWithEllipses方法更快地创建点?

+1

“我该如何改进我的代码?”这些类型的问题更适合[Code Review Stack Exchange](http://codereview.stackexchange.com/)。 StackOverflow更多的是让代码工作的问题。 – Abion47

+0

所以你想要生成半径为'radius'的'numberOfPoints'非重叠圆? –

+0

@ Abion47不一定。如果有一个关于改进用于解决问题的算法的具体问题,它可能是SO的主题。问题在于改进算法,而不仅仅是提高代码质量。 –

回答

0

这是它是如何工作的^^哦,你正在创造比你想我想的更多。 如果你输入10它将创建100.如果你输入4你得到16. numberof points * numberofpoints

无论如何这里是你想我想的(如果你想要输入点的确切数目,删除一个循环)^^

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

     using (Graphics g = Graphics.FromImage(bmp)) 
     { 
      g.Clear(Color.Black); 
      g.SmoothingMode = SmoothingMode.AntiAlias; 
      List<RectangleF> rects = new List<RectangleF>(); 
      rects.Add(new RectangleF(0, 0, 0, 0)); 

      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)); 

        PointF p = new PointF(r.Next(Width), r.Next(Height)); 
        RectangleF rect = new RectangleF(p, new SizeF(radius * 2, radius * 2)); 

        if (!rects.Any(tmp => tmp.IntersectsWith(rect))) 
        { 
         rects.Add(rect); 
         g.FillEllipse(new SolidBrush(c), rect); 
        } 
        else 
        { 
         y--; 
        } 
       } 
      } 
     } 

     return bmp; 
    } 
+0

当我改变每个点的半径大小,如果我将其更改为2.0f bmpWithPoints = GetBitmapWithEllipses(2.0f);或1.0f它将工作得很快。但是,如果我将其更改为4.0f,则需要一些时间,如果将其更改为6.0f或10.f,则需要很长时间才能在几分钟内完成。改变尺寸时,有没有办法让它更快速地运行?如果我把它的大小1.0f和点数50,它的工作速度很快。但是当改变50点的半径时,它会花费很多时间。 –

+0

它不在c#中,但可能有帮助[链接](https://www.youtube.com/watch?v=flQgnCUxHlw&list=PLRqwX-V7Uu6ZiZxtDDRCi6uhfTH4FilpH&index=37)。在描述中链接到代码^^ –

相关问题