P
P
Pray Montana2021-07-04 10:20:30
WPF
Pray Montana, 2021-07-04 10:20:30

How to do real-time graph rendering in WPF?

The graph is drawn instantly upon completion of the handler. How to make the graph draw gradually?

wpf code

<Window x:Class="Trajectory.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:Trajectory"
        mc:Ignorable="d"
        Title="MainWindow" Height="300" Width="450" Loaded="Window_Loaded">
    
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition/>
        </Grid.RowDefinitions>

        <Canvas x:Name="image" Grid.Column="0" Grid.Row="0" Margin="10"
                Loaded="image_Loaded"/>
    </Grid>
</Window>


c# code
using System;
using System.Timers;
using System.Windows;
using System.Windows.Media;
using System.Windows.Shapes;
using System.Windows.Controls;
using System.Collections.Generic;

namespace Trajectory
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private List<Point> points;

        public MainWindow()
        {
            InitializeComponent();
            points = new List<Point>(64);
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            Title = "Формирование траектории";
            Background = Brushes.LightGray;
            image.Background = Brushes.White;
        }

        private void image_Loaded(object sender, RoutedEventArgs e)
        {
            double InitT = 0, LastT = 6.3; // Оборот в 360 градусов (6,28 радиан)
            double Step = 0.1, angle = InitT;
            double x, y, x1, y1;
            int cX = 120, cY = 120; // Центр большой окружности
            int R2 = 90; // Радиус большой окружности
            int k = 20; // Число областей на траектории
            int R1 = R2 / k; // Радиус меньшей (движущейся) окружности
            int i = 0; // Количество точек прорисовки

            while (angle <= LastT)
            {
                x = R1 * (k - 1) * (Math.Cos(angle) + Math.Cos((k - 1) * angle) / (k - 1));
                y = R1 * (k - 1) * (Math.Sin(angle) - Math.Sin((k - 1) * angle) / (k - 1));
                points.Add(new Point(cX + (int)x, cY + (int)y)); // Расчет очередной точки траектории
                PaintGraphic(cX, cY, R2, (int)x, (int)y);
                x1 = (R2 - R1) * Math.Sin(angle + 1.57);
                y1 = (R2 - R1) * Math.Cos(angle + 1.57);
                PaintCircle(cX, cY, (int)x1, (int)y1, R1, (int)x, (int)y);
                angle += Step;
                i++;
                System.Threading.Thread.Sleep(40);
            }
        }

        private void DrawLine(Point start, Point end, Brush brush)
        {
            Line line = new Line();
            line.Stroke = brush;
            line.StrokeThickness = 3;
            line.X1 = start.X;
            line.Y1 = start.Y;
            line.X2 = end.X;
            line.Y2 = end.Y;
            image.Children.Add(line);
        }

        private void PaintCircle(int cX, int cY, int centX, int centY, int radius, int x, int y)
        {
            Ellipse ellipse = new Ellipse();
            ellipse.Stroke = Brushes.Black;
            ellipse.StrokeThickness = 3;
            ellipse.Width = 2 * radius;
            ellipse.Height = 2 * radius;
            ellipse.SetCurrentValue(Canvas.LeftProperty, (double)(centX + cX - radius));
            ellipse.SetCurrentValue(Canvas.TopProperty, (double)(cY - radius - centY));
            image.Children.Add(ellipse);

            DrawLine(new Point(centX + cX, cY - centY), new Point(cX + x, cY + y), Brushes.Black);
        }

        private void PaintGraphic(int cX, int cY, int r2, int x, int y)
        {
            image.Children.Clear();
            PaintCircle(cX, cY, 0, 0, r2, x, y);
            for (int i = 1; i < points.Count; ++i)
                DrawLine(points[i - 1], points[i], Brushes.Red);
        }
    }
}

Answer the question

In order to leave comments, you need to log in

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question