• 关于绘制图形,吹一下小牛皮


    你一看标题,肯定会想:靠!太菜了。是啊,很菜,简直菜歪歪了。自从被某些人封为“高手”起,我就丧失了当小白的机会,更别说当菜鸟了。其实,成为一名小白没有什么不好,是吧?无知无欲,人生更多欢乐,知得越多越痛苦,真的是这样,因为很多人总是知道他本不应该知道的东西,所以他们就活得很痛苦。

    有一位挚友不知道做了什么春梦,突然找到我说,他要写一个绘图程序。我说:“拿系统的画图程序来玩就行了,不够爽的话,就玩PS嘛。”他眼睛睁大了三倍地叫着:“自己写出来才爽。”

    是啊,其实他这句话灰常有道理。于是,他就开始扯了,说如何做到,鼠标,按下、拖动、弹起这一过程中在窗口上画出一个矩形。其实并不难吧,我相信很多人都会了。就是在鼠标按下的时候,记录其起点,然后鼠标移动,在鼠标弹起时记录终点,两个点,起点为左上角,终点为右下角,就能画出矩形了。

    是的,这就成了,于是他就开始写程序,表面上是做到了,但是,如果用户在操作时,起点的坐标比终点的坐标的值要小,哈哈,就画不出来了。按照他的逻辑,通常终点应当位于起点的右下角,所以他就这样做了,但是,他并没有考虑到,我在鼠标操作的时候,并不一定是往右下方移动鼠标,我有可能是从右下角往左上方移动鼠标,这时候你得考虑矩形的左上顶点和右下顶点应该取哪些坐标了。

    情况有四种——终点在起点右下方,这是最好处理的;终点在起点的右上方;终点在起点的左上方;终点在起点的左下方。

             

               

    再看看椭圆。

                

                 

    通过以上的“看图识字”,挚友忽然有所悟。是的,别小看实现用鼠标画矩形这一功能,其中还有不少学问,另外我们还要考虑鼠标坐标的起点和终点相同的情况,因为我们是不能画出长和宽都等于0的矩形。矩形的问题如果解决了,那么,画椭圆也可以解决了,原理是一样的。

    于是,我这个演示代码中用一个变量来表示绘图类型,0表示画矩形,1表示画椭圆,2表示画扇形。

    [csharp] view plain copy
     
    1. public partial class Form1 : Form  
    2. {  
    3.     bool isDown = false;  
    4.     Point startPoint;  
    5.     Rectangle rect;  
    6.   
    7.     // 绘制类型,0表示画矩形,1表示画椭圆,2表示扇形  
    8.     byte DrawType = 0;  


    isDown指示鼠标左键是否按下,在鼠标的Down和Up事件中分别设置它的值。在鼠标的Move事件中确定矩形的左上顶点和右下顶点。

    [csharp] view plain copy
     
    1. void Form1_MouseMove(object sender, MouseEventArgs e)  
    2. {  
    3.     if (isDown == false) return;  
    4.     Point tmpPt = new Point(e.X, e.Y);  
    5.     Point TopLeftPoint, BottomRightPoint;  
    6.     if (tmpPt.X > startPoint.X && tmpPt.Y > startPoint.Y)//终点在起点的右下角  
    7.     {  
    8.         TopLeftPoint = new Point(startPoint.X, startPoint.Y);  
    9.         BottomRightPoint = new Point(tmpPt.X, tmpPt.Y);  
    10.     }  
    11.     else if (tmpPt.X > startPoint.X && tmpPt.Y < startPoint.Y)//终点在起点的右上角  
    12.     {  
    13.         TopLeftPoint = new Point(startPoint.X, tmpPt.Y);  
    14.         BottomRightPoint = new Point(tmpPt.X, startPoint.Y);  
    15.     }  
    16.     else if (tmpPt.X < startPoint.X && tmpPt.Y < startPoint.Y)//终点在起点的左上角  
    17.     {  
    18.         TopLeftPoint = new Point(tmpPt.X, tmpPt.Y);  
    19.         BottomRightPoint = new Point(startPoint.X, startPoint.Y);  
    20.     }  
    21.     else if (tmpPt.X < startPoint.X && tmpPt.Y > startPoint.Y)//终点在起点的左下角  
    22.     {  
    23.         TopLeftPoint = new Point(tmpPt.X, startPoint.Y);  
    24.         BottomRightPoint = new Point(startPoint.X, tmpPt.Y);  
    25.     }  
    26.     else  
    27.     {  
    28.         TopLeftPoint = startPoint;  
    29.         BottomRightPoint = new Point(TopLeftPoint.X + 1, TopLeftPoint.Y + 1);  
    30.     }  
    31.     rect = new Rectangle(TopLeftPoint.X, TopLeftPoint.Y, BottomRightPoint.X - TopLeftPoint.X, BottomRightPoint.Y - TopLeftPoint.Y);  
    32.     this.Invalidate();  
    33. }  
    34.   
    35. void Form1_MouseUp(object sender, MouseEventArgs e)  
    36. {  
    37.     if (e.Button == System.Windows.Forms.MouseButtons.Left)  
    38.     {  
    39.         isDown = false;  
    40.         this.Invalidate();  
    41.     }  
    42. }  
    43.   
    44. void Form1_MouseDown(object sender, MouseEventArgs e)  
    45. {  
    46.     if (e.Button == System.Windows.Forms.MouseButtons.Left)  
    47.     {  
    48.         isDown = true;  
    49.         startPoint = new Point(e.X, e.Y);  
    50.     }  
    51. }  


    this.Invalidate方法调用强制窗口发生重绘,为了能够随着鼠标移动而动态显示图形,所以在坐标点变化后要刷新窗口,除了Invalidate方法外,还可以用Refresh方法。

    最后就是Paint事件,要根据左上点和右下点进行绘制。

    [csharp] view plain copy
     
    1. private void Form1_Paint(object sender, PaintEventArgs e)  
    2. {  
    3.     Graphics g = e.Graphics;  
    4.     g.Clear(SystemColors.Control);  
    5.     Pen myPen = new Pen(Color.Red, 2f);  
    6.     switch (DrawType)  
    7.     {  
    8.         case 0:  
    9.             g.DrawRectangle(myPen, rect);  
    10.             break;  
    11.         case 1:  
    12.             g.DrawEllipse(myPen, rect);  
    13.             break;  
    14.         case 2:  
    15.             g.DrawPie(myPen, rect, 0f, 90f);  
    16.             break;  
    17.     }  
    18.     myPen.Dispose();  
    19. }  


  • 相关阅读:
    Binary Search Tree Iterator 解答
    Invert Binary Tree 解答
    Min Stack 解答
    Trapping Raining Water 解答
    Candy 解答
    Jump Game II 解答
    Implement Hash Map Using Primitive Types
    Gas Station 解答
    Bucket Sort
    HashMap 专题
  • 原文地址:https://www.cnblogs.com/weekbo/p/8682053.html
Copyright © 2020-2023  润新知