wpf draw sin function motion via canvas and it's amplitude and frequency can adjust via slider which is more sensible

//xaml
<Window x:Class="WpfApp231.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:WpfApp231"
        mc:Ignorable="d"
        WindowState="Maximized"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition Height="100"/>
        </Grid.RowDefinitions>
        <Canvas Grid.Row="0" 
                Name="sinCanvas" 
                Background="White" 
                VerticalAlignment="Center"
                Height="700"/>

        <StackPanel Grid.Row="1" Orientation="Horizontal" VerticalAlignment="Bottom" Margin="10">
            <TextBlock Text="Amplitude:" VerticalAlignment="Center" Margin="5"/>
            <Slider Name="AmplitudeSlider" Minimum="10" Maximum="550" Value="150" Width="150" Margin="5"/>

            <TextBlock Text="Frequency:" VerticalAlignment="Center" Margin="5"/>
            <Slider Name="FrequencySlider" Minimum="0.01" Maximum="0.1" Value="0.02" Width="150" Margin="5"/>
        </StackPanel>
    </Grid>
</Window>




//cs
using System.Text;
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;
using System.Windows.Threading;

namespace WpfApp231
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    { 
        private DispatcherTimer timer;
        private double phase = 0;

        public MainWindow()
        {
            InitializeComponent();

            // Start animation timer
            timer = new DispatcherTimer();
            timer.Interval = TimeSpan.FromMilliseconds(16); // ~60 FPS
            timer.Tick += Timer_Tick;
            timer.Start();

            AmplitudeSlider.ValueChanged += (s, e) => Redraw();
            FrequencySlider.ValueChanged += (s, e) => Redraw();
        }

        private void Timer_Tick(object sender, EventArgs e)
        {
            phase += 0.1;
            Redraw();
        }

        private void Redraw()
        {
            sinCanvas.Children.Clear();

            double width = sinCanvas.ActualWidth;
            double height = sinCanvas.ActualHeight;

            if (width == 0 || height == 0)
            {
                return;
            }

            double amplitude = AmplitudeSlider.Value;
            double frequency = FrequencySlider.Value;

            Polyline sinePolyline = new Polyline
            {
                Stroke = Brushes.Blue,
                StrokeThickness = 5
            };

            for (int x = 0; x < width; x++)
            {
                double y = height / 2 - amplitude * Math.Sin(frequency * x + phase);
                sinePolyline.Points.Add(new Point(x, y));
            }

            sinCanvas.Children.Add(sinePolyline);
        }
    }
}

 

 

 

 

 

 

 

 

 

 

 

 

posted @ 2025-05-16 23:16  FredGrit  阅读(3)  评论(0)    收藏  举报