我试图将面板(在本例中为9个)散布在我绘制的圆上。
我正在使用c#winforms。
我已经尝试了许多代码变体,但是没有得到想要的东西,开始感到困惑。
最终我想要这样的东西:
我不确定如何使用角度将面板的中心放在圆上的相应点上。 这是我的代码:
public partial class Form1 : Form
{
List<Panel> plist = new List<Panel>();
Rectangle circ_rect = new Rectangle();
const int Num_Screens = 9;
const int margin = 15;
public Form1()
{
InitializeComponent();
WindowState = FormWindowState.Maximized;
}
private void Generate_Panels()
{
for (int i = 0; i < 9; i++)
{
Panel p = new Panel();
p.BackColor = Color.LightSkyBlue;
p.Size = new Size(250, 150);
p.BorderStyle = BorderStyle.FixedSingle;
p.Name = "panel_" + ((i + 1).ToString());
plist.Add(p);
}
}
private void Generate_Circle()
{
//Create panels
Generate_Panels();
//Set circle coord
Point circ_center = new Point(Width / 2, Height / 2);
Size circ_Size = new Size(Height - margin, Height - margin);
circ_center = new Point((circ_center.X - (circ_Size.Width / 2)),
(circ_center.Y - (circ_Size.Height / 2)));
circ_rect = new Rectangle(circ_center, circ_Size);
float radius = circ_Size.Width / 2;
float angle = 0.0f;
Point loc = Point.Empty;
Point rect_center = Point.Empty;
for (int i = 0; i < plist.Count; i++)
{
rect_center = new Point((plist[i].Width / 2), (plist[i].Height / 2));
angle = 360 * ((i + 1f) / 9);
loc.X = (int)(radius * Math.Cos(angle * Math.PI / 180)) + circ_center.X;
loc.Y = (int)(radius * Math.Sin(angle * Math.PI / 180)) + circ_center.Y;
plist[i].Location = new Point(loc.X - (plist[i].Width / 2) + circ_rect.X,
loc.Y - (plist[i].Height / 2) + circ_rect.Y);
this.Controls.Add(plist[i]);
}
}
private void Form1_Paint(object sender, PaintEventArgs e)
{
e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
e.Graphics.DrawEllipse(Pens.Red, circ_rect);
}
private void Form1_Load(object sender, EventArgs e)
{
Generate_Circle();
}
}
答案 0 :(得分:0)
在直角坐标系中,以r
作为中心为(0,0)
的圆的半径,我们可以根据角度计算圆上a的坐标:
x = r * cos(degree)
和y = r * sin(degree)
在C#Sin
和Cos
方法中,接受弧度,因此我们应使用以下公式将度转换为弧度。
radians = Math.PI * degree / 180.0
下一步是将笛卡尔坐标系值转换为形式坐标值:
panel.X = x + center.X - panel.Width/2
panel.Y = center.Y - y - panel.Height/2
下一步是计算角度。您可以手动设置角度,也可以通过将角度设置为起始角度(如90)并向该角度添加一个值(如40、360 / count)作为步长来计算角度。
示例
public partial class Form1 : Form {
Rectangle circle;
List<Panel> panels;
List<int> angles;
public Form1() {
InitializeComponent();
ResizeRedraw = true;
angles = Enumerable.Range(0, 9).Select(x => 90 + x * 40).ToList();
panels = Enumerable.Range(0, 9).Select(x => new Panel() {
Size = new Size(100, 40),
BackColor = Color.LightSkyBlue
}).ToList();
this.Controls.AddRange(panels.ToArray());
}
protected override void OnLayout(LayoutEventArgs levent) {
base.OnLayout(levent);
int padding = 50;
int radius = Math.Min(ClientSize.Width, ClientSize.Height) / 2 - padding;
Point center = new Point(ClientSize.Width / 2, ClientSize.Height / 2);
circle = new Rectangle(center.X - radius, center.Y - radius,
2 * radius, 2 * radius);
for (int i = 0; i < 9; i++) {
var x = (int)(radius * Math.Cos(Math.PI * angles[i] / 180.0)) + center.X;
var y = center.Y - (int)(radius * Math.Sin(Math.PI * angles[i] / 180.0));
panels[i].Left = x - (panels[i].Width / 2);
panels[i].Top = y - (panels[i].Height / 2);
}
}
protected override void OnPaint(PaintEventArgs e) {
base.OnPaint(e);
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
e.Graphics.DrawEllipse(Pens.Red, circle);
}
}