praymontana
@praymontana
Начинающий, туповат.

Как нарисовать фрактал «Звезда»?

Несмотря на применение RotateTransform, последующие звезды в фрактале не поворачиваются. Как лучше реализовать поворот звёзд и сделать так, чтобы они продолжались в 4-х концах, а не в 5-ти?

Должно быть:
60e82247e14fa651982615.png
Что получается:
60e8226ca4e18012050025.png

Код C#
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
<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>
  • Вопрос задан
  • 462 просмотра
Решения вопроса 1
twobomb
@twobomb
Ща туплю под конец дня, ну мож примерно так
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
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@soloveid
У Вас идёт неправильная работа с переменной поворота, скорее всего в этом ошибка
Вам надо
double rotate = 0;
передавать в метод DrawStar

Как-то так должно получиться
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);//<---- тут изменение
                }
            }
        }
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы