分享

WPF中的静态、动态图形绘制问题

 牛人的尾巴 2016-06-06

WPF中的静态、动态图形绘制问题

(2013-04-06 16:15:45)

    桂林老师来信询问数学图形绘制问题。分三种情况说明:

    一、利用【工具】中的工具绘制

    【工具】中有椭圆、矩形、直线工具,直接使用就行。还有钢笔、铅笔工具(在《WPF和Silverlight教程》中有较详细介绍)。下面的方法均需要编制较多程序。

    二、编程绘制静态规则图形   

利用Shape基类绘制规则图形

    Shape基类派生了六个实用类,可以实例化直接使用的对象,如 Ellipse(椭圆)、Line(直线)、Path(路径)、Polygon(绘制封闭的多边形)、Polyline(绘制首尾连接的直线,可以不封闭)和 Rectangle(矩形),Expression Blend中的图形控件使用了其中的对象。Shape的对象共享以下通用属性:

    Stroke:说明绘制形状的轮廓颜色;

    StrokeThickness:说明形状轮廓的粗细;

    Fill:说明如何绘制形状的内部;

    还有一些其它属性,这些属性在Blend的【属性】面板中可以找到,不在这里叙述。这些对象控件的使用也很简单,从【工具】面板选择就行,下面只举例说明如何通过编程应用Shape的对象绘制图形。一般在绘制规则图形时会使用到这些类。

    要说明的是图形绘制时的坐标体系:

    WPF默认的二维坐标原点是设计屏幕的左上角,X正方向向左,Y正方向向下,单位是1英寸(25.4毫米)的1/96。

    图3.23.1列举了几个图形绘制方法,界面的根布局类型改为Canvas,按钮事件代码即是图形的绘制程序。

1. 绘制直线

private void button1_Click(object sender, System.Windows.RoutedEventArgs e)

               

Line line = new Line();//定义直线对象

            line.Stroke = System.Windows.Media.Brushes.Red; //设置线的颜色,红色

            line.X1 = 0; //直线起点

            line.Y1 = 0;           

            line.X2 = 150; //直线终点

            line.Y2 = 320;           

            line.StrokeThickness = 5; //直线粗细

            this.LayoutRoot.Children.Add(line); //装入界面根布局容器中

        }

 WPF中的静态、动态图形绘制问题
图3.23.1 Shape类图形绘制

2. 绘制椭圆

private void button2_Click(object sender, System.Windows.RoutedEventArgs e)

               

            Ellipse ellipse = new Ellipse();//定义椭圆对象

            //属性设置,填充颜色、边粗细、边颜色、宽、高等

            ellipse.Fill=System.Windows.Media.Brushes.Green;

            ellipse.StrokeThickness = 4;          

            ellipse.Stroke =System.Windows.Media.Brushes.Gold; //边,金黄色

            ellipse.Width = 80;

            ellipse.Height = 200;

            //椭圆对象相对于父容器对象Canvas的位置,左边距、上边距

            Canvas.SetLeft(ellipse,165);

            Canvas.SetTop(ellipse,80);

            this.LayoutRoot.Children.Add(ellipse);

        }

3. 绘制矩形

private void button3_Click(object sender, System.Windows.RoutedEventArgs e)

        {

          Rectangle rectangle = new Rectangle();//矩形对象

          //属性设置,填充颜色、边粗细、边颜色、宽、高等

            rectangle.Fill=System.Windows.Media.Brushes.Blue;

            rectangle.StrokeThickness = 4;            

            rectangle.Stroke =System.Windows.Media.Brushes.Pink; //边,粉色

            rectangle.Width = 80;

            rectangle.Height = 200;

         //矩形对象相对于父容器对象Canvas的位置,左边距、上边距

            Canvas.SetLeft(rectangle,260);

            Canvas.SetTop(rectangle,80);

            this.LayoutRoot.Children.Add(rectangle);

        }

4. 封闭多边形

    封闭多边形Polygon的绘制需要指明多边形的顶点坐标,只要有了这些点集,Polygon自动依次连接每个顶点,并且自动将最后1个顶点和第1个顶点连接,绘制出封闭多边形,Polygon有个属性Points,需要声明设置此属性的点集合。

private void button4_Click(object sender, System.Windows.RoutedEventArgs e)

                 

           Polygon polygon = new Polygon();//定义封闭多边形对象

          //属性设置,边颜色、填充颜色、边粗细等

           polygon.Stroke = System.Windows.Media.Brushes.Red;

          //填充,浅海蓝色

           polygon.Fill = System.Windows.Media.Brushes.LightSeaGreen;

           polygon.StrokeThickness = 2;           

           Point Point1 = new Point(360,80); //封闭多边形的多个顶点坐标

           Point Point2 = new Point(390,90);

           Point Point3 = new Point(435,150);

           Point Point4 = new Point(390,200);

           Point Point5 = new Point(360,300);

            //定义点集合对象

           PointCollection pointCollection = new PointCollection();           

            pointCollection.Add(Point1); //将顶点添加到点集合对象

            pointCollection.Add(Point2);

            pointCollection.Add(Point3);

            pointCollection.Add(Point4);

            pointCollection.Add(Point5);           

            polygon.Points = pointCollection; //设置Polygon属性Points的点集合

            this.LayoutRoot.Children.Add(polygon);

        }

5. 不封闭形状

    不封闭形状Polyline 的绘制和Polygon的绘制类似,需要指明顶点坐标,只要有了这些点集,Polyline自动依次连接每个顶点,但最后1个顶点和第1个顶点不会连接,从而绘制出不封闭形状,Polyline也有个属性Points,需要声明设置此属性的点集合。

private void button5_Click(object sender, System.Windows.RoutedEventArgs e)

               

          Polyline polyline = new Polyline();//定义不封闭形状的对象

         //属性设置,边颜色、填充颜色、边粗细等

           polyline.Stroke = System.Windows.Media.Brushes.Red;

            //填充色,浅海蓝色

           polyline.Fill = System.Windows.Media.Brushes.LightSeaGreen; 

           polyline.StrokeThickness = 2;

           Point Point1 = new Point(460,80); //不封闭形状的多个顶点坐标

           Point Point2 = new Point(490,90);

           Point Point3 = new Point(535,150);

           Point Point4 = new Point(490,200);

           Point Point5 = new Point(460,300);

           //定义点集合对象

           PointCollection pointCollection = new PointCollection();              

           pointCollection.Add(Point1); //将顶点添加到点集合对象

           pointCollection.Add(Point2);

           pointCollection.Add(Point3);

           pointCollection.Add(Point4);

           pointCollection.Add(Point5);           

           polyline.Points = pointCollection;//Polyline对象属性Points的点集合

           this.LayoutRoot.Children.Add(polyline);

        }

     三、编程绘制动态随机图形 

利用Geometry基类绘制动态图形

    Geometry类以及派生类可以描绘基本、复杂二维形状的几何图形,可以剪辑图形绘制到屏幕,可以形成动画。Geometry的派生类大致可以分为三个类别:基本几何图形、复合几何图形和路径图形。当然,Geometry类描绘的图形需要借助其他方法显示。

    由于内容较多,这里没有详细介绍Geometry类,只是结合自由落体运动轨迹动态图形绘制介绍有关知识。图3.23.2(Example2.23\Window1.xaml)是动态绘制自由落体运动中高度变化的轨迹示例,希望对其他实时图形的绘制有所启发。

    图3.23.2左边有个小球,小球(ellipse)被放置在Canvas控件(canvas1)中,从顶端自由下落,在地面弹跳几次后停止,自由落体动画、缓冲曲线设置均使用编程实现。右边是动态绘制的图形,坐标线是直线控件直接放到【设计面板】实现,动态图形点的采集是在定时器的定时处理程序中实现的。右边黑色背景是Canvas控件(canvas2)。运动轨迹的绘制使用几何线段绘制对象PathFigure,此对象有个特点,只要确定绘制的开始点,就会自动连接后面采集的点形成线段,线段需要复合几何图形PathGeometry对象组合形成曲线图形、并借助于Path对象显示。图3.23.2左下方有两个按钮控件,一个用于“启动”(b1,启动自由落体动画),另一个用于“复位”(b2,小球回到开始位置)。最下方有个文本框TextBlock用于显示小球下落过程中高度的数字值,下面是程序。

 

 WPF中的静态、动态图形绘制问题
图3.23.2 实时图形绘制

    1. 初始化程序      

        int i=1; //动画时间计数

        DispatcherTimer timer=new DispatcherTimer();//定时器       

        PathFigure pf = new PathFigure();//运动轨迹线段绘制    

        PathGeometry pg = new PathGeometry();//组合绘制的线段      

        Path pa = new Path();//绘制轨迹曲线的容器,用于显示    

        DoubleAnimation da=new DoubleAnimation();//小球自由落体运动动画

        BounceEase easeBounce=new BounceEase();//缓动曲线定义      

        DoubleAnimation rt=new DoubleAnimation();//复位动画

        public Window1()

        {

            this.InitializeComponent();

            pa.Stroke=Brushes.LightGreen;//绘制颜色,亮绿色

            pa.StrokeThickness=2;//绘制的线宽

            Canvas.SetTop(this.ellipse,0);  //设置小球起点     

            startpoint();//确定绘制的开始点,自定义程序

            timer.Interval=TimeSpan.FromMilliseconds(10);//定时10毫秒

            timer.Tick+=new System.EventHandler(timer_Tick); //定时事件

            da.Completed+=new System.EventHandler(da_Completed);//动画完成事件

        }

    2. 绘制起点自定义程序

private void startpoint()

          

            pf.StartPoint = new Point(0,0);//定义绘制的第一个点

            //加入到PathFigure对象中,true表示描绘线段

            pf.Segments.Add(new LineSegment(new Point(0,0),true));          

            pg.Figures.Add(pf); //组合绘制的线段,只要操作一次

            pa.Data=pg;//作为Path对象的数据

            this.canvas2.Children.Add(pa);//加入Canvas在屏幕显示

            Canvas.SetLeft(pa,0);//设置Path对象左边距从0开始,绘制开始的X坐标

            Canvas.SetTop(pa,this.canvas2.Height/2);//绘制开始的Y坐标

        }

3. 自由落体动画

private void b1_Click(object sender, System.Windows.RoutedEventArgs e)

            

            easeBounce.EasingMode=EasingMode.EaseOut;//缓动曲线模式

            da.EasingFunction=easeBounce;//动画缓动曲线设置

            da.Duration=TimeSpan.FromSeconds(5);//动画间隔时间5秒

            da.From=0;//从高度0开始,起点

            da.To=400;//落地高度400,终点

            this.ellipse.RenderTransform=new TranslateTransform();//小球位移变换

            timer.Start();//启动定时器

            ellipse.BeginAnimation(Canvas.TopProperty,da);//启动动画           

    }

4. 动画完成

private void da_Completed(object sender, System.EventArgs e)

        {

            timer.Stop();      

    }

5. 定时器定时事件

private void timer_Tick(object sender, System.EventArgs e)

        {

            double y=Canvas.GetTop(this.ellipse);//获取当前高度

            pf.Segments.Add(new LineSegment(new Point(i,y/2),true));//加入

            i++;//计数

            this.tb.Text=y.ToString();//显示数字值

    }

6. 复位动画程序

private void b2_Click(object sender, System.Windows.RoutedEventArgs e)

        {

            rt.Duration=TimeSpan.FromSeconds(1);//动画时间1秒

            rt.From=400;//开始点

            rt.To=0;//终点

            this.ellipse.RenderTransform=new TranslateTransform();

            ellipse.BeginAnimation(Canvas.TopProperty,rt);

            pf.Segments.Clear();//PathFigure对象清0,所有绘制线段消失

            i=1;//重新计数 

    }

    以上的编程对初学者有点困难,其实可以寻找其他可以容易画图的软件生成EXE文件,在WPF中连接就相对简单了。

 

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多