简体   繁体   English

如何从点(希尔伯特曲线)旋转图形?

[英]How to rotate figure from points(Hilbert curve)?

I am working on Hilbert curve, and I cant rotate the whole figure, just lower rectangle(look at the screenshots, on third and next steps I have a problem)我正在研究希尔伯特曲线,我无法旋转整个图形,只能旋转较低的矩形(看屏幕截图,在第三步和后续步骤中我遇到了问题)

first 3 steps前 3 个步骤

I have a Figure class.我有一个 Figure 课。 I use it to store every figure and build next firuge from previous one.我用它来存储每个图形并从上一个图形构建下一个 firuge。 Here is my code这是我的代码

public class Fragment
{
    public static int PADDING = 50;
    public static float sideLength;

    private readonly Pen crimsonPen = new Pen(Color.Crimson);


    public List<PointF> pointsF = new List<PointF>();
    public PointF[] points;

    public Fragment(int step, Graphics graphics)
    {
        sideLength = Form1.sideLenght;
        points = new PointF[(int)Math.Pow(4, step + 1)];

        if (step.Equals(0))
        {
            points[0] = new PointF(PADDING, PADDING + sideLength);
            points[1] = new PointF(PADDING, PADDING);
            points[2] = new PointF(PADDING + sideLength, PADDING);
            points[3] = new PointF(PADDING + sideLength, PADDING + sideLength);
            graphics.DrawLines(crimsonPen, new[] { points[0], points[1], points[2], points[3] });
        }
        else
        {
            var frag = Form1.fragments[step - 1];
            for (var i = 0; i < step; i++)
            {
                PointF tmpPoint;
                // left lower #1 
                for (int j = frag.points.Length - 1; j >= 0; j--)
                {
                    points[frag.points.Length - 1 - j] = frag.points[j];
                    points[frag.points.Length - 1 - j].Y += sideLength * 2 * (i + 1);
                }

                //rotate left lower #1 
                for (int b = 0; b < Math.Pow(4, step) - 1; b++)
                {
                    tmpPoint = points[0];
                    for (int j = 0; j < frag.points.Length; j++)
                    {
                        if (j.Equals(frag.points.Length - 1))
                        {
                            points[j] = tmpPoint;
                        }
                        else
                        {
                            points[j] = points[j + 1];
                        }
                    }
                }

                // left upper #2
                for (int j = 0; j < frag.points.Length; j++)
                {
                    points[j + frag.points.Length] = frag.points[j];
                }

                // right upper #3
                for (int j = 0; j < frag.points.Length; j++)
                {
                    points[j + 2 * frag.points.Length] = points[j + frag.points.Length];
                    points[j + 2 * frag.points.Length].X += sideLength * 2 * (i + 1);
                }

                //right lower #4
                for (int j = frag.points.Length - 1; j >= 0; j--)
                {
                    points[3 * frag.points.Length + j] = points[2 * frag.points.Length + frag.points.Length - j - 1];
                    points[3 * frag.points.Length + j].Y += sideLength * 2 * (i + 1);
                }
                tmpPoint = points[3 * frag.points.Length];
                //rotate right lower #4
                for (int j = 0; j < frag.points.Length; j++)
                {
                    if (j.Equals(frag.points.Length - 1))
                    {
                        points[4 * (frag.points.Length) - 1] = tmpPoint;
                    }
                    else
                    {
                        points[3 * frag.points.Length + j] = points[3 * frag.points.Length + j + 1];
                    }
                }
            }

            graphics.DrawLines(crimsonPen, points);
        }
    }
}

Here I use my recursive method to draw figures这里我用我的递归方法来绘制图形

private void drawButton_Click(object sender, EventArgs e)
    {
        canvas.Refresh();
        count = 0;
        if (Int32.TryParse(stepsTextBox.Text, out steps))
        {
            sideLenght = (float)((canvas.Width - 100) / (Math.Pow(2, steps) - 1)); 
            fragments = new Fragment[steps];
            drawCurve();
        }
        else
        {
            MessageBox.Show("Wow, incorrect input", "Try again");
        }
    }

    private void drawCurve()
    {
        if (count < steps)
        {
            fragments[count] = new Fragment(count, graphics);
            ++count;
            drawCurve();
        } 
    }

I've tried to rotate points around figure center and use next code but the rotation is incorrect我试图围绕图形中心旋转点并使用下一个代码,但旋转不正确

public PointF rotatePoint(PointF pointToRotate)
    {
        pointToRotate.X = (float)(Math.Cos(180 * Math.PI / 180) * (pointToRotate.X - centerPoint.X) -
                                               Math.Sin(180 * Math.PI / 180) * (pointToRotate.Y - centerPoint.Y) +
                                               centerPoint.X);
        pointToRotate.Y = (float)(Math.Sin(0 * Math.PI / 180) * (pointToRotate.X - centerPoint.X) +
                                               Math.Cos(0 * Math.PI / 180) * (pointToRotate.Y - centerPoint.Y) +
                                               centerPoint.Y);
        return pointToRotate;
    }       

The problem is that you are using the X co-ordinate that you have already rotated when you calculate the rotated Y co-ordinate.问题是您在计算旋转的 Y 坐标时使用的是已经旋转的 X 坐标。 Use a temp variable to avoid this:使用临时变量来避免这种情况:

public PointF rotatePoint(PointF pointToRotate)
{
    float rotatedX = (float)(Math.Cos(180 * Math.PI / 180) * (pointToRotate.X - centerPoint.X) -
                                           Math.Sin(180 * Math.PI / 180) * (pointToRotate.Y - centerPoint.Y) +
                                           centerPoint.X);
    pointToRotate.Y = (float)(Math.Sin(0 * Math.PI / 180) * (pointToRotate.X - centerPoint.X) +
                                           Math.Cos(0 * Math.PI / 180) * (pointToRotate.Y - centerPoint.Y) +
                                           centerPoint.Y);
    pointToRotate.X = rotatedX;
    return pointToRotate;
}  

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM