一个圆内随机点(Random points inside a circle)

2019-10-22 06:55发布

所以我就在Windows一圈窗体应用程序,并在上面放置20个随机点在这个圈子里。 我的想法是圆分成4个部分,使其更加平衡。 我的问题是,点都围在中间产生的,我不知道如何解决这一问题?

    Graphics g;
    Pen p;
    Random r = new Random();
    int[] KegelX = new int[20];
    int[] KegelY = new int[20];
    private void Form1_Load(object sender, EventArgs e)
    {

    }

    private void button1_Click(object sender, EventArgs e)
    {
        Kegelplatzierung();
        p = new Pen(Color.Black);
        g = this.CreateGraphics();
        g.DrawEllipse(p, new Rectangle(50, 50, 400, 400));
        for (int i = 0; i < 20; i++)
        {
            g.DrawEllipse(p, new Rectangle(KegelX[i], KegelY[i], 1, 1));
        }
        p.Dispose();
        g.Dispose();
    }

    private void Kegelplatzierung() {
        for (int i = 0; i < 5; i++)
        {
            bool Kriterium = false;
            while (!Kriterium)
            {
                KegelX[i] = r.Next(50, 250);
                KegelY[i] = r.Next(50, 250);
                if (Math.Sqrt((250 - KegelX[i]) ^ 2 + (KegelY[i] - 250) ^ 2) < 200)
                {
                    Kriterium = true;
                }
            }
        }
        for (int i = 5; i < 10; i++)
        {
            bool Kriterium = false;
            while (!Kriterium)
            {
                KegelX[i] = r.Next(250, 450);
                KegelY[i] = r.Next(50, 250);
                if (Math.Sqrt((KegelX[i] - 250) ^ 2 + (KegelY[i] - 250) ^ 2) < 200)
                {
                    Kriterium = true;
                }
            }
        }
        for (int i = 10; i < 15; i++)
        {
            bool Kriterium = false;
            while (!Kriterium)
            {
                KegelX[i] = r.Next(50, 250);
                KegelY[i] = r.Next(250, 450);
                if (Math.Sqrt((250 - KegelX[i]) ^ 2 + (250 - KegelY[i]) ^ 2) < 200)
                {
                    Kriterium = true;
                }
            }
        }
        for (int i = 15; i < 20; i++)
        {
            bool Kriterium = false;
            while (!Kriterium)
            {
                KegelX[i] = r.Next(250, 450);
                KegelY[i] = r.Next(250, 450);
                if (Math.Sqrt((KegelX[i] - 250) ^ 2 + (250 - KegelY[i]) ^ 2) < 200)
                {
                    Kriterium = true;
                }
            }
        }

    }

例子: http://puu.sh/gB6Dg/e81f8c3486.png http://puu.sh/gB6Ec/306f61424c.png

感谢帮助!

Answer 1:

问题是,在C#中, ^是逻辑XOR运算符。 您需要使用Math.Pow代替。 所以...

if (Math.Sqrt(Math.Pow(250 - KegelX[i], 2) + Math.Pow(KegelY[i] - 250, 2)) < 200)

等等。



Answer 2:

生成一个给定半径的圆内随机点集的...

 private void button1_Click(object sender, EventArgs e)
            {
                int radius = 100;
                var p = new Pen(Color.Black);
                var g = this.CreateGraphics();
                g.DrawEllipse(p, 0,0,radius*2, radius*2);
                var pointGen = new RandomPointGenerator();
                var randomPoints = pointGen.GetPointsInACircle(radius, 20);
                p.Color = Color.Red;
                foreach (var point in randomPoints)
                {

                    g.DrawEllipse(p, point.X + radius, point.Y+radius, 2, 2);
                }
            }



public class RandomPointGenerator
    {
        private Random _randy = new Random();
        public List<Point> GetPointsInACircle(int radius, int numberOfPoints)
        {
            List<Point> points = new List<Point>();
            for (int pointIndex = 0; pointIndex < numberOfPoints; pointIndex++)
            {
                int distance = _randy.Next(radius);
                double angleInRadians = _randy.Next(360)/(2 * Math.PI) ;

                int x = (int)(distance * Math.Cos(angleInRadians));
                int y = (int)(distance * Math.Sin(angleInRadians));
                Point randomPoint = new Point(x, y);
                points.Add(randomPoint);
            }
            return points;
        }
    }


Answer 3:

您可以选择每个点的随机半径和角度做到这一点。

为了避免角度分量的显量化成径向辐条,我使用(double)rand.Next() / int.MaxValue得到一个随机数0和1之间,并乘上2π。

为了避免点被揉成附近的圆的中心,我用克里斯A.公式(在生成的圆内的随机点(均匀地) ),以产生半径:

Random rand = new Random();

private List<Point> GetRandomPoints(double rMax, int nPoints)
{
    var randPoints = new List<Point>();
    for (int i = 0; i < nPoints; i++)
    {
        var r = Math.Sqrt((double)rand.Next() / int.MaxValue) * rMax;
        var theta = (double)rand.Next() / int.MaxValue * 2 * Math.PI;
        randPoints.Add(new Point((int)(r * Math.Cos(theta)), (int)(r * Math.Sin(theta))));
    }
    return randPoints;
}

private void button1_Click(object sender, EventArgs e)
{
    using (Graphics g = this.CreateGraphics())
    {
        using (Pen p = new Pen(Color.Black))
        {
            var left = 50;
            var top = 50;
            var r = 200;
            g.DrawEllipse(p, new Rectangle(left, top, r * 2, r * 2));

            int nPoints = 20;
            var randomPoints = GetRandomPoints(r - 1, nPoints);

            for (int i = 0; i < nPoints; i++)
            {
                g.DrawEllipse(p, new Rectangle(randomPoints[i].X + left + r, randomPoints[i].Y + top + r, 1, 1));
            }
        }
    }
}

为了确保物品设置的清洁,可以使用using构造-它确保你不小心忘了。

它通常是更好的东西,如圆的半径分配给一个变量,那么你可以很容易地在一个地方改变它,它使得代码更容易,如果你使用有意义的变量名阅读。

下面是输出的一个例子,但与半径设定为100,并生成200点:



Answer 4:

这将做到这一点,你计划好了。 但是请注意,四个象限之间的对称性,只需要,如果你真的需要它来平衡非常点。 对于更大的数字没有必要,你可以将代码缩减至约一半的线..!

private void panel2_Paint(object sender, PaintEventArgs e)
{
    int dotsPerQuadrant = 666;
    Random R = new Random();
    Size s1x1 = new System.Drawing.Size(2, 2);
    int radius = 200;
    int rad2 = radius / 2;
    int off = 20;
    Rectangle bounds = new Rectangle(off, off, radius, radius);
    GraphicsPath gp = new GraphicsPath();
    gp.AddEllipse(bounds);
    Rectangle rectQ1 = new Rectangle(off, off, rad2, rad2);
    Rectangle rectQ2 = new Rectangle(off + rad2, off, rad2, rad2);
    Rectangle rectQ3 = new Rectangle(off, off + rad2, rad2, rad2);
    Rectangle rectQ4 = new Rectangle(off + rad2, off + rad2, rad2, rad2);
    List<Rectangle> quadrants = new List<Rectangle> { rectQ1, rectQ2, rectQ3, rectQ4 };
    e.Graphics.Clear(Color.AntiqueWhite);
    e.Graphics.DrawEllipse(Pens.Black, bounds);

    foreach (Rectangle rect in quadrants)
    {
        int count = 0;
        do
        {
            Point p = new Point(rect.X + R.Next(rad2), rect.Y + R.Next(rad2));
            if (gp.IsVisible(p))
            {
                e.Graphics.FillEllipse(Brushes.Red, new Rectangle(p, s1x1));
                count++;
            }
        } while (count < dotsPerQuadrant);
    }

}

下面是结果。 遍布均匀圆整的点, 而不是群集在中间

直接代码,SANS象限;

private void panel2_Paint(object sender, PaintEventArgs e)
{
    int dotstoDraw = 666*4;
    Random R = new Random();
    Size s1x1 = new System.Drawing.Size(2, 2);
    int radius = 200;
    int off = 20;
    Rectangle bounds = new Rectangle(off, off, radius, radius);
    GraphicsPath gp = new GraphicsPath();
    gp.AddEllipse(bounds);

    e.Graphics.Clear(Color.AntiqueWhite);
    e.Graphics.DrawEllipse(Pens.Black, bounds);

    int count = 0;
    do
    {
        Point p = new Point(off + R.Next(radius), off + R.Next(radius));
        if (gp.IsVisible(p))
        {
            e.Graphics.FillEllipse(Brushes.Red, new Rectangle(p, s1x1));
            count++;
        }
    } while (count < dotstoDraw);
 }


文章来源: Random points inside a circle