注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

信息 灵感 创新

I? =Information,Inspiration,Innovation

 
 
 

日志

 
 
关于我

we are 5. Mathematics, Computation, Programming, Engineering, and Making fun of life.

网易考拉推荐

C# Graphics Programming笔记(五)  

2011-10-19 09:52:32|  分类: C# & .NET |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

今天终于睡了个懒觉

这本书依旧是红皮书系列的,由Rod Stephens编写,网上有电子版的,使用搜索引擎一下就能找到,不过只有英文版的,好在对英文水平要求不高,过了CET-4绝对可以无障碍阅读。全书分8个章节,从简单的图形对象、画笔、刷子到复杂的位图、图形变换、打印等技术,最后还描述了一个从WPF而来的强有力的对象:FlowDocument,虽然这本书不能做到面面俱到而又深动详实,但全书言简意赅,结构紧凑,从宏观的角度介绍了GDI+编程的原理和方法,是一本不错的GDI+编程入门书籍。

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

第五章    使用变换

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 - 趁年轻,多折腾~~

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

  评论这张
 
阅读(3307)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2016