圆内的随机点
Random points inside a circle
所以我在 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
感谢帮助!
在给定半径的圆内生成一组随机点...
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;
}
}
您可以通过为每个点选择随机半径和角度来实现。
为了避免将角度分量明显量化为径向辐条,我使用 (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 个点:
这将按照您的计划进行。但是请注意,仅当您确实需要它来平衡非常几个点时,才需要四个象限之间的对称性。对于更大的数字,没有必要,您可以将代码减少到一半左右..!
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);
}
}
这是结果。圆点均匀分布在整个圆圈上,不在中间聚集:
直接代码,无象限;
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);
}
问题是在 C# 中,^
是逻辑异或运算符。您需要改用 Math.Pow。所以...
if (Math.Sqrt(Math.Pow(250 - KegelX[i], 2) + Math.Pow(KegelY[i] - 250, 2)) < 200)
等等。
所以我在 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
感谢帮助!
在给定半径的圆内生成一组随机点...
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;
}
}
您可以通过为每个点选择随机半径和角度来实现。
为了避免将角度分量明显量化为径向辐条,我使用 (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 个点:
这将按照您的计划进行。但是请注意,仅当您确实需要它来平衡非常几个点时,才需要四个象限之间的对称性。对于更大的数字,没有必要,您可以将代码减少到一半左右..!
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);
}
}
这是结果。圆点均匀分布在整个圆圈上,不在中间聚集:
直接代码,无象限;
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);
}
问题是在 C# 中,^
是逻辑异或运算符。您需要改用 Math.Pow。所以...
if (Math.Sqrt(Math.Pow(250 - KegelX[i], 2) + Math.Pow(KegelY[i] - 250, 2)) < 200)
等等。