Autor Beitrag
Jakob_Ullmann
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1747
Erhaltene Danke: 15

Win 7, *Ubuntu GNU/Linux*
*Anjuta* (C, C++, Python), Geany (Vala), Lazarus (Pascal), Eclipse (Java)
BeitragVerfasst: Do 12.08.10 18:01 
Hi!

Ich habe mal aus Spaß ein Programm geschrieben (Lazarus), welches die Mandelbrot-Menge grafisch darstellt (bezüglich komplexer Zahlen ist das sogar ein kleines wenig mehr geworden). Das Apfelmännchen selber ist auch schon recht gut zu erkennen. Allerdings würde ich mir ein wenig schönere Farben wünschen. Bis jetzt habe ich das provisorisch mal so gelöst:

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:
const
  DIVER_LIMIT = 1000;
  FLOOD_LIMIT = 2000;
  LIMIT_ORANGE = 80;
  LIMIT_RED = 40;
  LIMIT_MAROON = 20;
  LIMIT_BLUE = 10;
  LIMIT_BLACK = 5;

...

function ProveDivergence(c: TKomplex): Integer;
var
  z: TKomplex;
begin
  Result := 0;
  z := KZero;
  while ((KAbs(calcMandelbrot(z, c)) < DIVER_LIMIT) and
         (Result <= FLOOD_LIMIT)) do
  begin
    z := calcMandelbrot(z, c);
    inc(Result);
  end;
end;

...

function MandelColor(Diver: Integer): TColor;
begin
  if Diver <= LIMIT_BLACK then
    Result := clBlack
  else if Diver <= LIMIT_BLUE then
    Result := clNavy
  else if Diver <= LIMIT_MAROON then
    Result := clMaroon
  else if Diver <= LIMIT_RED then
    Result := clRed
  else if Diver <= LIMIT_ORANGE then
    Result := $0099ff
  else
    Result := $00ffff;
end;

...


Hier prüfe ich also für jedes c, wobei ich die Reihe z_n = Z_(n-1)² + c maximal bis n = FLOOD_LIMIT fortsetze, ob der Betrag KAbs(z) größer als DIVER_LIMIT wird. Anhand dieses N (Variable habe ich hier Diver genannt) wird dann die Farbe festgelegt (Mit einer Schwarz-Weiß-Darstellung wollte ich mich hier nicht zufrieden geben).

Da fallen mir aber mehrere Dinge auf:

- DIVER_LIMIT ist hier evtl. nicht ideal - ich kann aber nicht einschätzen, ob es höher oder tiefer sein müsste. Wenn es aber zu hoch ist (ich hab zwischen 10000 und 2 alle Größenordnungen durch), dauert der Kern (gelb) beim Zeichnen pro Spalte 1 Sekunde, während der schwarze Rest dann ziemlich schnell geht.
- Abstufung war nur zum Testen da. Ich hätte lieber einen graduellen Übergang, wie es in der Wikipedia der Fall ist.
- Zudem sind die Farblimits sowie die Farben selbst ziemlich hässlich gewählt.

Wie geht man denn normalerweise vor, wenn man ein Fraktal darstellen will? Evtl. will ich das Programm auch dahingehend erweitern, dass ich Julia-Mengen und andere Fraktale darstellen kann.

Mein erster Gedanke war jetzt ein Blau-Weiß-Übergang. Das kann man ja einfach berechnen, wenn man r(n), g(n) und b(n) als lineare Funktionen betrachtet. Aber besonders schön ist das auch nicht. Am liebsten hätte ich zwischendurch noch Orange-/Gelb-Töne (eben so wie in der Wikipedia).

PS: Ich habe natürlich die Forums-Suche benutzt, aber was ich da gefunden habe, war eben auch nicht viel mehr als ein einfacher Blau-Weiß-Übergang oder elend langsam.

//EDIT: Ein halbwegs ästhetisches Ergebnis kriege ich schonmal damit:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
function MandelColor(DIVER: Integer): TColor;
var
  b, r: Integer;
begin
  if Diver < 20 then
  begin
    b := $ff;
    r := Trunc($ff * Diver / 20);
    Result := RGB(r, r, b);
  end
  else if Diver < 500 then
    Result := clWhite
  else
    Result := clBlack
end;


Aber wie gesagt, nur ein naiver Blau-Weiß-Ansatz und ich bin nicht wirklich zufrieden damit.


Moderiert von user profile iconNarses: Topic aus Off Topic verschoben am Do 12.08.2010 um 18:26
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Do 12.08.10 18:38 
de.wikipedia.org/wik...ng_complex_functions

Das hab ich auch bei mir mal kurz in ner Demo umgesetzt und das sah recht vielversprechend aus. Hab da Source da, falls Du brauchst.

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
Jakob_Ullmann Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1747
Erhaltene Danke: 15

Win 7, *Ubuntu GNU/Linux*
*Anjuta* (C, C++, Python), Geany (Vala), Lazarus (Pascal), Eclipse (Java)
BeitragVerfasst: Do 12.08.10 19:03 
Also das sieht schon gut aus, aber das mit dem HSV-Farbraum ist glaube ich nicht ganz das, was ich will. Ich habe das jetzt nur überflogen und das Endergebnis ist dann ja wahrscheinlich sowas:

de.wikipedia.org/wik...lbrot-Iterate-20.jpg

Schön wäre aber eher sowas, was eben nicht den gesamten Farbkreis mit einschließt:

de.wikipedia.org/w/i...0_mandelbrot_set.jpg

Blau-Weiß sieht ja alles mit dem letzten Code ganz ästhetisch aus. Aber der Algo ist doch ziemlich wertlos, den irgendwann will ich ja auch die kleinen Apfelmännchen sehen können:

de.wikipedia.org/w/i...oom_07_satellite.jpg

Ansonsten macht das ganze ja wenig Sinn. OK, wahrscheinlich muss ich eh noch den gesamten Algorithmus ändern. Bis jetzt ist das ja Escape-Time, Ziel wäre ja Normalized Iterator Count.

EDIT: Verdammt, das mit dem Bildern klappt nicht. Ich hab den img-Tag jetzt durch url ersetzt.

Edit2: Ich bin bei dem Bild im "XFract - Fraktalgenerator für Mandelbrot und Juliamengen"-Thread irgendwie darauf gekommen, nicht Diver, sondern (Diver mod 100) als Maß für die Farbe genommen. So habe ich jetzt einen schönen Blau-Orange-Wechsel. Zoom funktioniert jetzt auch. Abschließend ein Screenshot von den kleineren Apfelmännchen:

Bildschirmfoto

EDIT:

Für alle, die selber sowas machen: Die ultimative Formel von Garcia, Fernandez, Barrallo, Martin (aus dem Paper Coloring Dynamical Systems in the Complex Plane) für Real Escape Time / Normalized Iteration Count:

n' = n + ( log(log(b)) - log(log( |z| )) ) / log(2)

Damit verschwindet dann auch der Bändereffekt. :D
Einloggen, um Attachments anzusehen!