原文: 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工程
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIn5GcugjYmNmN1EDZzgDM4QTZ2ATZhFTOxEzMzkTOiNWZ3M2NfdWbp9CXt92Yu4GZjlGbh5SZslmZxl3Lc9CX6MHc0RHaiojIsJye.png)
二、添加代碼
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”執行工程,顯示界面。