AndrewZ AndrewZ - 1 month ago 11
C# Question

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

I have a Figure class. I use it to store every figure and build next firuge from previous one. 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;
}

Answer

The problem is that you are using the X co-ordinate that you have already rotated when you calculate the rotated Y co-ordinate. 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;
}  
Comments