2016-10-17 4 views
1

Я работаю над Гильбертом кривого, и я не могу повернуть всю фигуру, только нижний прямоугольник (смотрите на скриншотах, на третьи и последующие шаги у меня есть проблемы)Как повернуть фигуру из точек (кривая Гильберта)?

first 3 steps

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

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

ответ

1

Проблема в том, что вы используете координату X, которую вы уже повернули, когда вы вычисляете повернутую координату Y. Используйте временную переменную, чтобы избежать этого:

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; 
} 
Смежные вопросы