P
P
Pray Montana2021-07-09 13:19:37
WPF
Pray Montana, 2021-07-09 13:19:37

How to draw a fractal "Star"?

Despite applying the RotateTransform, subsequent stars in the fractal do not rotate. What is the best way to implement the rotation of the stars and make them continue in 4 ends, and not in 5?

Should be:
60e82247e14fa651982615.png
What happens:
60e8226ca4e18012050025.png

C# code

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 Star
{
    /// <summary>
    /// Логика взаимодействия для MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        const double scale = 0.35;
        const int depth = 4;
        double rotate = 0;
       
        public MainWindow()
        {
            InitializeComponent();
        }
        private void btnStart_Click(object sender, RoutedEventArgs e)
        {
            double xmid = image.Width / 2;
            double ymid = image.Height / 2;

            DrawStar(1, xmid, ymid, 100);
        }

        private void DrawStar(int level, double x, double y, double r)
        {
            const double offset = - Math.PI / 2;
            const double angle = 4 * Math.PI / 5;
            Polyline star = new Polyline();
            star.Stroke = Brushes.DarkRed;
            image.Children.Add(star);

            for (int i = 0; i <= 5; i++)
            {
                star.Points.Add(new Point((int)(x + r * Math.Cos(offset + i * angle)),
                    (int)(y + r * Math.Sin(offset + i * angle))));
              
                star.RenderTransform = new RotateTransform(rotate, x, y);

                if (level < depth)
                {
                    rotate += 72;
                    DrawStar(level + 1, x + r * Math.Cos(offset + i * angle),
                    y + r * Math.Sin(offset + i * angle), r * scale);
                }
            }
        }
    }
}


WPF Code
<Window x:Class="Star.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:Star"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <StackPanel>
            <StackPanel Orientation="Horizontal" 
              Margin="5,5,5,0" Background="#FFA6FF00">
            <Button Name="btnStart" Click="btnStart_Click" 
              Width="95.949" Content="Start" Height="29.618" 
              FontFamily="Times New Roman" 
              FontWeight="Bold" FontSize="16"/>
            <TextBlock Name="tbLabel" Margin="20,5,0,0"/>
            </StackPanel>
            <Canvas Name="image" Width="300" Height="300" Margin="5"></Canvas>
        </StackPanel>
    </Grid>
</Window>

Answer the question

In order to leave comments, you need to log in

2 answer(s)
T
twobomb, 2021-07-09
@praymontana

I'm dumb at the end of the day, well, maybe something like this

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 WpfApplication1
{
    /// <summary>
    /// Логика взаимодействия для MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        const double scale = 0.35;
        const int depth = 5;

        public MainWindow()
        {
            InitializeComponent();
            btnStart_Click(null, null);
        }
        private void btnStart_Click(object sender, RoutedEventArgs e)
        {
            double xmid = image.Width / 2;
            double ymid = image.Height / 2;

            DrawStar(1, xmid, ymid, 100, -1);
        }

        private void DrawStar(int level, double x, double y, double r, int skip, bool isRotate = true){
            double offset = isRotate? Math.PI / 2:-Math.PI / 2;
            const double angle = 4 * Math.PI / 5;
            Polyline star = new Polyline();
            star.Stroke = Brushes.DarkRed;
            image.Children.Add(star);


            for (int i = 0; i <= 5; i++){
                var angleT = offset +  i * angle;

                var lx = (int) (x + r*Math.Cos(angleT));
                var ly = (int) (y + r*Math.Sin(angleT));
                star.Points.Add(new Point(lx,ly));

                if (level < depth){
                    var newrad = r*scale;
                    var lx2 = (int)(x + (r + newrad) * Math.Cos(angleT));
                    var ly2 = (int)(y + (r + newrad) * Math.Sin(angleT));
                    if(i != skip && i !=5)
                            DrawStar(level + 1, lx2, ly2, newrad, i, !isRotate);

                }
            }
        }
    }
}

60e847566900e091965850.png

S
soloveid, 2021-07-09
@soloveid

You are working incorrectly with the rotation variable, most likely this is the error
you need to pass to the DrawStar method Somehow it should turn out like this
double rotate = 0;

void DrawStar(int level, double x, double y, double r,  double rotate)//<---- тут изменение
        {
            const double offset = - Math.PI / 2;
            const double angle = 4 * Math.PI / 5;

            Polyline star = new Polyline();
            star.Stroke = Brushes.DarkRed;
            image.Children.Add(star);

            for (int i = 0; i <= 5; i++)
            {
                star.Points.Add(new Point((int)(x + r * Math.Cos(offset + i * angle)),
                    (int)(y + r * Math.Sin(offset + i * angle))));
              
                star.RenderTransform = new RotateTransform(rotate, x, y);

                rotate += 360/5; //<----тут изменение
                if (level < depth)
                {
                    DrawStar(level + 1, x + r * Math.Cos(offset + i * angle),
                    y + r * Math.Sin(offset + i * angle), r * scale, rotate);//<---- тут изменение
                }
            }
        }

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question