Laden...

MandelbrotGenerator.GenerateImage (C#, WPF)

Erstellt von HansWilli vor einem Jahr Letzter Beitrag vor einem Jahr 320 Views
H
HansWilli Themenstarter:in
2 Beiträge seit 2022
vor einem Jahr
MandelbrotGenerator.GenerateImage (C#, WPF)

Hallo,
ich fange gerade mit c# und WPF an und hatte keine Idee für ein Programm, daher habe ich ein wenig im Internet gesucht und habe ein Programm zur Erzeugung von Mandelbrotmengen gefunden (hübsche Bilder).
Leider hängt das Programm an einer Stelle und ich verstehe nicht warum. The name 'MandelbrotGenerator.GenerateImage' does not exist in the current context.
Was muss ich machen?
Lieben Dank
Hans


private void Render()
        {
            MandelbrotGenerator.GenerateImage(
                bmp,
                centerX - (bmp.PixelWidth / 2) * step,
                centerY - (bmp.PixelHeight / 2) * step,
                step,
                depth,
                colors.GeneratePalette(depth));
        }

Das ganze Programm findet man hier:
https://developershell.net/the-mandelbrot-set-in-wpf/

bzw. hier hab ich das Listing kopiert. Den WPF Teil habe ich mal weggelassen.


using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;

namespace Mandelbrot3
{

    public partial class MainWindow : Window
    {
        WriteableBitmap bmp = new WriteableBitmap(
            (int)SystemParameters.PrimaryScreenWidth,
            (int)SystemParameters.PrimaryScreenHeight,
            96,
            96,
            PixelFormats.Bgr24,
            null);
        GradientColorGenerator colors = new GradientColorGenerator();
        int depth = 100;
        double step = 0.002;
        double centerX = -0.5;
        double centerY = 0;

        public MainWindow()
        {
            InitializeComponent();
            Render();
            img.ImageSource = bmp;
         
        }

        protected override void OnMouseDown(MouseButtonEventArgs e)
        {
            var p = e.GetPosition(this);
            centerX += (p.X - bmp.PixelWidth / 2) * step;
            centerY += (p.Y - bmp.PixelHeight / 2) * step;
            Render();

            base.OnMouseDown(e);
        }

        protected override void OnMouseWheel(MouseWheelEventArgs e)
        {
            if (Keyboard.Modifiers.HasFlag(ModifierKeys.Shift))
            {
                depth = (int)(e.Delta > 0 ? 1.1 * depth : 0.9 * depth);
            }
            else
            {
                step *= e.Delta > 0 ? 0.9 : 1.1;
            }

            Render();

            base.OnMouseWheel(e);
        }

        private void Render()
        {
            MandelbrotGenerator.GenerateImage(    // [b]hier ist das Problem: The name 'MandelbrotGenerator.GenerateImage' does not exist in the current context.[/b]
                bmp,
                centerX - (bmp.PixelWidth / 2) * step,
                centerY - (bmp.PixelHeight / 2) * step,
                step,
                depth,
                colors.GeneratePalette(depth));
        }

        public static void GenerateImage(WriteableBitmap bmp,
    double startX, double startY, double step, int[] palette)
        {
            long buffer = 0;
            var stride = 0;
            var width = 0;
            var height = 0;

            bmp.Dispatcher.Invoke(() =>
            {
                bmp.Lock();
                buffer = (long)bmp.BackBuffer;
                stride = bmp.BackBufferStride;
                width = bmp.PixelWidth;
                height = bmp.PixelHeight;
            });

            
            {
                Parallel.For(0, height, j =>
                {
                    Parallel.For(0, width, i =>
                    {
                        var pixel = buffer + j * stride + i * 3;
                        pixel = palette[Iterate(
                            startX + i * step,
                            startY + j * step,
                            palette.Length)];
                    });
                });
            }

            bmp.Dispatcher.Invoke(() =>
            {
                bmp.AddDirtyRect(new Int32Rect(0, 0, width, height));
                bmp.Unlock();
            });
        }

        static int Iterate(double x, double y, int limit)
        {
            var x0 = x;
            var y0 = y;
            for (var i = 0; i < limit; i++)
            {
                if (x * x + y * y >= 4)
                    return i;

                var zx = x * x - y * y + x0;
                y = 2 * x * y + y0;
                x = zx;
            }

            return 0;
        }
    }

}
internal class GradientColorGenerator
{

    private readonly IList<dynamic> _stops = new List<dynamic>
        {
            new {v=0.000f, r=0.000f, g=0.000f, b=0.000f },
            new {v=0.160f, r=0.125f, g=0.420f, b=0.796f },
            new {v=0.420f, r=0.930f, g=1.000f, b=1.000f },
            new {v=0.642f, r=1.000f, g=0.666f, b=0.000f },
            new {v=1.000f, r=0.000f, g=0.000f, b=0.000f },
        };

    public int[] GeneratePalette(int depth)
    {
        var x = new int[depth];
        for (int i = 0; i < depth; i++)
        {
            x[i] = GetColor(i / (float)depth);
        }
        return x;
    }

    private int GetColor(float p)
    {
        if (p > 1) p = 1;
        for (int i = 0; i < _stops.Count; i++)
        {
            if (_stops[i].v <= p && _stops[i + 1].v >= p)
            {
                var s0 = _stops[i];
                var s1 = _stops[i + 1];
                var pos = (p - s0.v) / (s1.v - s0.v);
                var rpos = 1 - pos;
                var r = rpos * s0.r + pos * s1.r;
                var g = rpos * s0.g + pos * s1.g;
                var b = rpos * s0.b + pos * s1.b;
                return
                    Convert.ToByte(r * 255) << 16 |
                    Convert.ToByte(g * 255) << 8 |
                    Convert.ToByte(b * 255);
            }
        }

        return 0;
    }
}

Hinweis von gfoidl vor einem Jahr

Bitte die [__csharp]-Tags für den Code verwenden, das erleichtert das Helfen!

4.931 Beiträge seit 2008
vor einem Jahr

Hallo und willkommen,

da du die Methode GenerateImage in deiner MainWindow-Klasse erstellt hast (und nicht, wie wohl im anderen Sourcecode, in einer extra Klasse) reicht es nur den Methodennamen beim Aufruf anzugeben:


GenerateImage(...);

PS: Trotzdem wäre es designtechnisch sinnvoller, die Berechnungsmethoden in eine andere Klasse auszulagern.

Außerdem solltest du deinen Code hier mit den C#-Tags formatieren!

H
HansWilli Themenstarter:in
2 Beiträge seit 2022
vor einem Jahr

Hi,
ja, du hast natürlich Recht,
jetzt gibt es wenigsten keine Fehlermeldung mehr.
aber ist ja nicht mein Code - wollte nur was spannendes zu lesen.
Die Klasse GradientColorGenerator hatte ich auch schon in externe Datei ausgelegt.
Refractory kommt jetzt...
Danke.
BR
Hans.