Autor Beitrag
Palladin007
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1282
Erhaltene Danke: 182

Windows 11 x64 Pro
C# (Visual Studio Preview)
BeitragVerfasst: Di 30.08.16 21:33 
'n Abend,

ich wollte mir auch mal die Fraktale anschauen und zeichen lassen und hab mit der Mandelbrot-Menge angefangen.
Dafür hab ich mir ein Beispiel-Projekt raus gesucht, was das tut, auf WPF portiert und dann den eigentlichen Kern heraus kristalisiert und so umgeschrieben, dass ich damit arbeiten kann.
Am Ende hab ich jetzt eine Methode, die alle Koordinaten durch geht und für jede Koordinate eine Action aufruft.
In dieser Action bekomme ich dann die Position im Control in Pixeln und die Koordinaten.

Die Koordinaten übergebe ich dieser Methode um die Farbe, die an der Position gesetzt werden soll, zu bekommen:

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
private Drawing.Color GetMandelColor(Drawing.PointF coordinates)
{
    double x = 0, y = 0;
    int colorId = 0;
            
    while (colorId < _colors.Length - 1 && Math.Sqrt(Math.Pow(x, 2) + Math.Pow(y, 2)) < 2)
    {                
        var newX = Math.Pow(x, 2) - Math.Pow(y, 2) + coordinates.X;
        var newY = x * y * 2 + coordinates.Y;

        x = newX;
        y = newY;

        colorId++;
    }

    return _colors[colorId];
}


Die Colors bekomme ich aus einem Farb-Set mit 256 Farben, was bei dem Beispiel-Projekt dabei war.
Ich habe explizit Math.Pow verwendet, weil es in meinen Augen dann besser erkennbar ist, dass da das Quadrat berechnet wird.

Ich hab mich dazu mal hier belesen.
Die Iteration ist jetzt auch nicht so kompliziert, zumindest nicht, wenn ich eine anständige Programmiersprache zum berechnen habe.

Aber so wie ich das verstanden habe, wird die Berechnung für jede Koordinate einzeln durchgeführt?
Das spiegelt sich aber überhaupt nicht in dem Code-Schnippsel wieder

Kann mir das jemand erklären?
Vielleicht hat ja unser hauseigener Mathematiker Lust? :)

Wenn ich das Konzept verstanden habe, möchte ich den eigentlichen reinen "Formel-Teil" in eine eigene Methode legen, in der Hoffnung, dass ich die eigentliche Berechnung dann z.B. als User-Eingabe in Form einer Formel ermöglichen kann, sodass bei dem Programm theoretisch jede beliebige Fraktal-Formel eingetragen werden kann.


Besten Dank :)
Mathematiker
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 2622
Erhaltene Danke: 1447

Win 7, 8.1, 10
Delphi 5, 7, 10.1
BeitragVerfasst: Di 30.08.16 22:01 
Hallo,
gleich vornweg, mit C# kenne ich mich nicht aus. Daher kann ich nur eine Delphi-Routine erläutern.

Für jeden Punkt der komplexen Gaußschen Zahlenebene musst du die Berechnung einzeln ausführen. In meinem Beispiel läuft der Realteil der Zeichenebene von -2.5 bis 2.5, der Imaginärteil von -2.5i bis 2.5i, d.h. jeweils Intervallbreiten von 5.

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
procedure mandelbrotmenge;
var i,j,anz,b,h:integer; 
    x,y,cx,cy,xneu,yneu:double;
begin
  b:=paintbox1.width; 
  h:=paintbox1.height;
  
  for i:=1 to b do begin
   for j:=1 to h do begin
     cx:=5*i/b-2.5;          //Transformation des Pixels in komplexe Zahl
     cy:=5*j/h-2.5
     x:=0; y:=0
     anz:=0;
     repeat
       xneu:=x*x-y*y+cx;     //klassisches Apfelmännchen 
       yneu:=2*x*y+cy; 
       x:=xneu; 
       y:=yneu; 
       inc(anz);
     until (x*x+y*y>4or    //bei Betrag der komplexen Zahl >=2 ist die Divergenz der Folge sicher
           (anz>100);        //Genauigkeit der Berechnung
     paintbox1.canvas.pixels[i,j]:=rgb(2*anz, 2*anz, 2*anz);   //keine schöne Farbwahl
  end end;
end;

Die Berechnung breche ich ab, wenn entweder Divergenz sicher ist, d.h. x²+y²>4 ist (keine Wurzel!), oder die Konvergenz "wahrscheinlich" ist. Hier nehme ich 100 Iterationen; für eine exaktere Darstellung entsprechend mehr.

Für eine allgemeine Routine, d.h. mit beliebigen komplexen Funktionen und nicht nur z²+c, wirst du wohl einen Parser für komplexe Funktionen brauchen und damit die komplexe Zahl xneu + i yneu berechnen.
Ich hoffe, dass ich deine Frage richtig verstanden habe.

Beste Grüße
Mathematiker

Nachtrag: Ich hänge den Parser für komplexe Funktionen (Delphi!) mal an. Der Code ist "exotisch", da ein paar Teile aus verschiedenen Quellen zusammengestückelt wurde.
Ich verwende die Routine in www.entwickler-ecke....highlight=phasenplot .
Einloggen, um Attachments anzusehen!
_________________
Töten im Krieg ist nach meiner Auffassung um nichts besser als gewöhnlicher Mord. Albert Einstein


Zuletzt bearbeitet von Mathematiker am Di 30.08.16 22:07, insgesamt 1-mal bearbeitet
FinnO
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1331
Erhaltene Danke: 123

Mac OSX, Arch
TypeScript (Webstorm), Kotlin, Clojure (IDEA), Golang (VSCode)
BeitragVerfasst: Di 30.08.16 22:06 
Moin,

da beginnt man gerade, eine Antwort zu schreiben, da ist der Mathematiker schneller. Mein Wrap-Up des Mandelbrot-Algorithmus:

ausblenden Quelltext
1:
2:
3:
4:
5:
6:
Für jeden Pixel in deinem Bild:
  Transfomiere den Pixel in eine Komplexe Zahl z
        z = z^2 + z;
  Zähle nach wie vielen Iterationen z noch in der Mandelbrotmenge enthalten ist. 
            Oder breche ab wenn Anzahl der Iterationen > Konstante
  Färbe den Pixel entsprechend der Anzahl der Iterationen.


Und (fast genau so lang) in JavaScript hier.

Gruß
Finn
gerd8888
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 205
Erhaltene Danke: 3

Win7
Delphi 10.1 Starter (kostenlos) Lazarus
BeitragVerfasst: Di 30.08.16 22:23 
Ich kenne dieses Beispiel auch. Es steht z.B. im Buch von Henning Mittelbach (Programmierkurs Turbo Pascal), die guten alten Bücher.
Benoit Mandelbrot (1924 - 2010)
Palladin007 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1282
Erhaltene Danke: 182

Windows 11 x64 Pro
C# (Visual Studio Preview)
BeitragVerfasst: Di 30.08.16 22:26 
Die Konstante (bei mir 2) ist also der Grenzwert, ab dem nicht weiter gerechnet wird, soweit so klar.
Aber woher bekomme ich denn die Konstante?
In meinem Beispiel sind auch noch die folgenden Werte dabei:
Zitat:
xMin = -2.1
yMin = -1.3
xMax = 1
yMax = 1.3

Also die jeweiligen Minimum/Maximum-Werte jeder Achse.
Da weiß ich auch nicht, woher die kommen. Sie scheinen die jeweiligen Maximum/Minimum-Werte, die es in der Mandelbrot-Menge gibt, einzugrenzen, sodass das Koordinatensystem nicht zu groß oder zu klein sind.
Kann es sein, dass ich die Werte berechnen muss, indem ich die ganze Mandelbrot-Berechnung einmal so durch führe und schaue, was die jeweiligen Minimum/Maximum-Werte sind?



Und wie hängt die Berechnung mit der Formel zusammen?
Wie komme ich von der Formel:
Zitat:
Z(n) = Z(n-1)² + C

zu der Berechnung im Code bzw. umgekehrt?

So wie ich die Formel verstanden habe, würde ich die so im Code umsetzen:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
private double Mandelbrot(double value)
{
    var result = 0d;

    for (int i = 0; i < 100; i++)
    {
        result = result * result + value;
    }

    return result;
}

Was aber jetzt nicht wirklich das ist, was ich hier habe ...




Die Formel zu parsen, darum kümmere ich mich dann schon, mir geht's rein um das Verständnis ^^
Ich weiß auch nicht, ob ich mit deinem Parser klar komme, Mathematiker, ich kann Delphi zwar halbwegs lesen, aber sobald es komplexer wird, muss ich aussteigen :D
Aber darum kümmere ich mich, wenn es soweit ist, erst einmal möchte ich soweit sein, jede dieser Formeln in eine Methode umsetzen zu können, die mir sagt, ob ein Punkt in der Menge ist oder nicht, denn dann ist das ganze austauschbar und fügt sich nahtlos in den Rest ein.



Edit:

Zitat:
Transfomiere den Pixel in eine Komplexe Zahl z


Wie meinst Du das, FinnO?
FinnO
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1331
Erhaltene Danke: 123

Mac OSX, Arch
TypeScript (Webstorm), Kotlin, Clojure (IDEA), Golang (VSCode)
BeitragVerfasst: Di 30.08.16 22:42 
user profile iconPalladin007 hat folgendes geschrieben Zum zitierten Posting springen:
Die Konstante (bei mir 2) ist also der Grenzwert, ab dem nicht weiter gerechnet wird, soweit so klar.
Und wie hängt die Berechnung mit der Formel zusammen?
Wie komme ich von der Formel:
Zitat:
Z(n) = Z(n-1)² + C

zu der Berechnung im Code bzw. umgekehrt?


Ah, ich erkenne das Problem. Alle Codebeispiele, die bisher vorgebracht wurden, arbeiten nicht mit nativen Datentypen für komplexe Zahlen. Eine Komplexe Zahl z \in \mathbb{C} kann z.B. so aufgeschrieben werden: z = x + y\cdot i mit i = \sqrt{-1}. Man nennt dann x den Realteil und y den Imaginärteil der komplexen Zahl. Demzufolge ist dann das Quadrat der komplexen Zahl z:

z^2 = (x + iy)(x + iy) = x^2 + 2i\cdot x\cdot y + i^2 y^2. Teilt man dieses Ergebnis wieder nach Realteil und Imaginärteil auf, erhält man:
Re{z^2} = x^2 - y^2 und Im{z^2} = 2xy. Durch messerscharfes hingucken lässt sich so die Formel im Code erkennen.


user profile iconPalladin007 hat folgendes geschrieben Zum zitierten Posting springen:
Zitat:
Transfomiere den Pixel in eine Komplexe Zahl z


Wie meinst Du das, FinnO?


Die Pixelkoordinaten einer Zeichenfläche sind ja üblicherweise Integer zwischen 0 und der jeweils maximalen Größe der Fläche. Deine Mandelbrotfunktion möchte aber eine komplexe Zahl als Eingabewert. Man muss also eine beliebige Transformation wählen, die die Pixelposition auf eine solche Zahl abbildet, man kann z.B. den Y-Wert des Pixels als Imaginärteil und den X-Wert des Pixels als Realteil verwenden.

user profile iconPalladin007 hat folgendes geschrieben Zum zitierten Posting springen:

So wie ich die Formel verstanden habe, würde ich die so im Code umsetzen:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
private double Mandelbrot(double value)
{
    var result = 0d;

    for (int i = 0; i < 100; i++)
    {
        result = result * result + value;
    }

    return result;
}

Was aber jetzt nicht wirklich das ist, was ich hier habe ...


Der Code würde in C# (minus meine Syntaxfehler, die ich hier beim Blindtippen mache) richtig lauten:

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
using System.Numeric;

private int Mandelbrot(Complex<double> value)
{
    var result = value;
    var i = 0;

    while(i < 100 && Complex<double>.Abs(value) < 2)
    {
        result = Complex<double>.Pow(result, 2) + value;
  i++;
    }

    return i;
}


Siehe hierzu auch die Dokumentation von System.Numerics.
Den Rückgabewert dieser Funktion muss man dann auf eine Farbe abbilden.

BG
Finn


Zuletzt bearbeitet von FinnO am Di 30.08.16 22:52, insgesamt 3-mal bearbeitet
Frühlingsrolle
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Di 30.08.16 22:44 
- Nachträglich durch die Entwickler-Ecke gelöscht -
Palladin007 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1282
Erhaltene Danke: 182

Windows 11 x64 Pro
C# (Visual Studio Preview)
BeitragVerfasst: Di 30.08.16 23:24 
Das mit den komplexen Zahlen hat mir gefehlt, jetzt gibt das auch alles Sinn :D
Danke für den Tipp ^^ (Complex ist nicht generisch :P)

Ich hab in der Zwischenzeit das ganze auch mal auf asynchron umgebaut, lief mit dem vorherigen Code dadurch rund doppelt so schnell.
Mit deiner Variante leicht angepasst (max iterations als Parameter) hab ich dann aber das Problem, dass mir das Ding den ganzen Rechner zum hängen bringt, weil sich das Programm irgendwo aufhängt und dabei konsequent alle Kerne blockiert :D

Ich weiß noch nicht, woran das liegt, kann aber auch an meinen Änderungen liegen.



Bis dahin habe ich aber noch zwei Fragen:

Die Werte (in meinem Beispiel xMin, yMin, xMax und yMax) beschreiben die Grenzen des Koordinatensystems, welcher Bereich dargestellt wird.
Liege ich richtig in der Annahme, dass ich die nicht "einfach" berechnen kann, sondern nur, indem ich ausprobiere, ob die Menge in dem dadurch aufgezeigten Bereich liegt?
Sprich: Ich setze Fix-Werte, rechne das für alle Punkte einmal durch und wenn die Menge größer ist, erhöhe ich entsprechend, bis ich die Minimal/Maximal-Werte habe
Oder gibt es da eine einfachere bzw. schnellere Möglichkeit?

In jedem Code, den ich bisher dazu gesehen habe, wird die Summe aus dem Quadrat der beiden Werte auf > Zahl geprüft.
Bei mir ists die 2, bei Mathematiker ist es die 4.
Woher kommt der Wert? Ist damit der Maximalwert gemeint, der sowohl auf der Y- als auch der X-Achse erlaubt ist? Und wenn ich vorher errechnet habe, dass der X-Wert nicht über 2 sein kann, kann ich in dieser Prüfung getrost auf 2 setzen?




PS:
Ich hab meinen Fehler gefunden.
In der Prüfung, bei Complex.Abs hatte ich den Wert, der als Parameter mitgegeben wurde, nicht der zuvor berechnete Wert.
Jetzt läuft alles wunderbar :)
Mathematiker
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 2622
Erhaltene Danke: 1447

Win 7, 8.1, 10
Delphi 5, 7, 10.1
BeitragVerfasst: Mi 31.08.16 06:57 
Hallo,
user profile iconPalladin007 hat folgendes geschrieben Zum zitierten Posting springen:
In jedem Code, den ich bisher dazu gesehen habe, wird die Summe aus dem Quadrat der beiden Werte auf > Zahl geprüft. Bei mir ists die 2, bei Mathematiker ist es die 4.
Woher kommt der Wert? Ist damit der Maximalwert gemeint, der sowohl auf der Y- als auch der X-Achse erlaubt ist? Und wenn ich vorher errechnet habe, dass der X-Wert nicht über 2 sein kann, kann ich in dieser Prüfung getrost auf 2 setzen?

Die Berechnung wird abgebrochen, wenn der Betrag der komplexen Zahl sqrt(x^2+y^2) größer als 2 ist.
Zur Beschleunigung der Berechnung spare ich mir das Wurzelziehen und teste ob x^2+y^2>4. Mehr ist das nicht.
Die 2 ergibt sich aus einem nicht ganz einfachen Beweis, dass beim Erreichen dieses Betrages der komplexen Zahl nur noch Divergenz zu erwarten ist, d.h. die komplexe Zahl wird dem Betrag nach bei jeder weiteren Berechnung größer.

Beste Grüße
Mathematiker

_________________
Töten im Krieg ist nach meiner Auffassung um nichts besser als gewöhnlicher Mord. Albert Einstein
OlafSt
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 486
Erhaltene Danke: 99

Win7, Win81, Win10
Tokyo, VS2017
BeitragVerfasst: Mi 31.08.16 10:00 
Ich nenne das mal eine sehr clevere Methode der Optimierung.

Wie viele hätten versucht, eine noch schnellere Version von SQRT zu basteln und viel Zeit dafür aufgewandt... Anstatt es einfach wegzulassen und mit dem Nicht-Wurzelgezogenen 4 (was ja 2^2 ist) zu arbeiten. Respekt, @Mathematiker.

_________________
Lies, was da steht. Denk dann drüber nach. Dann erst fragen.
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4764
Erhaltene Danke: 1052

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Mi 31.08.16 12:41 
Dies ist aber eine altbekannte Optimierung. Hat man z.B. auch beim Ermitteln, ob zwei Punkte einen bestimmten Radius unter- bzw. überschreiten:
ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
// in Pseudocode

// statt
IF (SQRT((x1-x2)^2 + (y1-y2)^2) < R)

// dann
IF ((x1-x2)^2 + (y1-y2)^2 < R^2)
// bzw.
IF ((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2) < R*R)
Palladin007 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1282
Erhaltene Danke: 182

Windows 11 x64 Pro
C# (Visual Studio Preview)
BeitragVerfasst: Mi 31.08.16 12:45 
Ok, dann nehme ich die Wurzel bei mir auch mal raus :D
Braucht auch noch zu lange, für meinen Geschmack, mal schauen, wo ich da optimieren kann. Ich will ja nicht bis zur Darstellung warten müssen


Zitat:
Die 2 ergibt sich aus einem nicht ganz einfachen Beweis, dass beim Erreichen dieses Betrages der komplexen Zahl nur noch Divergenz zu erwarten ist

Lohnt es sich, das zu berechnen?
Ich möchte ja auch andere Formeln darstellen können, ändert sich dieser Wert denn nich auch mit der Formel?
Palladin007 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1282
Erhaltene Danke: 182

Windows 11 x64 Pro
C# (Visual Studio Preview)
BeitragVerfasst: Mi 31.08.16 14:52 
So, die Berechnung dauert bei mir jetzt unter 200ms, vorher über 5 Sekunden.
Der Flaschenhals war das SetPixel von Bitmap, das mache ich jetzt manuell byte für byte im unsafe-Code. Dazu noch komplett parallel.
Außerdem macht der Complex-Typ das recht langsam. Ich hab es jetzt auf die manuelle Berechnung und ohne Math-Klasse reduziert.


Allerdings habe ich jetzt immer noch das Problem: Wenn ich sehr weit ran zoome, dann wird irgendwann nicht weiter berechnet, das sieht dann nur noch sch**** aus.
Kann das daran liegen, dass ich mit double arbeite? Ich hab testweise mal decimal genommen, allerdings dauert jetzt jede Berechnung über 12 Sekunden, das geht garnicht...


PS:
Wenn wer den Code haben will, einfach Bescheid sagen.
Ist aber unkommentiert und C#, Delphi-Leute werden es also nicht ganz so einfach haben :P
Mathematiker
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 2622
Erhaltene Danke: 1447

Win 7, 8.1, 10
Delphi 5, 7, 10.1
BeitragVerfasst: Mi 31.08.16 15:59 
Hallo,
user profile iconPalladin007 hat folgendes geschrieben Zum zitierten Posting springen:
Wenn ich sehr weit ran zoome, dann wird irgendwann nicht weiter berechnet, das sieht dann nur noch sch**** aus.
Kann das daran liegen, dass ich mit double arbeite?

Double sollte i.A. genügen. Allerdings musst du für kleinere Intervalle die maximale Anzahl von Iterationen erhöhen. Bei hohen Vergrößerungen nutze ich 5000 Iterationen. Das dauert zwar länger, aber die Berechnung wird exakter.
Übrigens ist bei meiner Mandelbrotlösung (mathematikalpha.de Teilprogramm Chaostheorie/Mandelbrotmenge, Juliamenge) eine maximale Vergrößerung von 1 : 60 Billionen möglich. Dann genügt die Genauigkeit von double nicht mehr.

user profile iconPalladin007 hat folgendes geschrieben Zum zitierten Posting springen:
Zitat:
Die 2 ergibt sich aus einem nicht ganz einfachen Beweis, dass beim Erreichen dieses Betrages der komplexen Zahl nur noch Divergenz zu erwarten ist
Ich möchte ja auch andere Formeln darstellen können, ändert sich dieser Wert denn nich auch mit der Formel?

Ja, leider. Die Abbruchbedingung ist vom Fraktaltyp abhängig. Ich kenne keine Möglichkeit, wie man diese Grenze ermittelt. Daher nutze ich meist die 2 und es funktioniert ganz gut.

Beste Grüße
Mathematiker

_________________
Töten im Krieg ist nach meiner Auffassung um nichts besser als gewöhnlicher Mord. Albert Einstein
Palladin007 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1282
Erhaltene Danke: 182

Windows 11 x64 Pro
C# (Visual Studio Preview)
BeitragVerfasst: Mi 31.08.16 19:40 
Ich hab mir jetzt mal dein Programm herunter geladen und ausprobiert.
Da ich bei mir das Problem hatte, dass das Bild ziemlich unschön aussieht, wenn ich sehr weit rein zoome, hab ich das bei deiner Variante auch mal ausprobiert.
Im Dateianhang gibts einen Screenshot davon

Es verzerrt sich auch
Wenn ich näher ran gehe, verstärkt sich der Effekt nur noch.


Erwarte ich da zu viel von der Mandelbrot-Menge? Ist das so nahe, dass es da diese Muster einfach nicht mehr gibt?
Oder liegt das an was Anderem?


PS:
Und wie schaffst Du es, dass es bei 10k Iterationen trotzdem nach relativ schnell geht? :D
Laut der Anzeige rechts oben nur 3 Sekunden
Einloggen, um Attachments anzusehen!
Palladin007 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1282
Erhaltene Danke: 182

Windows 11 x64 Pro
C# (Visual Studio Preview)
BeitragVerfasst: Mi 31.08.16 20:01 
Oder ist das die Ungenauigkeit von double bzw. dem Typ, den Du verwendest?

Ich hab bei mir ein Check eingebaut, der prüft, dass MinX kleiner als MaxX sein muss.
Mit dem Check kann ich gar nicht so nahe heran gehen, da die Werte vorher schon als Gleich aufgefasst werden.
Mathematiker
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 2622
Erhaltene Danke: 1447

Win 7, 8.1, 10
Delphi 5, 7, 10.1
BeitragVerfasst: Mi 31.08.16 20:02 
Hallo,
user profile iconPalladin007 hat folgendes geschrieben Zum zitierten Posting springen:
Es verzerrt sich auch. Wenn ich näher ran gehe, verstärkt sich der Effekt nur noch.

Das ist normal und geschieht, wenn x-Intervall und y-Intervall nicht die gleiche Auflösung haben. Dazu habe ich in der Schalterleiste den 7.Schalter "Auflösung anpassen".
Ist das y-Intervall für die Höhe der Ausgabe(Bitmap?) zu klein, im Vergleich zum x-Intervall, wie in dem von dir angehängten Bild, so gibt es diese Verzerrung.

user profile iconPalladin007 hat folgendes geschrieben Zum zitierten Posting springen:
Und wie schaffst Du es, dass es bei 10k Iterationen trotzdem nach relativ schnell geht? :D
Laut der Anzeige rechts oben nur 3 Sekunden

Die Berechnung erfolgt mittels ASM. In Kombination mit scanline, bei dem nur die Farben zeilenweise in einem Bitmap geändert werden und zu gegebener Zeit das Bitmap kopiert wird, wird es dann hinreichend schnell.

Beste Grüße
Mathematiker

Der nachfolgende Delphi-Text funktioniert allein natürlich nicht und ist vielleicht auch nicht besonders schön, aber vielleicht hilft er dir doch ein kleines Bisschen.

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
PROCEDURE PaintApple;
VAR radius,a,b,da,db,xf,yf,invers : double;
          i,it,xs,ys : word;
    rowrgb : pbytearray;
BEGIN
  it :=ein_int(e1);
  da := (_x2-_x1) / breite;
  db := (_y2-_y1) / hoehe;
  radius := 9;
  QueryPerformanceCounter(Time1);
  b := _y2;
  FOR ys:=0 TO hoehe-1 DO BEGIN
    rowrgb:=tempbitmap.scanline[ys];
    b := b - db;
    a := _x1;
    FOR xs:=0 TO breite-1 DO BEGIN
      a := a + da;
      xf:=a;
      yf:=b;
    ASM
         FLD     radius
         FLD     xf
         FLD     yf
         FLD     st
         FMUL    st,st
         FLD     st(2)
         FMUL    st,st
         FLD     st(2)
         FLD     st(4)
         XOR     cx,cx
@itloop: INC     cx
         CMP     cx,it
         JE      @noloop
         FMUL
         FADD    st,st
         FADD    st,st(3)
         FLD     st(1)
         FSUB    st,st(3)
         FADD    st,st(5)
         FST     st(3)
         FMUL    st,st
         FSTP    st(2)
         FLD     st
         FMUL    st,st
         FADD    st,st(2)
         FCOM    st(6)
         FSTSW   ax
         FSUB    st,st(2)
         FXCH    st(3)
         AND     ah,1
         JNZ     @itloop
@noloop: MOV     i, cx
         FINIT
      END;
      if i>=it then begin
        if farbverlauf then i:=(round(100.0*modus*(sqr(a)+sqr(b)))) mod 256
                       else i:=0
      end
      else i:=(modus*i) mod 256;
      farbfeld[xs,ys]:=i;
      rowrgb[3*xs]:=pal[i].b;
      rowrgb[3*xs+1]:=pal[i].g;
      rowrgb[3*xs+2]:=pal[i].r;
    END;
    QueryPerformanceCounter(Time2);
    if time2-time1>abbruchtime then begin
      application.processmessages;
      if abbruch then exit;
      PB1.canvas.draw(0,0,tempbitmap);
      time1:=time2;
    end;
  END;
  PB1.canvas.draw(0,0,tempbitmap);
END;

_________________
Töten im Krieg ist nach meiner Auffassung um nichts besser als gewöhnlicher Mord. Albert Einstein
Delphi-Laie
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1600
Erhaltene Danke: 232


Delphi 2 - RAD-Studio 10.1 Berlin
BeitragVerfasst: Mi 31.08.16 22:53 
user profile iconOlafSt hat folgendes geschrieben Zum zitierten Posting springen:
Ich nenne das mal eine sehr clevere Methode der Optimierung.

Wie viele hätten versucht, eine noch schnellere Version von SQRT zu basteln und viel Zeit dafür aufgewandt... Anstatt es einfach wegzulassen und mit dem Nicht-Wurzelgezogenen 4 (was ja 2^2 ist) zu arbeiten.


Derlei Banalitäten sollten eigentlich jedem intellektuell flexiblen (!!) Abiturienten einfallen. Stichwort: (Un-)Gleichungsbehandlung, (Un-)Gleichungstransformation in Richtung Vereinfachung. Dazu muß (müßte) man "nur" simples mathematisches Rüstzeug anwendungsbereit in einem anderen Fach anwenden.
mandras
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 429
Erhaltene Danke: 107

Win 10
Delphi 6 Prof, Delphi 10.4 Prof
BeitragVerfasst: Sa 03.09.16 00:41 
Falls Interesse besteht, kann ich einen alten Text von mir einmal neu formatieren und hier einstellen.
Dort hatte ich ein paar Erklärungen zum einfachen Apfelmännchen geschrieben incl.
Vergleich der Geschwindigkeit auf verschiedenen Rechnern, mit verschiedenen Sprachen (Delphi, Fortran u.a.)
und auch zusätzliche Optimierungsmöglichkeiten (Kreis/Zykloidentest).
Sind so ca. 8-9 Seiten, Alter: Alt. Südhang, eher süffig. Aus meiner Dozentenzeit (also - ich denke so 15 Jahre her)

Für diesen Beitrag haben gedankt: Mathematiker
Mathematiker
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 2622
Erhaltene Danke: 1447

Win 7, 8.1, 10
Delphi 5, 7, 10.1
BeitragVerfasst: Sa 03.09.16 07:47 
user profile iconmandras hat folgendes geschrieben Zum zitierten Posting springen:
Falls Interesse besteht, kann ich einen alten Text von mir einmal neu formatieren und hier einstellen.

Danke für das Angebot.
Ich persönlich habe immer Interesse an Texten zu mathematisch-chaostheoretischen Sachen.

Beste Grüße
Mathematiker

_________________
Töten im Krieg ist nach meiner Auffassung um nichts besser als gewöhnlicher Mord. Albert Einstein