Расположение элементов управления по кругу - PullRequest
0 голосов
/ 25 июня 2018

Я пытаюсь распределить панели (в моем примере 9) по кругу, который я нарисовал.

Я использую c # winforms.

Я перепробовал много вариантов моего кода, но я не понимаю, чего хочу, и начал путаться.

В конце концов я хочу что-то вроде этого: Manually spread panels

Я не совсем уверен, как расположить центр моих панелей в соответствующих точках на окружности, используя углы.Вот мой код:

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

    }
}

1 Ответ

0 голосов
/ 25 июня 2018

Имея r в качестве радиуса круга с центром (0,0) в декартовой системе координат, мы можем вычислить координату окружности на основе угла:

  • 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 / количество) в качестве шага к углам.

enter image description here

Пример

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);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...