欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 健康 > 美食 > WPF绘制动态曲线

WPF绘制动态曲线

2024/10/26 5:33:15 来源:https://blog.csdn.net/weixin_43434464/article/details/140924583  浏览:    关键词:WPF绘制动态曲线

WPF绘制动态曲线
Direct2D

在这里插入图片描述

<Window x:Class="WpfApp2.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:local="clr-namespace:WpfApp2"mc:Ignorable="d"Title="MainWindow" Height="450" Width="800"><Grid><Image Name="DxImage"/></Grid>
</Window>
using System;
using System.Windows;
using System.Windows.Interop;
using System.Windows.Threading;
using SharpDX;
using SharpDX.Direct2D1;
using SharpDX.Direct3D11;
using SharpDX.DXGI;
using SharpDX.Mathematics.Interop;
using Device = SharpDX.Direct3D11.Device;
using Factory = SharpDX.Direct2D1.Factory;
using AlphaModeD2D = SharpDX.Direct2D1.AlphaMode;
using SharpDX.DirectWrite;
using System.Windows.Media;
using FactoryType = SharpDX.Direct2D1.FactoryType;
using TextAntialiasMode = SharpDX.Direct2D1.TextAntialiasMode;
using DashStyle = SharpDX.Direct2D1.DashStyle;
using SolidColorBrush = SharpDX.Direct2D1.SolidColorBrush;
using PathGeometry = SharpDX.Direct2D1.PathGeometry;namespace WpfApp2
{public partial class MainWindow : Window{private Device device;private SwapChain swapChain;private RenderTarget renderTarget;private Factory factory;private SharpDX.DirectWrite.Factory writeFactory;private TextFormat textFormat;private bool isResizing = false;private StrokeStyle strokeStyle;private DispatcherTimer timer;private float phase = 0;public MainWindow(){InitializeComponent();Loaded += MainWindow_Loaded;Unloaded += MainWindow_Unloaded;SizeChanged += MainWindow_SizeChanged;timer = new DispatcherTimer();timer.Interval = TimeSpan.FromMilliseconds(16); // 约60 FPStimer.Tick += Timer_Tick;timer.Start();}private void MainWindow_Loaded(object sender, RoutedEventArgs e){InitializeSharpDX();CompositionTarget.Rendering += CompositionTarget_Rendering;}private void MainWindow_Unloaded(object sender, RoutedEventArgs e){CompositionTarget.Rendering -= CompositionTarget_Rendering;DisposeResources();}private void MainWindow_SizeChanged(object sender, SizeChangedEventArgs e){if (swapChain != null && !isResizing){isResizing = true;try{renderTarget?.Dispose();swapChain.ResizeBuffers(1, (int)ActualWidth, (int)ActualHeight, Format.B8G8R8A8_UNorm, SwapChainFlags.None);CreateRenderTarget();UpdateTextFormat();}finally{isResizing = false;}}}private float speed = 0.15f;private void Timer_Tick(object sender, EventArgs e){phase += speed;if (phase > Math.PI * 2)phase -= (float)(Math.PI * 2);InvalidateVisual();}private void InitializeSharpDX(){factory = new Factory(FactoryType.SingleThreaded);writeFactory = new SharpDX.DirectWrite.Factory();var swapChainDescription = new SwapChainDescription{BufferCount = 1,ModeDescription = new ModeDescription((int)ActualWidth, (int)ActualHeight, new Rational(60, 1), Format.B8G8R8A8_UNorm),IsWindowed = true,OutputHandle = new WindowInteropHelper(this).Handle,SampleDescription = new SampleDescription(1, 0),SwapEffect = SwapEffect.Discard,Usage = Usage.RenderTargetOutput};Device.CreateWithSwapChain(SharpDX.Direct3D.DriverType.Hardware, DeviceCreationFlags.BgraSupport, swapChainDescription, out device, out swapChain);UpdateTextFormat();CreateRenderTarget();CreateStrokeStyle();}private void UpdateTextFormat(){textFormat?.Dispose();float fontSize = (float)(Math.Min(ActualWidth, ActualHeight) * 0.02);textFormat = new TextFormat(writeFactory, "Arial", fontSize){TextAlignment = SharpDX.DirectWrite.TextAlignment.Center,ParagraphAlignment = SharpDX.DirectWrite.ParagraphAlignment.Center};}private void CreateRenderTarget(){using (var surface = swapChain.GetBackBuffer<Surface>(0)){var properties = new RenderTargetProperties(new SharpDX.Direct2D1.PixelFormat(Format.Unknown, AlphaModeD2D.Premultiplied));renderTarget = new RenderTarget(factory, surface, properties){AntialiasMode = AntialiasMode.PerPrimitive,TextAntialiasMode = TextAntialiasMode.Cleartype};}}private void CreateStrokeStyle(){strokeStyle?.Dispose();strokeStyle = new StrokeStyle(factory, new StrokeStyleProperties{DashStyle = DashStyle.Solid,LineJoin = LineJoin.Round,StartCap = CapStyle.Round,EndCap = CapStyle.Round});}private void CompositionTarget_Rendering(object sender, EventArgs e){if (renderTarget == null || isResizing)return;renderTarget.BeginDraw();DrawScene();renderTarget.EndDraw();swapChain.Present(1, PresentFlags.None);}private void DrawScene(){renderTarget.Clear(new RawColor4(1, 1, 1, 1)); // 清空画布,设置为白色背景using (var axisBrush = new SharpDX.Direct2D1.SolidColorBrush(renderTarget, new RawColor4(0, 0, 0, 1)))using (var curveBrush = new SolidColorBrush(renderTarget, new RawColor4(0, 0, 1, 1)))using (var textBrush = new SolidColorBrush(renderTarget, new RawColor4(0, 0, 0, 1))){float width = (float)renderTarget.Size.Width;float height = (float)renderTarget.Size.Height;float margin = Math.Min(width, height) * 0.1f;float axisLength = Math.Min(width, height) * 0.8f;// 画 X 轴renderTarget.DrawLine(new RawVector2(margin, height / 2),new RawVector2(width - margin, height / 2),axisBrush, 2);// 画 Y 轴renderTarget.DrawLine(new RawVector2(width / 2, margin),new RawVector2(width / 2, height - margin),axisBrush, 2);// 添加 X 轴和 Y 轴的刻度线和标签AddAxisTicksAndLabels(width, height, margin, axisBrush, textBrush);// 生成正弦波的点var points = GenerateSineWavePoints(width, height, margin, phase);using (var geometry = new PathGeometry(factory)){var sink = geometry.Open();sink.BeginFigure(points[0], FigureBegin.Hollow);for (int i = 1; i < points.Length; i++){sink.AddLine(points[i]);}sink.EndFigure(FigureEnd.Open);sink.Close();renderTarget.DrawGeometry(geometry, curveBrush, 2, null);}}}private void AddAxisTicksAndLabels(float width, float height, float margin, SharpDX.Direct2D1.SolidColorBrush axisBrush, SolidColorBrush textBrush){int numberOfTicks = 10;float xTickSpacing = (width - 2 * margin) / numberOfTicks;float yTickSpacing = (height - 2 * margin) / numberOfTicks;for (int i = 0; i <= numberOfTicks; i++){// X 轴刻度线float x = margin + i * xTickSpacing;renderTarget.DrawLine(new RawVector2(x, height / 2 - 5), new RawVector2(x, height / 2 + 5), axisBrush, 2);// X 轴标签DrawText(renderTarget, textBrush, x.ToString(), new RawVector2(x, height / 2 + 10));// Y 轴刻度线float y = margin + i * yTickSpacing;renderTarget.DrawLine(new RawVector2(width / 2 - 5, y), new RawVector2(width / 2 + 5, y), axisBrush, 2);// Y 轴标签DrawText(renderTarget, textBrush, ((height - y) / (height / 2) * 10).ToString(), new RawVector2(width / 2 + 10, y));}}private void DrawText(RenderTarget renderTarget, SolidColorBrush textBrush, string text, RawVector2 position){renderTarget.DrawText(text, textFormat, new RawRectangleF(position.X, position.Y, position.X + 50, position.Y + 20), textBrush);}private RawVector2[] GenerateSineWavePoints(float width, float height, float margin, float phase){int pointCount = 200;RawVector2[] points = new RawVector2[pointCount];float dx = (width - 2 * margin) / (pointCount - 1);float amplitude = height / 4;for (int i = 0; i < pointCount; i++){float x = margin + i * dx;float y = height / 2 + (float)Math.Sin(i * 0.05 + phase) * amplitude;points[i] = new RawVector2(x, y);}return points;}private void DisposeResources(){renderTarget?.Dispose();swapChain?.Dispose();device?.Dispose();factory?.Dispose();writeFactory?.Dispose();textFormat?.Dispose();strokeStyle?.Dispose();}}
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com