在圆上转录多边形

Alb*_*ure 7 c# algorithm math winforms

我目前正试图在圆圈内刻上十边形的对角线

像这样 在此输入图像描述

在c#中,我的方法是创建一个圆圈

e.Graphics.DrawEllipse(myPen, 0, 0, 100, 100);
Run Code Online (Sandbox Code Playgroud)

并在里面画线

 e.Graphics.DrawLine(myPen, 20, 5, 50, 50);
Run Code Online (Sandbox Code Playgroud)

之后我会绘制一个十边形多边形.

目前我坚持如何将圆分为10个部分/找到圆周上点的正确坐标,因为我的数学不好,我想知道我怎么知道圆的圆周中的下一个点我的圆圈大小如上所示.
而且我也想问一个更好的方法来解决我的问题.

谢谢 :)

das*_*ght 6

解决这个问题的一种方法是使用三角函数sincos.通过他们的所需的角度,以弧度为单位,在一个循环中(需要的倍数2*?/10,即,a = i*?/5i9 0至,包括端点).R*sin(a)会给你原点的垂直偏移量; R*cos(a)会给你水平偏移.

请注意,sincos在从范围-11,所以你会看到正反两方面的结果.您需要为圆的中心添加偏移量,以使点出现在正确的位置.

一旦你产生点的列表,连接点i来点i+1.到达第九个点时,将其连接到初始点以完成多边形.


Idl*_*ind 5

对于粗粒和小腿,这是一个通用的实现,它将X边多边形刻入你传递它的Rectangle中.请注意,在这种方法中,我实际上并没有计算任何绝对点.相反,我正在翻译原点,旋转曲面,并使用固定的长度和角度仅相对于原点绘制线条.这在循环中重复以实现下面的最终结果,并且非常类似于命令Logo中的Turtle :

铭刻多边形

public partial class Form1 : Form
{

    PictureBox pb = new PictureBox();
    NumericUpDown nud = new NumericUpDown();

    public Form1()
    {
        InitializeComponent();

        this.Text = "Inscribed Polygon Demo";

        TableLayoutPanel tlp = new TableLayoutPanel();
        tlp.RowCount = 2;
        tlp.RowStyles.Clear();
        tlp.RowStyles.Add(new RowStyle(SizeType.AutoSize));
        tlp.RowStyles.Add(new RowStyle(SizeType.Percent, 100));
        tlp.ColumnCount = 2;
        tlp.ColumnStyles.Clear();
        tlp.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize));
        tlp.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize));
        tlp.Dock = DockStyle.Fill;
        this.Controls.Add(tlp);

        Label lbl = new Label();
        lbl.Text = "Number of Sides:";
        lbl.TextAlign = ContentAlignment.MiddleRight;
        tlp.Controls.Add(lbl, 0, 0);

        nud.Minimum = 3;
        nud.Maximum = 20;
        nud.AutoSize = true;
        nud.ValueChanged += new EventHandler(nud_ValueChanged);
        tlp.Controls.Add(nud, 1, 0);

        pb.Dock = DockStyle.Fill;
        pb.Paint += new PaintEventHandler(pb_Paint);
        pb.SizeChanged += new EventHandler(pb_SizeChanged);
        tlp.SetColumnSpan(pb, 2);
        tlp.Controls.Add(pb, 0, 1);
    }

    void nud_ValueChanged(object sender, EventArgs e)
    {
        pb.Refresh();
    }

    void pb_SizeChanged(object sender, EventArgs e)
    {
        pb.Refresh();
    }

    void pb_Paint(object sender, PaintEventArgs e)
    {
        // make circle centered and 90% of PictureBox size:
        int Radius = (int)((double)Math.Min(pb.ClientRectangle.Width, pb.ClientRectangle.Height) / (double)2.0 * (double).9);
        Point Center = new Point((int)((double)pb.ClientRectangle.Width / (double)2.0), (int)((double)pb.ClientRectangle.Height / (double)2.0));
        Rectangle rc = new Rectangle(Center, new Size(1, 1));
        rc.Inflate(Radius, Radius);

        InscribePolygon(e.Graphics, rc, (int)nud.Value);
    }

    private void InscribePolygon(Graphics G, Rectangle rc, int numSides)
    {
        if (numSides < 3)
            throw new Exception("Number of sides must be greater than or equal to 3!");

        float Radius = (float)((double)Math.Min(rc.Width, rc.Height) / 2.0);
        PointF Center = new PointF((float)(rc.Location.X + rc.Width / 2.0), (float)(rc.Location.Y + rc.Height / 2.0));
        RectangleF rcF = new RectangleF(Center, new SizeF(1, 1));
        rcF.Inflate(Radius, Radius);
        G.DrawEllipse(Pens.Black, rcF);

        float Sides = (float)numSides;
        float ExteriorAngle = (float)360 / Sides;
        float InteriorAngle = (Sides - (float)2) / Sides * (float)180;
        float SideLength = (float)2 * Radius * (float)Math.Sin(Math.PI / (double)Sides);
        for (int i = 1; i <= Sides; i++)
        {
            G.ResetTransform();
            G.TranslateTransform(Center.X, Center.Y);
            G.RotateTransform((i - 1) * ExteriorAngle);
            G.DrawLine(Pens.Black, new PointF(0, 0), new PointF(0, -Radius));
            G.TranslateTransform(0, -Radius);
            G.RotateTransform(180 - InteriorAngle / 2);
            G.DrawLine(Pens.Black, new PointF(0, 0), new PointF(0, -SideLength));
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

我在常规多边形计算器中得到了侧面长度的公式.