C# вращение (преобразование) проблема

Я пытаюсь создать программу, где на холсте будет нарисован список рыб. (Следующим шагом будет изменение места рыб на основе некоторых расчетов) Каждая рыба представлена ​​растровым изображением (png-файл 7x12 px с изображением рыбы).

Я создал форму, на которой PictureBox является моим холстом для рисования. Он имеет размер 640x480 пикселей.

Ниже приведен упрощенный код, который я использую (я обрезал все ненужные вещи). Моя проблема с матрицей преобразования, на данный момент только с вращением.

Проблема в классе Fish в методе Draw(), где я пытаюсь сделать трансформацию, в данный момент я устанавливаю поворот на 30 градусов для каждой рыбы, но позже у каждой рыбы будет свой начальный угол поворота. Я хочу сделать трансформацию с тем, где будет поворачиваться рыба на угол поворота вокруг ее центра. Таким образом, в этом случае все рыбы должны быть в одну линию и повернуты на угол поворота (здесь 30 градусов).
Но они расположены по диагонали, поэтому трансформация как-то запутана. Как я могу это исправить? Я, вероятно, неправильно использую преобразование.

Использование пространств имен в классах

using System.Drawing;//Graphics, Point
using System.Drawing.Drawing2D;//Matrix

Рыба

    class Fish {
      public Point position;
      public int rotation;
      public Graphics g;
      public Image fishImage;
      private Rectangle rect;
      private Matrix matrix;

      public Fish(ref Graphics g, int x, int y, int rotation,Image img){
        this.g =  g;
        position = new Point(x,y);
        this.rotation = rotation;
        this.fishImage = img;
        this.rect = new Rectangle(position.X,position.Y, fishImage.Width, fishImage.Height);

      }

   public void Draw() {
    matrix = new Matrix();
    matrix.Rotate((float)rotation, Matrix.Append); //if i comment this it
    //will be drawn in one line
    //according to the initial values for position
    //if i let the rotation here it will be on diagonale
    //i want it on one line but rotated
    g.Transform = matrix;

    rect = new Rectangle(position.X, position.Y, fishImage.Width, fishImage.Height);
    g.DrawImage(fishImage, rect);
   }
}//end Fish class

форма

public partial class Form1 : Form
{
 private Bitmap canvasBitmap; //bitmap for drawing
 private Graphics g;          
 Image fishImage;

 private List<Fish> fishes = new List<Fish>();
  public Form1() {
    InitializeComponent();
   //png image 7x12 pixels 
   fishImage = FishGenetic.Properties.Resources.fishImage; 
   //on Form there is placed PictureBox called canvas
   //so canvas is PictureBox 640x480 px
   canvasBitmap = new Bitmap(canvas.Width, canvas.Height);
   canvas.Image = canvasBitmap;

   //prepare graphics
   g = Graphics.FromImage(canvasBitmap);
   g.SmoothingMode = SmoothingMode.AntiAlias;

   InitFishes();
   DrawFishes();
   canvas.Invalidate(); //invalidate the canvas 

  }//end Form1 constructor     


 private void InitFishes() {

   Fish fish1 = new Fish(ref g, 10, 10, 30, fishImage);
   Fish fish2 = new Fish(ref g, 20, 10, 30, fishImage);
   Fish fish3 = new Fish(ref g, 30, 10, 30, fishImage);
   Fish fish4 = new Fish(ref g, 40, 10, 30, fishImage);
   Fish fish5 = new Fish(ref g, 50, 10, 30, fishImage);
   fishes.Add(fish1);
   fishes.Add(fish2);
   fishes.Add(fish3);
   fishes.Add(fish4);
   fishes.Add(fish5);
 }

private void DrawFishes() {
   foreach(Fish fish in fishes) {
       fish.Draw();
   }
}

}//end Form1 class

Основной класс

static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
    }

1 ответ

Решение

Вы должны использовать RotateAt вместо Rotate. Метод Rotate вращает рыбу вокруг левого верхнего угла элемента управления (origin), в то время как RotateAt вращает что-то вокруг указанной вами точки.

Просто вычислите центр каждой рыбы (X=Left+FishWidth/2, Y=Top+FishHeight/2) и вращайте вокруг этой точки.

Другие вопросы по тегам