C#WPF 如何绘制几何图形 图示教程 绘制sin曲线 正弦 绘制2D坐标系 有图有代码

简介: 原文:C#WPF 如何绘制几何图形 图示教程 绘制sin曲线 正弦 绘制2D坐标系 有图有代码 C#WPF 如何绘制几何图形? 怎么绘制坐标系?绘制sin曲线(正弦曲线)? 这离不开Path(System.Windows.Shapes)和StreamGeometry(System.Windows.Media)类。
原文: C#WPF 如何绘制几何图形 图示教程 绘制sin曲线 正弦 绘制2D坐标系 有图有代码

C#WPF 如何绘制几何图形? 怎么绘制坐标系?绘制sin曲线(正弦曲线)?

这离不开Path(System.Windows.Shapes)和StreamGeometry(System.Windows.Media)类。

完成该工程,我们首先要建立并绘制一个坐标系,然后在该坐标系中绘制sin曲线的点(x,y),最后,把曲线的点转换为屏幕坐标并连接;这样坐标系和sin曲线就绘制完成了。

 代码下载:http://download.csdn.net/detail/wyx100/8320225

如果有帮助,别忘了给评价!

 

一、建立WPF工程  

 

 

二、添加代码

MainWindow.xaml 中代码

<Window x:Class="WPFDrawingTraning.MainWindow"
        xmlns="<a target=_blank href="http://schemas.microsoft.com/winfx/2006/xaml/presentation">http://schemas.microsoft.com/winfx/2006/xaml/presentation</a>"
        xmlns:x="<a target=_blank href="http://schemas.microsoft.com/winfx/2006/xaml">http://schemas.microsoft.com/winfx/2006/xaml</a>"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Canvas Name="mainPanel" HorizontalAlignment="Left" Height="320" VerticalAlignment="Top" Width="517"/>
    </Grid>
</Window>

 

MainWindow.xaml.cs中代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WPFDrawingTraning
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : System.Windows.Window
    {
        //Canvas mainPanel = new Canvas();
        public MainWindow()
        {
            InitializeComponent();

            Drawsin();//绘制2D坐标系和sin曲线
    
            Drawpentagon();

        }
        /// <summary>
        /// 绘制一组线段
        /// </summary>
        protected void Drawing()
        {
            PathFigure myPathFigure = new PathFigure();
            myPathFigure.StartPoint = new Point(10, 50);

            LineSegment myLineSegment = new LineSegment();
            myLineSegment.Point = new Point(200, 70);

            PathSegmentCollection myPathSegmentCollection = new PathSegmentCollection();
            myPathSegmentCollection.Add(myLineSegment);

            myPathFigure.Segments = myPathSegmentCollection;

            PathFigureCollection myPathFigureCollection = new PathFigureCollection();
            myPathFigureCollection.Add(myPathFigure);

            PathGeometry myPathGeometry = new PathGeometry();
            myPathGeometry.Figures = myPathFigureCollection;
            

            Path myPath = new Path();
            myPath.Stroke = Brushes.Black;
            myPath.StrokeThickness = 1;
            myPath.Data = myPathGeometry;

            // Add path shape to the UI.
            StackPanel mainPanel = new StackPanel();
            mainPanel.Children.Add(myPath);
            this.Content = mainPanel;

        }
        /// <summary>
        /// 绘制线段
        /// </summary>
        protected void DrawingLine(Point startPt,Point endPt)
        {
            LineGeometry myLineGeometry = new LineGeometry();
            myLineGeometry.StartPoint = startPt;
            myLineGeometry.EndPoint = endPt;

            Path myPath = new Path();
            myPath.Stroke = Brushes.Black;
            myPath.StrokeThickness = 1;
            myPath.Data = myLineGeometry;

            mainPanel.Children.Add(myPath);
            
        }
        /// <summary>
        /// 绘制星状线
        /// </summary>
        protected void DrawingAstroid(Point center,double r)
        {

            double h1 = r * Math.Sin(18 * Math.PI / 180);
            double h2 = r * Math.Cos(18*Math.PI/180);
            double h3 = r * Math.Sin(36 * Math.PI / 180);
            double h4 = r * Math.Cos(36 * Math.PI / 180); ;
            Point p1 = new Point(r, 0);
            Point p2 = new Point(r - h2, r - h1);
            Point p3 = new Point(r - h3, r + h4);
            Point p4 = new Point(r + h3, p3.Y);
            Point p5 = new Point(r + h2, p2.Y);
            Point[] values = new Point[] { p1, p2, p3, p4, p5 };
            PathFigureCollection myPathFigureCollection = new PathFigureCollection();
            PathGeometry myPathGeometry = new PathGeometry();
            
            for (int i = 0; i < values.Length; i++)
            {
                //DrawingLine(center, values[i]);
                PathFigure myPathFigure = new PathFigure();
                myPathFigure.StartPoint = center;

                LineSegment myLineSegment = new LineSegment();
                myLineSegment.Point = values[i];

                PathSegmentCollection myPathSegmentCollection = new PathSegmentCollection();
                myPathSegmentCollection.Add(myLineSegment);

                myPathFigure.Segments = myPathSegmentCollection;

                myPathFigureCollection.Add(myPathFigure);
            }
            myPathGeometry.Figures = myPathFigureCollection;
            Path myPath = new Path();
            myPath.Stroke = Brushes.Black;
            myPath.StrokeThickness = 1;
            myPath.Data = myPathGeometry;
            
            mainPanel.Children.Add(myPath);
        }

        /// <summary>
        /// 绘制坐标系和sin曲线
        /// </summary>
        private void Drawpentagon()
        {
            Point center = new Point(50, 50);
            double r = 50;
            DrawingAstroid(center, r);

            double h1 = r * Math.Sin(18 * Math.PI / 180);
            double h2 = r * Math.Cos(18 * Math.PI / 180);
            double h3 = r * Math.Sin(36 * Math.PI / 180);
            double h4 = r * Math.Cos(36 * Math.PI / 180); ;
            Point p1 = new Point(r, 0);
            Point p2 = new Point(r - h2, r - h1);
            Point p3 = new Point(r - h3, r + h4);
            Point p4 = new Point(r + h3, p3.Y);
            Point p5 = new Point(r + h2, p2.Y);
            Point[] values = new Point[] { p1, p3, p5, p2, p4 };
            // Create a path to draw a geometry with.
            Path myPath = new Path();
            myPath.Stroke = Brushes.Black;
            myPath.StrokeThickness = 1;
            StreamGeometry theGeometry = BuildRegularPolygon(values, true, false);
            // Create a StreamGeometry to use to specify myPath.
            theGeometry.FillRule = FillRule.EvenOdd;

            // Freeze the geometry (make it unmodifiable)
            // for additional performance benefits.
            theGeometry.Freeze();

            // Use the StreamGeometry returned by the BuildRegularPolygon to 
            // specify the shape of the path.
            myPath.Data = theGeometry;

            // Add path shape to the UI.
            mainPanel.Children.Add(myPath);

        }

        /// <summary>
        /// 绘制连续的线段
        /// </summary>
        /// <param name="values"></param>
        /// <returns></returns>
        private StreamGeometry BuildRegularPolygon(Point[] values, bool isClosed,bool isfilled)
        {
            // c is the center, r is the radius,
            // numSides the number of sides, offsetDegree the offset in Degrees.
            // Do not add the last point.

            StreamGeometry geometry = new StreamGeometry();

            using (StreamGeometryContext ctx = geometry.Open())
            {
                ctx.BeginFigure(values[0], isfilled /* is filled */, isClosed /* is closed */);
                
                for (int i = 1; i < values.Length; i++)
                {                    
                    ctx.LineTo(values[i], true /* is stroked */, false /* is smooth join */);
                }
            }
            
            return geometry;

        }

        /// <summary>
        /// 绘制五角星
        /// </summary>
        private void Drawsin()
        {
            Point point = new Point(this.mainPanel.Width, this.mainPanel.Height);
            Point xypoint = new Point(point.X / 2, point.Y / 2);//新坐标原点

            //x轴坐标起点
            Point xstartpoint = new Point(0, point.Y / 2);
            //x轴坐标终点
            Point xendpoint = new Point(point.X, point.Y / 2);

            //y轴坐标起点
            Point ystartpoint = new Point(point.X / 2, point.Y);
            //y轴坐标终点
            Point yendpoint = new Point(point.X / 2, 0);

            Line xline = new Line();
            xline.Stroke = System.Windows.Media.Brushes.LightSteelBlue;

            xline.X1 = 0;
            xline.Y1 = this.mainPanel.Height / 2;

            xline.X2 = this.mainPanel.Width;
            xline.Y2 = this.mainPanel.Height / 2;

            this.mainPanel.Children.Add(xline);


            Line yline = new Line();
            yline.Stroke = System.Windows.Media.Brushes.LightSteelBlue;

            yline.X1 = this.mainPanel.Width / 2;
            yline.Y1 = this.mainPanel.Height;

            yline.X2 = this.mainPanel.Width / 2;
            yline.Y2 = 0;

            this.mainPanel.Children.Add(yline);
            Point[] points=new Point[1000];

            //绘制sin曲线,从原点(0,0)开始
              Point zpoint = new Point(0, 0);
            zpoint = XYTransf(zpoint, xypoint);
            points[0] = zpoint;//sin曲线的起点

         
              for (int i = 1; i < 1000; i++)
            {
                //计算sin(x,y)
                point.X =10 * i;//x
              point.Y =10 * Math.Sin(i);//y
  
                //坐标转换
                point = XYTransf(point, xypoint);
                points[i] = point;

            }

            Path myPath = new Path();
            myPath.Stroke = Brushes.Black;
            myPath.StrokeThickness = 1;
            StreamGeometry theGeometry = BuildRegularPolygon(points, true, false);
            // Create a StreamGeometry to use to specify myPath.
            theGeometry.FillRule = FillRule.EvenOdd;

            // Freeze the geometry (make it unmodifiable)
            // for additional performance benefits.
            theGeometry.Freeze();

            // Use the StreamGeometry returned by the BuildRegularPolygon to 
            // specify the shape of the path.
            myPath.Data = theGeometry;

            // Add path shape to the UI.
            mainPanel.Children.Add(myPath);

        }

        //构建的XY坐标系中的坐标转换为界面坐标系
        public Point XYTransf(Point point, Point xypoint)
        {
            point.X += xypoint.X;
            point.Y = xypoint.Y - point.Y;

            return point;//显示屏幕坐标系的位置
        }
    }
}

三、页面效果

 

四、介绍

private void Drawsin()  函数中完成:坐标系绘制,sin曲线绘制;

point是绘图坐标系中的点,xypoint(maincanvas.Width/2,maincanvas.Height/2)是绘图屏幕坐标的几何中心点( 图 坐标点转换,中x轴和y轴原点)的坐标。

public Point XYTransf(Point point, Point xypoint)函数返回值是在屏幕坐标绘制点的坐标。

        //转换为界面坐标系
        public Point XYTransf(Point point, Point xypoint)

        {
            point.X += xypoint.X;
            point.Y = xypoint.Y - point.Y;

            return point;//显示屏幕坐标系的位置
        }


 

1.mainPanel  是一个Canvas面板,我们在该面板绘制图形。

2.绘制坐标系,以mainPanel 的图形中心为坐标原点;

                                                                                           图 坐标点转换

 

 3.计算sin(x,y)并转换为屏幕坐标点,取1000个坐标点,并存在points数组中

            for (int i = 1; i < 1000; i++)
            {
                //计算sin(x,y)
                point.X =10 * i;//sin x
              point.Y =10 * Math.Sin(i);//sin y
  
                //坐标转换
                point = XYTransf(point, xypoint);
              points[i] = point;

            }

4.连接1000个sin(x,y)的屏幕坐标点,并显示在Canvas中

StreamGeometry theGeometry = BuildRegularPolygon(points, true, false);   通过该函数连接points中所有的点;

            Path myPath = new Path();
            myPath.Stroke = Brushes.Black;
            myPath.StrokeThickness = 1;
            StreamGeometry theGeometry = BuildRegularPolygon(points, true, false);
            // Create a StreamGeometry to use to specify myPath.
            theGeometry.FillRule = FillRule.EvenOdd;

            // Freeze the geometry (make it unmodifiable)
            // for additional performance benefits.
            theGeometry.Freeze();

            // Use the StreamGeometry returned by the BuildRegularPolygon to 
            // specify the shape of the path.
            myPath.Data = theGeometry;

            // Add path shape to the UI.
            mainPanel.Children.Add(myPath);

5.执行显示效果

点击“启动”或按键盘“F5”执行工程,显示界面。



 

 

目录
相关文章
|
2月前
|
C# Windows
C#通过代码实现快捷键编辑
C#通过代码实现快捷键编辑
|
4月前
|
开发框架 .NET 编译器
C# 10.0中Lambda表达式的改进:更简洁、更灵活的代码编写体验
【1月更文挑战第21天】随着C#语言的不断发展,Lambda表达式作为一种简洁、高效的函数式编程工具,在C# 10.0中迎来了重要的改进。本文将详细探讨C# 10.0中Lambda表达式的新特性,包括参数类型的推断增强、自然类型的Lambda参数以及Lambda表达式的属性改进等。这些改进不仅简化了Lambda表达式的编写过程,还提升了代码的可读性和灵活性,为开发者带来了更优质的编程体验。
|
4月前
|
C# 开发者
C# 10.0中的文件范围命名空间:简化代码组织的新方式
【1月更文挑战第18天】C# 10.0引入了文件范围的命名空间,这是一种新的语法糖,用于更简洁地组织和管理代码。文件范围命名空间允许开发者在每个文件的基础上定义命名空间,而无需显式使用花括号包裹整个文件内容。本文将深入探讨文件范围命名空间的工作原理、使用场景以及它们为C#开发者带来的便利。
|
5月前
|
存储 人工智能 C#
【Unity 3D】C#中数组、集合、栈、队列、哈希表、字典的讲解(附测试代码)
【Unity 3D】C#中数组、集合、栈、队列、哈希表、字典的讲解(附测试代码)
37 0
|
6月前
|
开发框架 .NET C#
如何调试 C# Emit 生成的动态代码?
如何调试 C# Emit 生成的动态代码?
|
5月前
|
IDE C# 开发工具
C# | 多线程批量下载文件(创建N个线程同时批量下载文件,只需要几行代码而已)
批量下载文件时使用多线程可以有效缩短完成时间,本文将讲解如何使用C#+CodePlus扩展库快速完成多线程的文件下载。 大部分代码由IDE自动生成,需要我们自己编写的代码正好**10行**。也就是说,只需要10分钟,就可以手撸一个多线程的批量下载器。
94 0
C# | 多线程批量下载文件(创建N个线程同时批量下载文件,只需要几行代码而已)
|
3月前
|
数据采集 JSON 前端开发
从代码到内容:使用C#和Fizzler探索Instagram的深处
Instagram是一个流行的社交媒体平台,拥有数亿的用户和海量的图片和视频内容。如果您想要从Instagram上获取一些有用的信息或数据,您可能需要使用爬虫技术来自动化地抓取和分析网页内容。本文将介绍如何使用C#和Fizzler这两个强大的工具,来实现一个简单而高效的Instagram爬虫,从代码到内容,探索Instagram的深处。
|
4月前
|
存储 传感器 监控
工业相机如何实现实时和本地Raw格式图像和Bitmap格式图像的保存和相互转换(C#代码,UI界面版)
工业相机如何实现实时和本地Raw格式图像和Bitmap格式图像的保存和相互转换(C#代码,UI界面版)
32 0
|
4月前
|
存储 C#
C# 数据类型与类型转换:包含教程与示例
使用正确的数据类型对应于相应的变量是重要的;这样可以避免错误、节省时间和内存,还会使您的代码更易于维护和阅读。最常见的数据类型有:
30 0
|
4月前
|
存储 C# 容器
掌握 C# 变量:在代码中声明、初始化和使用不同类型的综合指南
变量是用于存储数据值的容器。 在 C# 中,有不同类型的变量(用不同的关键字定义),例如: int - 存储整数(没有小数点的整数),如 123 或 -123 double - 存储浮点数,有小数点,如 19.99 或 -19.99 char - 存储单个字符,如 'a' 或 'B'。Char 值用单引号括起来 string - 存储文本,如 "Hello World"。String 值用双引号括起来 bool - 存储具有两个状态的值:true 或 false
39 2