Winform GDI+ 绘图

1. 常用结构

1) Point:点坐标
2) Size:大小
3) Rectangle:包括位置与大小

Rectangle.Location:位置坐标

Rectangle.Size:大小

4) Pen:画笔

红色笔:Pens.Red,黑色笔:Pens.Black

其它的一次类推。

5) Brush:画刷

红色画刷:Brushes.Red 黑色画刷:Brushes.Black

其它以此类推。

2. 坐标变换

对象

屏幕坐标转化为客户区坐标

客户区坐标转化为屏幕坐标

Point

PointToClinet(Point pt)

PointToScreen(Point pt)

Rectangle

RectangleToClient

RectangleToScreen

涉及坐标的程序必须先考虑是否需要坐标变换

坐标平移:

X目标=X现在+dx

Y目标=Y现在+dy

坐标缩放:

X目标=X现在*dx

Y目标=Y现在*dy

坐标旋转:

X目标=X现在*Cos(α)+Y现在*Sin(α)

Y目标= X现在*Sin(α)+Y现在*Cos(α)

综合后

clip_image002

引入矩阵

clip_image004

综合后的公式可以写为

clip_image006

clip_image008

clip_image010

坐标变换会因为顺序的不同而产生不同的结果,多次坐标变换的结果是多个矩阵相乘。

clip_image012

clip_image014

clip_image016

clip_image018

clip_image020

clip_image022

右下角矩阵说明

X

Y

隐含列

Sx 缩放因子

Ry旋转因子

0

Rx旋转因子

sy缩放因子

0

Dx平移因子

Dy平移因子

1

clip_image024

图-1 原始矩阵

clip_image026

图-2 x轴平移100个像素

clip_image028

图-3 y轴平移100个像素

clip_image030

图-4 x轴放大1.5倍

clip_image032

图-5 y轴放大1.5倍

clip_image034

图-6 x轴旋转0.5

clip_image036

图-7 y轴旋转0.5

3. 鼠标事件

事件名称

说明

OnMouseUp

鼠标松开

OnMouseDown

鼠标按下

OnMouseMove

鼠标移动

OnMouseEnter

鼠标进入

OnMouseLeave

鼠标离开

OnMouseHover

鼠标停留。Hover事件至多在Enter与Leave之间发生一次

OnMouseCaptureChanged

鼠标捕获变化,捕获发生一次,释放发生一次

4. 常见问题与解决方法

1) 如判断鼠标按下拖动

首先在鼠标的OnMouseMoveMove事件中添加如下判断:

if (e.Button == MouseButtons.Left)

{

//鼠标移动的过程中是否按下了左键

}

2) 如何避免鼠标按住旋转后划线后出现多条痕迹

在OnPaint事件中添加如下代码:

//划线之前先用背景色把原先的痕迹抹掉。

g.Clear(this.BackColor);

3) 鼠标的Capture事件

鼠标的捕获释放只能在一个控件中完成,前一个控件A捕获了鼠标后,不可能由下一个控件B捕获,必须是A释放了之后才能由B控件捕获。

假设在A控件上按住鼠标移动,鼠标移出A放在了B控件上。假设在B控件中的OnMouseHover中添加了代码弹出对话框,这样的对话框不会弹出,因为A捕获了鼠标,在A未释放之前,其他控件不可能激发鼠标相关的事件,除非其他控件捕获它之后,才可能激发它的事件。

附坐标变化程序代码:

 

ExpandedBlockStart.gif 代码
using  System;
using  System.Collections.Generic;
using  System.ComponentModel;
using  System.Data;
using  System.Drawing;
using  System.Linq;
using  System.Text;
using  System.Windows.Forms;
using  System.Drawing.Drawing2D;

namespace  GDITransformApp
{
    
    
public   partial   class  Transform1 : Form
    {
        
public   class  MyMatrix
        {
            
public   float  X
            {
                
get ;
                
set ;
            }
            
public   float  Y
            {
                
get ;
                
set ;
            }

            
public  MyMatrix( float  x,  float  y)
            {
                X 
=  x;
                Y 
=  y;
            }

        }

        
#region  Coordanate
        
// 坐标轴X与控件边缘的距离
         private   const   int  xPad  =   80 ;

        
// 坐标轴Y与控件边缘的距离
         private   const   int  yPad  =   60 ;

        
///   <summary>
        
///  X坐标标签间距
        
///   </summary>
         private   int  coordinateLablePadX  =   20 ;
        
public   int  CoordinateLablePadX
        {
            
get
            {
                
return  coordinateLablePadX;
            }

            
set
            {
                Invalidate();
                coordinateLablePadX 
=  value;
            }
        }


        
///   <summary>
        
///  Y坐标标签间距
        
///   </summary>
         private   int  coordinateLablePadY  =   30 ;
        
public   int  CoordinateLablePadY
        {
            
get
            {
                
return  coordinateLablePadY;
            }

            
set
            {
                Invalidate();
                coordinateLablePadY 
=  value;
            }
        }

        
///   <summary>
        
///  y坐标轴起点坐标
        
///   </summary>
         public  Point YCoordinateStartPoint
        {
            
get
            {
                
return   new  Point(xPad,  this .Height  -  yPad);

            }
        }


        
///   <summary>
        
///   y坐标轴终点坐标
        
///   </summary>
         public  Point YCoordinateEndPoint
        {
            
get
            {
                
return   new  Point(xPad, yPad);
            }
        }


        
///   <summary>
        
///   x坐标轴起点坐标
        
///   </summary>
         public  Point XCoordinateStartPoint
        {
            
get
            {
                
return  YCoordinateStartPoint;
            }
        }

        
///   <summary>
        
///   x坐标轴终点坐标
        
///   </summary>
         public  Point XCoordinateEndPoint
        {
            
get
            {
                Point current 
=   new  Point();
                current.X 
=  Width  -  xPad;
                current.Y 
=  Height  -  yPad;
                
return  current;
            }
        }

        
private   void  DrawCoordinate(PaintEventArgs e)
        {


            Pen currentPen 
=   new  Pen(Color.Black);

            currentPen.EndCap 
=  LineCap.ArrowAnchor;

            
// 绘制Y轴
            e.Graphics.DrawLine(
                currentPen,
                YCoordinateStartPoint,
                YCoordinateEndPoint
                );

            
// 绘制Y轴
            e.Graphics.DrawLine(
                currentPen,
                XCoordinateStartPoint,
                XCoordinateEndPoint
                );
            currentPen.Dispose();

            
// 绘制X,Y 标签
            DrawCoordinateLabel(e.Graphics, YCoordinateStartPoint, YCoordinateEndPoint, XCoordinateStartPoint, XCoordinateEndPoint);
        }

        
///   <summary>
        
///  绘制坐标标记
        
///   </summary>
         private   void  DrawCoordinateLabel(Graphics gp, Point startYPoint, Point endYPoint, Point startXPoint, Point endXPoint)
        {
            
// int y = YCoordinateStartPoint  .Y -  YCoordinateEndPoint.Y;

            
int  currentValue  =   - 1 ;
            
float  labelX  =   0 , labelY  =   0 ;
            
int  pad  =   5 ;

            
// 绘制Y轴
             for  ( int  current  =  YCoordinateStartPoint.Y; current  >  YCoordinateEndPoint.Y; current  -=  CoordinateLablePadY)
            {
                currentValue
++ ;

                SizeF textSize 
=  gp.MeasureString(currentValue.ToString(), Font);

                labelX 
=  YCoordinateStartPoint.X  -  xPad  /   2 ;
                labelY 
=  current  -  textSize.Height  /   2 ;

                
// 绘制label
                gp.DrawString(currentValue.ToString(), Font, Brushes.Black,
                    
new  PointF(labelX, labelY)
                        );

                
// 绘制|-
                gp.DrawLine(Pens.Black,  new  Point(YCoordinateStartPoint.X, current),  new  Point(YCoordinateStartPoint.X  +  pad, current));

            }

            currentValue 
=   - 1 ;
            
// 绘制X轴
             for  ( int  current  =  XCoordinateStartPoint.X; current  <  XCoordinateEndPoint.X; current  +=  CoordinateLablePadX)
            {
                currentValue
++ ;

                SizeF textSize 
=  gp.MeasureString(currentValue.ToString(), Font);

                labelY 
=  XCoordinateStartPoint.Y  +  yPad  /   2 ;
                labelX 
=  current;

                
// 绘制label
                gp.DrawString(currentValue.ToString(), Font, Brushes.Black,
                    
new  PointF(labelX, labelY)
                        );

                
// 绘制_|_
                gp.DrawLine(Pens.Black,
                    
new  Point(current, XCoordinateStartPoint.Y),
                
new  Point(current, XCoordinateStartPoint.Y  -  pad)
                );


            }




        }

#endregion

        
float  angle  =  0f;
        
float  scaleX  =  1f;
        
float  scaleY  =  1f;

        
float  translateX  =  1f;
        
float  translateY  =  1f;
        
public  Transform1()
        {
            InitializeComponent();
        }

        Matrix matrix 
=   new  Matrix();

        List
< MyMatrix >  myList  =   new  List < MyMatrix > ();


       

        
protected   override   void  OnPaint(PaintEventArgs e)
        {
            
base .OnPaint(e);

            e.Graphics.Clear(
this .BackColor);

            DrawCoordinate(e);

            DrawRectangle();

        }

        
private   void  DrawRectangle()
        {
            
using  (Graphics gh  =  CreateGraphics())
            {
               
                Rectangle rect 
=   new  Rectangle( 100 100 200 200 );
                
                StringFormat sf
= new  StringFormat();
                sf.Alignment
= StringAlignment.Center ;
                sf.LineAlignment
= StringAlignment .Center ;

                
// 平移
                gh.TranslateTransform(translateX, translateY);
                
// 旋转
                gh.RotateTransform(angle);
                
// 缩放
                gh.ScaleTransform(scaleX, scaleY);

                
// 设置gh的变换矩阵
                gh.Transform  =  matrix;
              
                gh.DrawRectangle(Pens.Red, rect);
                gh.DrawString(
" AAAAAAAAA " this .Font, Brushes.Blue, rect, sf);

                matrix 
=  gh.Transform;

                myList.Add(
new  MyMatrix(matrix.Elements[ 0 ], matrix.Elements[ 1 ]));
                myList.Add(
new  MyMatrix(matrix.Elements[ 2 ], matrix.Elements[ 3 ]));
                myList.Add(
new  MyMatrix(matrix.Elements[ 4 ], matrix.Elements[ 5 ]));

                
this .dgvMatrix.DataSource  =  myList;
          
                
            }

        }

        
private   void  button1_Click( object  sender, EventArgs e)
        {
            angle 
+=   10 ;
            
this .Invalidate();
        }

        
private   void  btnScaleAdd_Click( object  sender, EventArgs e)
        {
            scaleX 
+=   1 ;
            scaleY 
+=   1 ;
            
this .Invalidate();
        }

        
private   void  btnScaleSub_Click( object  sender, EventArgs e)
        {
            scaleX 
-=   1 ;
            scaleY 
-=   1 ;
            
this .Invalidate();
        }

        
private   void  btnRolateSub_Click( object  sender, EventArgs e)
        {
            angle 
-=   10 ;
            
this .Invalidate();
        }

        
private   void  btnBack_Click( object  sender, EventArgs e)
        {
            angle 
=  0f;
            scaleX 
=  1f;
            scaleY 
=  1f;
            translateX 
=  0f;
            translateY 
=  0f;
            
this .Invalidate();
        }

        
private   void  btnTranslateAdd_Click( object  sender, EventArgs e)
        {
            translateX 
+=  3f;
            translateY 
+=  3f;
            
this .Invalidate();
        }

        
private   void  btnTranslateSub_Click( object  sender, EventArgs e)
        {
            translateX 
-=  5f;
            translateY 
-=  5f;
            
this .Invalidate();
        }

       

        
private   void  btnMatrixBack_Click( object  sender, EventArgs e)
        {
            matrix 
=   new  Matrix
            (
              
1 , 0 ,
              
0 , 1 ,
              
0 , 0
            );
            
this .Invalidate();
        }

        
private   void  button1_Click_1( object  sender, EventArgs e)
        {
            matrix 
=   new  Matrix(

               ((MyMatrix)
this .dgvMatrix.Rows[ 0 ].DataBoundItem).X, ((MyMatrix) this .dgvMatrix.Rows[ 0 ].DataBoundItem).Y ,
               ((MyMatrix)
this .dgvMatrix.Rows[ 1 ].DataBoundItem).X, ((MyMatrix) this .dgvMatrix.Rows[ 1 ].DataBoundItem).Y ,
               ((MyMatrix)
this .dgvMatrix.Rows[ 2 ].DataBoundItem).X, ((MyMatrix) this .dgvMatrix.Rows[ 2 ].DataBoundItem).Y 
               );
            
            
this .Invalidate();

        }
    }
}

 

 

转载于:https://www.cnblogs.com/hbb0b0/archive/2011/01/07/1929880.html

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值