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

标签 c# algorithm graphics fractals

我正在研究希尔伯特曲线,我无法旋转整个图形,只能旋转较低的矩形(查看屏幕截图,在第三步和后续步骤中我遇到了问题)

first 3 steps

我有一个 Figure 类。我用它来存储每个图形并从上一个图形构建下一个图形。这是我的代码

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

这里我用我的递归方法画图

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

我尝试围绕图形中心旋转点并使用下一个代码,但旋转不正确

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;
    }       

最佳答案

问题是您在计算旋转后的 Y 坐标时使用的是已经旋转过的 X 坐标。使用临时变量来避免这种情况:

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;
}  

关于c# - 如何从点(希尔伯特曲线)旋转图形?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40083675/

相关文章:

javascript 扫雷器 floodfill 算法无法正常工作

opengl - 确定内存中已编译着色器的大小

c++ - 朗伯阴影和阴影(光线追踪)的问题

c# - 如何在 Windows 中获取 z 顺序?

c# - 异常过滤器触发 CA2202?

c# - 使用适用于所有继承对象的方法为基类型创建集合?

c# - 我如何正确地将数据从 wordpress mySQL DB 解析为 xamarin forms c#?

ios - 如何运行数据长度不是 2 的幂的 Apple Accelerate fft 算法?

python - 平均脸-算法

c# - 在 C# 中制作小行星游戏