C# Graphics Programming笔记(五)

第五章    使用变换

Graphics类的Transformation方法提供了变换。主要的变换方法有TranslateTransformScaleTransformRotateTransform,分别实现平移、缩放和旋转。

平移变换

private void Form1_Paint(object sender, PaintEventArgs e)

{

    Graphics gr = e.Graphics;

    Pen p = new Pen(Color.Red, 5);

    Rectangle rect = new Rectangle(0, 0, 200, 150);

    gr.DrawRectangle(p, rect);

    gr.TranslateTransform(150, 50);

    p.Color = Color.Blue;

    gr.DrawRectangle(p, rect);

    gr.Dispose();

    p.Dispose();

}

C Graphics Programming笔记(五) - Castor - 趁年轻,多折腾~~

 缩放变换

//下面的函数使用形参gr-1 <= x <= 1, -1 <= y <= 1内绘制一个笑脸

private void DrawSmiley(Graphics gr)

{

    using (Pen thin_pen = new Pen(Color.Blue, 0))

    {

        gr.FillEllipse(Brushes.Yellow, -1, -1, 2, 2);

        gr.DrawEllipse(thin_pen, -1, -1, 2, 2);

        gr.DrawArc(thin_pen, -0.75f, -0.75f, 1.5f, 1.5f, 0, 180);

        gr.FillEllipse(Brushes.Red, -0.2f, -0.2f, 0.4f, 0.6F);

        gr.FillEllipse(Brushes.White, -0.5f, -0.6f, 0.3f, 0.5F);

        gr.DrawEllipse(thin_pen, -0.5f, -0.6f, 0.3f, 0.5F);

        gr.FillEllipse(Brushes.Black, -0.4f, -0.5f, 0.2f, 0.3F);

        gr.FillEllipse(Brushes.White, 0.2f, -0.6f, 0.3f, 0.5F);

        gr.DrawEllipse(thin_pen, 0.2f, -0.6f, 0.3f, 0.5F);

        gr.FillEllipse(Brushes.Black, 0.3f, -0.5f, 0.2f, 0.3F);

    }

}

 

private void Form1_Paint(object sender, PaintEventArgs e)

{

    e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;

    // Draw 50x50 pixels.

    e.Graphics.ScaleTransform(50, 50);

    e.Graphics.TranslateTransform(60, 60, MatrixOrder.Append);

    DrawSmiley(e.Graphics);

    e.Graphics.ResetTransform();

}

效果如下:

C Graphics Programming笔记(五) - Castor - 趁年轻,多折腾~~

 先将其放大了50倍,然后平移过来,最后重设变换。

 旋转变换

private void Form1_Paint(object sender, PaintEventArgs e)

{

    e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;

    e.Graphics.TranslateTransform(150, 150);

    Rectangle rect=new Rectangle(0,0,100,100);

    for (int i = 0; i < 36; i++)

    {

        e.Graphics.RotateTransform(10);

        e.Graphics.DrawArc(Pens.Blue, rect, 0, 360);

    }

    e.Graphics.ResetTransform();

}

C Graphics Programming笔记(五) - Castor - 趁年轻,多折腾~~

 注意变换是一个累积过程。如果进行一下组合,将会有许多奇妙的图形出现,下图是在旋转后添加了一个语句:e.Graphics.ScaleTransform(1.1f, 0.9f);

C Graphics Programming笔记(五) - Castor - 趁年轻,多折腾~~

 如果是在前面添加:

C Graphics Programming笔记(五) - Castor - 趁年轻,多折腾~~

 可以发现效果是不一样的。所以,顺序很重要。

世界坐标系的映射

将世界坐标系映射到设备坐标系(图形对象)上去。这样画图将会简单多了。

C Graphics Programming笔记(五) - Castor - 趁年轻,多折腾~~

 下面的方法将实现世界坐标系到设备坐标系的矩形映射。

private void MapRectangles(Graphics gr, RectangleF WorldRect, RectangleF DeviceRect)

{

    PointF[] DevicePoints=new PointF[3];

    //三点分别是设备坐标系的左上、右上和左下

    DevicePoints[0] = new PointF(DeviceRect.Left, DeviceRect.Top);

    DevicePoints[1] = new PointF(DeviceRect.Left + DeviceRect.Width, DeviceRect.Top);

    DevicePoints[2] = new PointF(DeviceRect.Left, DeviceRect.Top + DeviceRect.Height);

    //映射矩形到点

    gr.Transform = new Matrix(WorldRect, DevicePoints);

}

然后是绘制数据的窗口:

private void Form1_Paint(object sender, PaintEventArgs e)

{

    e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;

 

    const int MIN_YEAR = 1990;

    const int MAX_YEAR = 2001;

    const int MIN_SALES = 0;

    const int MAX_SALES = 30000000;

    MapRectangles(e.Graphics, new RectangleF(MIN_YEAR,MIN_SALES,MAX_YEAR-MIN_YEAR,MAX_SALES-MIN_SALES), this.ClientRectangle);

    // 数据

    Point[] sales_data = {

        new Point(1990, 4000000),

        new Point(1991, 3000000),

        new Point(1992, 5000000),

        new Point(1993, 10000000),

        new Point(1994, 9000000),

        new Point(1995, 14000000),

        new Point(1996, 19000000),

        new Point(1997, 18000000),

        new Point(1998, 22000000),

        new Point(1999, 27000000),

        new Point(2000, 30000000)};

    using (Pen thin_pen = new Pen(Color.Green, 0))

    {

        foreach (Point pt in sales_data)

        {

            e.Graphics.FillRectangle(Brushes.PaleGreen, pt.X, 0, 1, pt.Y);

            e.Graphics.DrawRectangle(thin_pen, pt.X, 0, 1, pt.Y);

        }

        //画连线

        e.Graphics.TranslateTransform(0.5f, 0f, MatrixOrder.Prepend);

        thin_pen.Color = Color.Red;

        e.Graphics.DrawLines(thin_pen, sales_data);

    }

}

效果如下:

C Graphics Programming笔记(五) - Castor - 趁年轻,多折腾~~

 现在的问题是,图形画反了,如果能够将上下倒过来就OK了,可以修改一下MapRectangles方法中的映射点:

DevicePoints[0] = new PointF(DeviceRect.Left, DeviceRect.Top + DeviceRect.Height);

DevicePoints[1] = new PointF(DeviceRect.Left + DeviceRect.Width, DeviceRect.Top + DeviceRect.Height);

DevicePoints[2] = new PointF(DeviceRect.Left, DeviceRect.Top);

再运行一下:

C Graphics Programming笔记(五) - Castor - 趁年轻,多折腾~~

另外,可以实现垂直翻转和水平翻转的功能。

private void VerticalFilp(Graphics gr,Rectangle rect)

{

    PointF[] PArr = new PointF[3];

    PArr[0] = new PointF(rect.Left, rect.Top + rect.Height);

    PArr[1] = new PointF(rect.Left + rect.Width, rect.Top + rect.Height);

    PArr[2] = new PointF(rect.Left, rect.Top);

    gr.Transform = new Matrix(rect, PArr);

}

private void Form1_Paint(object sender, PaintEventArgs e)

{

    Pen p = new Pen(Color.BlueViolet,5f);

    Point[] ps = new Point[4];

    ps[0] = new Point(0, 0);

    ps[1] = new Point(100, 0);

    ps[2] = new Point(0, 100);

    ps[3] = new Point(100, 100);

    e.Graphics.DrawLines(p, ps);

    VerticalFilp(e.Graphics,new Rectangle(0,0,100,100));

    e.Graphics.TranslateTransform(150, 0, MatrixOrder.Append);

    e.Graphics.DrawLines(p,ps);

}

这将输出垂直翻转的Z

C Graphics Programming笔记(五) - Castor - 趁年轻,多折腾~~

 变换也可运用到文字和图片上。

This Wrox Blox teaches you how to add graphics to C# 2008 applications, explaining fundamental graphics techniques such as: drawing shapes with different colors and line styles; filling areas with colors, gradients, and patterns; drawing text that is properly aligned, sized, and clipped exactly where you want it; manipulating images and saving results in bitmap, JPEG, and other types of files. Also covered are instructions for how to greatly increase your graphics capabilities using transformations. Transformations allow you to move, stretch, or rotate graphics. They also let you work in coordinate systems that make sense for your application. You will also learn how to use all of these techniques in printouts. The author describes the sequence of events that produce a printout and shows how to generate and preview printouts. The final sections describe two powerful new graphic tools that were introduced with .NET Framework 3.0: WPF graphics and FlowDocuments. WPF applications can use XAML graphic commands to declaratively draw and fill the same kinds of shapes that a program can draw by using graphics objects. Finally, a discussion on the FlowDocument object shows you how to define items that should be flowed across multiple pages as space permits. This lets you display text, graphics, controls, and other items that automatically flow across page breaks. FlowDocument viewers make displaying these documents easy for you, and simplifies the user's reading of the documents. This Wrox Blox also contains 35 example programs written in C# 2008, although most of the code works in previous versions of C# as well. The most notable exceptions are WPF graphics and FlowDocuments, both of which require WPF provided in .NET Framework 3.0 and later.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值