圆圈内的随机点

时间:2015-03-15 11:25:36

标签: c# visual-studio pythagorean

所以我在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

感谢您的帮助!

4 个答案:

答案 0 :(得分:2)

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

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

等等。

答案 1 :(得分:1)

在给定半径的圆内生成一组随机点...

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

答案 2 :(得分:1)

您可以通过为每个点选择随机半径和角度来实现此目的。

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

为了避免在圆心附近聚集点,我使用Chris A.的公式(Generate a random point within a circle (uniformly))来生成半径:

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点:

Sample output

答案 3 :(得分:1)

这将按照您的计划进行。但请注意,只有当真正需要它来平衡非常几个点时,才需要四个象限之间的对称性。对于更大的数字,没有必要,你可以将代码减少到大约一半的行..!

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

}

结果如下。点遍布整个圆圈,没有聚集在中间

4x666 random dots

直接代码,没有象限;

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