日期:2014-05-18  浏览次数:20946 次

c# 绘图板中的旋转问题
程序基本功能如下:
1、实现直线、矩形、圆形、文字的绘制
2、实现元素选择、移动
3、元素放大、缩小、旋转
思路是有元素抽象父类,然后每种元素(圆形、直线、文字等)继承父类,绘图页面有图形列表List,比如会直线,就在列表里加入直线对象,然后在pCanvs的paint事件里进行遍历、绘制list列表中的所有元素。

遇到的问题是:元素的旋转没有很好的实现思路,目前有的思路是在元素类里加入变换函数,在paint事件里绘制元素时同时执行旋转操作。但是该方法实现的时候没成功,问题没找出来,而且个人觉得该方法不是很好,想问下达人有没有直接改变坐标系的方法,其实我最终要实现的效果是把pCanvs上的所有元素都同时旋转指定的角度,求达人帮忙,提供思路,有代码的更好,谢谢

------解决方案--------------------
如果旋转的角度以及中心都能确定,则可以
1、平移到旋转中心后
2、再旋转
3、平移回去

比如下面的例子(注意每个对象在自己的坐标系内绘画):
C# code

public Form1()
{
    InitializeComponent();
    this.DoubleBuffered = true;
    shapes.Add(new Rect() { Location = new Point(100, 100), Size = new Size(50, 30) });
    shapes.Add(new Rect() { Location = new Point(220, 200), Size = new Size(20, 40) });

    Random random = new Random();
    timer.Tick += delegate
    {
        foreach (Shape shape in this.shapes)
        {
            shape.RotateAngle += random.Next(10);
            this.Invalidate();
        }
    };
}

System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer() { Enabled = true, Interval = 100 };
List<Shape> shapes = new List<Shape>();
protected override void OnPaint(PaintEventArgs e)
{
    foreach (Shape shape in shapes)
    {
        e.Graphics.TranslateTransform(shape.Location.X, shape.Location.Y);
        shape.DrawTo(e.Graphics);
        e.Graphics.ResetTransform();
    }
}

public abstract class Shape
{
    public abstract void  DrawTo(Graphics g);
    public float RotateAngle { get; set; }
    public Point Location { get; set; }
}

public class Rect : Shape
{
    public Size Size { get; set; }
    public override void DrawTo(Graphics g)
    {
        PointF center = new PointF(Size.Width / 2.0f, Size.Height / 2.0f);
        g.TranslateTransform(center.X, center.Y);    //<--1
        g.RotateTransform(RotateAngle);              //<--2
        g.TranslateTransform(-center.X, -center.Y);  //<--3

        g.FillRectangle(Brushes.PeachPuff, new Rectangle(Point.Empty, Size));
    } 
}