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”執行工程,顯示界面。
本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。