1

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

C# вращение (трансформация) выпуск

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

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

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

Namespaces с использованием в классах

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

@x ... Но как я могу использовать событие Paint? Его первостепенное значение имеет метод OnPaint, но где? Я имею в виду, на какой объект ??? Как это связано с моей Grafic g, которую я использую для создания холста (PictureBox) в моей форме? – user1097772

ответ

1

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

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

+0

Это разрешает вращение, но если я хочу сделать больше преобразований? например, скрежет? Я использую, чтобы что-то узнать об этом, было что-то вроде перехода к происхождению, выполнения преобразований и возврата назад или чего-то подобного. – user1097772

+1

Перемещение в начало координат (так, что средняя точка изображения равна 0,0), вращаясь вокруг него и двигаясь назад, является примером, который я видел в нескольких местах. Это еще один способ сделать поворот, который вы ищете, но использование RotateAt намного яснее. Однако важно делать преобразования в правильном порядке. [Вот хорошая статья] (https://msdn.microsoft.com/en-us/library/eews39w7 (v = vs.110) .aspx) о них. Вы действительно можете найти довольно много статей, связанных с GDI +, на MSDN. – hankide

+0

Знаете ли вы, как используется e.Graphics? Я обнаружил, что вам нужно переопределить метод OnPaint, но на каком объекте и как это использовать? Здесь я использую метод Draw для рисования, поэтому это будет что-то вроде метода OnPaint в классе Fish, а не fish.Invalidate() ?? – user1097772

Смежные вопросы