2016-07-23 181 views
1

我正在尝试创建程序,其中将在画布上绘制鱼类列表。 (下一步将根据一些计算改变鱼类的位置) 每个鱼都由位图表示(png文件7x12像素与鱼的图片)。

C#旋转(转换)问题

我创建了FormBox,它是PictureBox,它是我的绘图画布。它有大小640x480像素。

在下面的代码是我使用的简化代码(我切断了所有不需要的东西)。我的问题是转矩矩阵,此时只有旋转。

问题类鱼方法来绘制()这里我试图做一个改造的探讨,此刻我设置了旋转的每条鱼30度,但后来每条鱼都会有不同的起始旋转角度。我想对鱼的旋转角度绕其中心旋转的位置进行转换。所以在这种情况下,所有的鱼都应该在一条线上,并且每条鱼的旋转角度(这里是30度)都要旋转。
但他们被放置在diagonale,所以转换搞砸了。 我该如何解决这个问题? 我可能无法正确使用转换。

命名空间使用类

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 

Main类

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方法,但在哪里?我的意思是什么对象?这与我用于在窗体上创建画布(PictureBox)的Grafic g有什么关系? – user1097772

回答

1

您应该使用RotateAt而不是Rotate。旋转方法旋转控制器(原点)左上角周围的鱼,同时RotateAt围绕您指定的点旋转某物。

只需计算每条鱼的中心(X =左+ FishWidth/2,Y =上+ FishHeight/2)并围绕该点旋转。

+0

这解决了旋转,但如果我想做更多的转换?例如缩小?我用它来学习一些东西,有些东西就像移动到原点,做转换,然后移回来或者类似的东西。 – user1097772

+1

移动到原点(使图像的中间点位于0,0),围绕它旋转并移回是我在几个地方看到的一个示例。这是执行旋转的另一种方法,但您使用RotateAt要清晰得多。但是,以正确的顺序进行转换很重要。 [这是一篇很好的文章](https://msdn.microsoft.com/en-us/library/eews39w7(v = vs.110).aspx)。实际上,您仍然可以在MSDN上找到相当多的GDI +相关文章。 – hankide

+0

你知道e.Graphics是如何使用的吗?我发现你必须重写OnPaint方法,但是在什么对象上以及如何使用?这里我使用Draw方法进行绘制,所以它会像Fish类中的OnPaint方法,并且比fish.Invalidate()? – user1097772