SRL Archive - Other Scripts

Fractal drawer!


almost

2010-12-01 15:12:50

This script generates a fractal image that can be zoomed into infinitely without losing detail.

Version 2 is now up!
Simba version is now up!

What is a fractal?
There are many ways to define fractal, but my own perception would be something like… An object with infinite complexity that is self repeating. Each piece of a fractal, no matter how small, is a part of the whole.
Fractals have only just recently discovered a new form of math called "fractal geometry"
I would recommend watching this documentary on fractals to be able to understand what they are - http://www.youtube.com/watch?v=qB8m85p7GsU It changed the way I think of everything.
Or this documentary that has more to do with how fractals are found in nature - http://www.streaming-madness.net/watch-online/documentary/fractals-hunting-the-hidden-dimension/

How do I use the plugin?
Download the Coloration.rar and open up your plugins folder for SCAR.
It should be something like "C:\Program Files\SCAR\Plugins" for scar and something like "C:\Simba\Plugins" for simba.
Paste or drag the Coloration.dll into this folder and you're done.

Using the form
Zooming
Clicking on the image will zoom in by the number in "Zoom Amount"
Right clicking will zoom out by the same amount.
Changing the "Size" box is also a form of zooming in. Increasing the size will not show a larger area of the fractal, but will show a much more up close view and more detail.

Navigating
Pressing one of the four arrow buttons will move the fractal in that direction.
The "Shift Amount" box tells how much to move the fractal when an arrow is clicked.
If the checkbox beside it is checked, it will shift by a percent instead of a number of pixels.
The x and y box contain the center point of the rendering (starting out at the origin, (0, 0))

Detail tab
The minimum, average, and maximum boxes are read only and show you the range of iterations found in the fractal.
These numbers can be used to know what to set other settings at to get the best detail in your picture.

The "Max Iterations" box is how many "iterations" or loops are done for each pixel (at max). The max number may never be met though, for example if you set the max iterations to 10,000 but the highest needed iteration found was only 1000 then you could have set the max iterations to only 1000 and had the same result. And in this case if you were to increase the max iterations all the way up to a million it still wouldn't take any longer to render.
To know if you need to raise the "max iterations", look at the maximum box. If this number is close to the "max iterations" then you will most likely need to raise it to show the image's full detail.

The "Pixel Size" box tells how big to draw each pixel. It is recommended to leave at 1, unless you are just cruising around the fractal looking for an interesting spot. Increasing the pixel size makes it render more quickly at the cost of some detail.

The "Stretch" box will stretch the image by x amount of pixels. This should only be used for viewing a certain area of a fractal on a larger scale, but not for navigating around because it offsets the center points.
Basically this is a way to make the fractal larger but not increase the rendering time, although it does not increase the detail either.

Color Tab
(For the time being, the two buttons on the color tab only work in the scar version)
The colors used are in a color palette that is created based on the "Colors" box and the "Starting Color" box.
The palette goes through every hue from 0-100 and for each hue the luminance goes from 0-100.
The "Colors" box tells how many colors are in the palette.
The "Color Start" box is what color the palette starts at.
The "Change Zero Color" button will change the color of pixels that are not in the "set". The default color is black.
The "Change Form Color" button simply changes the background color.

Detail vs Speed
If you are looking for the best detail (this is how the amazing images are found) here are the settings you need -
Set the size to as big as you can, the larger the more wait though.
I like to set it around 500 once I've found something interesting.
Max iterations needs to be just above the maximum found iteration of the image (you have to figure this part)
Pixel size - 1, Stretch - 0, Fast mode off
Color start and amount don't change detail.
Anti aliasing set to all is a lot of times the best option but it depends on the fractal you are rendering.

If you are just trying to navigate around and explore here are some fast rendering options -
Size - 100, Max Iterations - 1000, Pixel Size - 2 or 3ish, Stretch - 0, fast mode on, anti alias off

Extras
(For the time being most of the extras only work in the scar version)
The box that contains the 3 tabs and also the box that has the "draw" button on it can be moved by holding down the mouse.
Each of the 3 tabs can be dragged from the main box and dropped anywhere you want and you will have a separate box for that tab.
If you drag a tab off the main box and want it to go back, simply drag it back onto the main box and it will attach itself again.

So that's about it. If you have any questions about it ask away.
I've had a lot of fun with this program just exploring the never ending possibilities. And it has been one of my longest/hardest projects ever so I hope you all enjoy :D

Here are a couple of interesting pics I found in the process of making this -
These first 2 are the same with a different "Color Start" to show how that changes the fractal-
http://i200.photobucket.com/albums/aa143/kronikel/12.jpg
http://i200.photobucket.com/albums/aa143/kronikel/11.jpg

http://i200.photobucket.com/albums/aa143/kronikel/13.jpg
http://i200.photobucket.com/albums/aa143/kronikel/14.jpg
http://i200.photobucket.com/albums/aa143/kronikel/10.jpg

And here is the source for the plugin, if you don't feel like downloading the plugin you can paste this function in (but it will take a LOT longer to draw)
function ColorPoint(px, py: extended; MaxIteration: integer): integer; stdcall;
var
x, y, xtemp: extended;
begin
x:= px;
y:= py;
repeat
xtemp:= x*x - y*y + px;
y:= 2*x*y + py;
x:= xtemp;
Result:= Result + 1;
until((x*x + y*y >= 4) or (Result > MaxIteration));
if (Result = MaxIteration) then
Result:= 0;
end;

Cstrike

2010-12-01 15:14:19

Fractals are cool at times :) Nice

BraK

2010-12-01 16:10:19

I'm on video 4 of 6 of "The colors of Infinity" it's a really awesome series I recomend the everyone Watch the Video. It's intriguing beyond what you'd imagine.

~BraK

E: cstrike did you watch the videos?

almost2

2010-12-01 16:34:30

Yes they are quite interesting.
I've been studying them ever since I first watched the videos.

edit: lol I logged in on the wrong account.
Got so used to using this one.

Cstrike

2010-12-01 16:35:14

Didn,t looked at the pictures :)

Also the file that was uploaded cant compile (on Simba?)

almost

2010-12-01 17:12:58

I gave up with simba.
IMO it is a slower version of scar with less functions, a lot of which are needed to run this.

BraK

2010-12-01 17:22:47

Which Functions are needed that simba doesn't have?

~BraK

almost

2010-12-01 17:24:31

Not entirely sure but I know a lot of thins that have to do with canvases and bitmaps.
Such as CopyCanvas, which I'm not sure how you could recreate that yourself.
Also some things involved in making the form would have to change.
I had a working simba version at one point but I didn't like it.

Smartzkid

2010-12-01 17:31:24

Tried to get this working in simba, got stuck at GetBitmapCanvas. Anyone?

almost

2010-12-01 17:52:03

I got around this by not using a bitmap at all.
You can use Form.Canvas.Pixels[x, y] instead of Bmp.Canvas.Pixels[x, y]
But that requires redoing a lot of the script.

And the only reason I used a bitmap to begin with is so the Form.OnPaint can paste the bitmap.
You can downsize the form or move things on top of the image without the image disappearing.

EvilChicken!

2010-12-01 17:59:17

From: almost2
Yes they are quite interesting.
I've been studying them ever since I first watched the videos.

edit: lol I logged in on the wrong account.
Got so used to using this one.


Just a bit offtopic, excuse me for it – but can I ban this account now that you've gotten your old one back?


As for the drawer, it looks really neat from the pictures; I'll take a look at the actual files tomorrow.
I assume the source is included? I hope to learn something from it.. :o

almost

2010-12-01 18:29:42

Yes feel free to ban the old one there's no point in having it around.

The source for the plugin is shown and it's actually only a few lines.
But that's where the magic happens.

The function is called Coloration and it takes a point and does iterations on it until it either reaches 0 or until it has determined it will reach infinity.
If it reached 0 it is colored what I call in this script the "zero color" (which is black by default) and if it does not then it gets colored a certain color based on how many loops it went through to determine that point would be infinity.
The equation for making a fractal is "z = z^2 + c"
Because z is on the left AND right side of the equation, the output of each loop becomes the input for the next one.
if z starts at 1 and c is 2 you would get a loop looking like
z = 1^2 + 2 (z = 3)
z = 3^2 + 2 (z = 11)
z = 11^2 + 2 (z = 123)
And in this example it quickly speeds off into infinity

Nava2

2010-12-01 19:10:29

From: almost
Not entirely sure but I know a lot of thins that have to do with canvases and bitmaps.
Such as CopyCanvas, which I'm not sure how you could recreate that yourself.
Also some things involved in making the form would have to change.
I had a working simba version at one point but I didn't like it.


There is so much wrong with these statements..

So, canvases are silly and not cross compatible. To work with canvases, you instead work with bitmaps.

Check out: http://git.villavu.com/?p=simba.git;a=blob_plain;f=Units/MMLCore/bitmaps.pas;h=5a02ae44515494761fddffe124043d27f801d414;hb=HEAD

The main thing to look at is this:
TMufasaBitmap = class(TObject)
private
w,h : integer;
FTransparentColor : TRGB32;
FTransparentSet : boolean;
FIndex : integer;
FName : string;
public
OnDestroy : procedure(Bitmap : TMufasaBitmap) of object;
//FakeData : array of TRGB32;
FData : PRGB32;
property Name : string read FName write FName;
property Index : integer read FIndex write FIndex;
procedure SetSize(AWidth,AHeight : integer);
procedure StretchResize(AWidth,AHeight : integer);
property Width : Integer read w;
property Height : Integer read h;
procedure ValidatePoint(x,y : integer);
function SaveToFile(const FileName : string) :boolean;
procedure LoadFromFile(const FileName : string);
procedure Rectangle(const Box : TBox;FillCol : TColor);
procedure FloodFill(const StartPT : TPoint; const SearchCol, ReplaceCol : TColor);
procedure FastSetPixel(x,y : integer; Color : TColor);
procedure FastSetPixels(Points : TPointArray; Colors : TIntegerArray);
procedure DrawATPA(ATPA : T2DPointArray; Colors : TIntegerArray);overload;
procedure DrawATPA(ATPA : T2DPointArray);overload;
procedure DrawTPA(Points : TPointArray; Color : TColor);
procedure DrawToCanvas(x,y : integer; Canvas : TCanvas);
function CreateTPA(SearchCol : TColor) : TPointArray;
function FastGetPixel(x,y : integer) : TColor;
function FastGetPixels(Points : TPointArray) : TIntegerArray;
function GetAreaColors(xs,ys,xe,ye : integer) : T2DIntArray;
procedure FastDrawClear(Color : TColor);
procedure FastDrawTransparent(x, y: Integer; TargetBitmap: TMufasaBitmap);
procedure FastReplaceColor(OldColor, NewColor: TColor);
procedure CopyClientToBitmap(MWindow : TObject;Resize : boolean; xs, ys, xe, ye: Integer);overload;
procedure CopyClientToBitmap(MWindow : TObject;Resize : boolean;x,y : integer; xs, ys, xe, ye: Integer);overload;
procedure RotateBitmap(angle: Extended;TargetBitmap : TMufasaBitmap );
procedure Desaturate(TargetBitmap : TMufasaBitmap); overload;
procedure Desaturate;overload;
procedure GreyScale(TargetBitmap : TMufasaBitmap);overload;
procedure GreyScale;
procedure Brightness(TargetBitmap : TMufasaBitmap; br : integer); overload;
procedure Brightness(br: integer);overload;
procedure Contrast(TargetBitmap : TMufasaBitmap; co : Extended);overload;
procedure Contrast(co: Extended);overload;
procedure Invert(TargetBitmap : TMufasaBitmap);overload;
procedure Invert;overload;
procedure Posterize(TargetBitmap : TMufasaBitmap; Po : integer);overload;
procedure Posterize(Po : integer);overload;
function Copy(const xs,ys,xe,ye : integer) : TMufasaBitmap; overload;
function Copy: TMufasaBitmap;overload;
function ToTBitmap: TBitmap;
function ToString : string;
procedure LoadFromTBitmap(bmp: TBitmap);
procedure LoadFromRawImage(RawImage: TRawImage);
function CreateTMask : TMask;
procedure SetTransparentColor(Col : TColor);
function GetTransparentColor : TColor;
property TransparentColorSet : boolean read FTransparentSet;
procedure SetAlphaValue(const value : byte);
constructor Create;
destructor Destroy;override;
end;

ALL of those methods are attached to the Bitmap. This allows you to use TMBitmaps in simba! You can do everything with canvases with a bitmap. You merely display the bitmap after. In fact, it will be faster in Simba.

Simba as a whole is actually faster than SCAR. If its not fast enough, make it faster in a plugin. I guarantee you will not be disappointed.

almost

2010-12-01 19:25:24

I like this.
I figured simba didn't use canvases at all.
I'll give it a try and I have a feeling it might be faster in some ways.

What killed me was that in simba you click on the Bitmap section and it shows some functions you can do and I could only assume those were all of them but apparently there are plenty more.

Nava2

2010-12-01 23:01:55

From: almost
I like this.
I figured simba didn't use canvases at all.
I'll give it a try and I have a feeling it might be faster in some ways.

What killed me was that in simba you click on the Bitmap section and it shows some functions you can do and I could only assume those were all of them but apparently there are plenty more.


If you create a TMBitmap by using.. some function I cannot remember, you have access to all of those. You can treat it as an object! :)

almost

2010-12-03 16:36:14

Version 2 is now up!
This version is much faster and at least 1000 times better looking!
It uses a color palette rather than a color algorithm to map colors.

So what changed?
No more fast mode option, because it's always in fast mode now
Much more detail available, the color palette has luminance now to greatly increase contrast
No more anti alias option, as it won't be needed now

The same plugin is used though, so if you downloaded the first version you should definitely give the new one a go.

New pictures have been added to the first post to show the new results =)

Gu3st...

2010-12-03 17:58:44

Wow.
This is truly amazing, almost :)
Good job! Looks amazing!!
It's a shame I don't have scar installed on this computer… I'll have to install it now though :redface:
EDIT: I got 3.25 Alpha now.. What version do you use?

almost

2010-12-03 18:13:29

I made this on SCAR 3.21 but I would assume it still works on the newest versions.

Gu3st...

2010-12-03 18:18:54

From: almost
I made this on SCAR 3.21 but I would assume it still works on the newest versions.
It doesn't :(
Execution error at line 879.. I had to edit a few lines (add some round()'s and some parameters…)

almost

2010-12-03 18:20:35

But did you get it running?
I suppose I should release a simba version.

Smartzkid

2010-12-04 00:54:18

From: almost
I suppose I should release a simba version.


Please!!

Wanted

2010-12-04 04:31:05

Here's a pretty easy patch for SCAR 3.25 beta

--- C:/Users/James/AppData/Local/Temp/Left.txt-revBASE.svn000.tmp.txt	Sat Dec  4 03:30:06 2010
+++ C:/Users/James/Documents/wtf/Left.txt Sat Dec 4 03:29:49 2010
@@ -36,9 +36,6 @@
end;


-
-
-
function MaxArray(a: TIntegerArray): integer;
var
i: integer;
@@ -81,7 +78,7 @@
Result:= Result + a[i];
c:= c + 1;
end;
- Result:= (Result / c);
+ Result:= (Result div c);
end;


@@ -102,7 +99,7 @@
function ColorIndex(Iteration: integer): integer;
begin
if (Iteration >= GetArrayLength(Colors)) then
- Iteration:= (Iteration - (GetArrayLength(Colors) * (Iteration / GetArrayLength(Colors))));
+ Iteration:= (Iteration - (GetArrayLength(Colors) * (Iteration div GetArrayLength(Colors))));
Result:= Colors[Iteration];
end;

@@ -270,7 +267,7 @@
mx:= StrToFloat(cxBox.Text);
my:= StrToFloat(cyBox.Text);
RealToImaginary(x, y, ix, iy);
- RealToImaginary(Size / 2 - 1, Size / 2 - 1, ix2, iy2);
+ RealToImaginary(Size div 2 - 1, Size div 2 - 1, ix2, iy2);
mx:= mx + (ix - ix2);
my:= my + (iy - iy2);
if Side then
@@ -543,13 +540,13 @@
begin
case Sender of
Settings:
- Settings.BeginDrag(False);
+ Settings.BeginDrag(False, 32);
NewImage:
- NewImage.BeginDrag(False);
+ NewImage.BeginDrag(False, 32);
NewDetail:
- NewDetail.BeginDrag(False);
+ NewDetail.BeginDrag(False, 32);
NewColor:
- NewColor.BeginDrag(False);
+ NewColor.BeginDrag(False, 32);
end;
end;


Wizzup?

2010-12-04 06:05:29

From: almost
But did you get it running?
I suppose I should release a simba version.


You should know that we didn't use a system similar to SCAR's on purpose because canvas is slow. Simba methods are faster. They just require a different approach. Perhaps someone (me?) can write a tutorial on it later.

I'm not exactly sure what you use CopyCancas for but it is easily replaced with other methods. What other canvas methods do you use?

Remember that Simba also has canvas:

program new;
var a: TBitmap;
begin
a:=TBitmap.Create;
a.Canvas.Pen.Color := clRed;
end.

And I think TBitmap and TMufasaBitmap are quite interchangeable. TMufasaBitmap has methods to convert to and from TBitmap, although I currently miss the "LoadFromTBitmap" in the interpreter.

Gu3st...

2010-12-04 06:18:16

Thanks IceFire! :)
I did NewColor.BeginDrag(False, 0); instead of NewColor.BeginDrag(False, 32); :(

almost

2010-12-04 12:35:16

I understand how to use bitmaps in simba now.
Bitmaps are objects which I like better.
Shouldn't take but a few minutes to convert to simba.
I wanted to convert to c++ first though, and I just got done with that.
Which is very nice, I can do a full screen rendering in a couple seconds.

Also keep in mind if you have issues with the events like Drag you can take those out.
Dragging and dropping tabs isn't necessary I just liked having it.

Wanted

2010-12-04 13:03:46

From: Zyt3x
Thanks IceFire! :)
I did NewColor.BeginDrag(False, 0); instead of NewColor.BeginDrag(False, 32); :(


I honestly don't know the difference, I just saw someone else use 32 before and figured it work.

almost

2010-12-04 14:06:07

I have a simba version that compiles now.
But no matter how I use a bitmap in simba I get tons of errors.
I have tried using TMufasaBitmap and TBitmap.
I have tried Bitmap:= TMufasaBitmap.Create and Bitmap:= BitmapFromString(w, h, '');
Everything crashes the script/ freezes my computer, making it extremely hard to debug.

Edit:
This is testing out how to use a bitmap.
It just creates a bitmap and tries to set some of its pixels then draw the bitmap on the form.
"Error: Exception: You are accessing an invalid point, (0,0) at bitmap[0] at line 69"
program new;

var
Bmp: TMufasaBitmap;
Canvas: TCanvas;
Form: TForm;
x, y: integer;



procedure InitForm;
begin
Form:= TForm.Create(nil);
Form.Caption := 'Freakin Fractals - By Almost';
Form.Color := 15582994;
Form.Font.Color := clWindowText;
Form.Font.Height := -11;
Form.Font.Name := 'MS Sans Serif';
Form.Font.Style := [];
Form.Visible := False;
Form.PixelsPerInch := 96;
Form.Windowstate:= WSMaximized;
Form.Height:= 500;
Form.Width:= 800;

Bmp.DrawToCanvas(0, 0, Form.Canvas);
end;





procedure SafeInitForm;
var
v: TVariantArray;
begin
setarraylength(v, 0);
ThreadSafeCall('InitForm', v);
end;





procedure ShowFormModal;
begin
Form.ShowModal;
end;





procedure SafeShowFormModal;
var
v: TVariantArray;
begin
SetArrayLength(v, 0);
ThreadSafeCall('ShowFormModal', v);
end;





begin
Bmp:= TMufasaBitmap.create;
for x:= 0 to 50 do
for y:= 0 to 50 do
Bmp.FastSetPixel(x, y, 0);
SafeInitForm;
SafeShowFormModal;
Form.Free;
Bmp.Free;
end.

Gu3st...

2010-12-04 17:58:03

You have to make sure the point you are trying to draw on is available on the bitmap. If your bitmap is 20x20 you can't paint on 52,12.

Also, I don't think that's the correct way of creating a TMufasaBitmap… Correct me if I'm wrong

almost

2010-12-04 21:10:07

I don't see any way of setting the width and height of it.
TMufasaBitmap.Width is read only.
And BitmapFromString returns an integer.
Maybe TMufasaBitmap.Something:= BitmapFromstring?

I don't think that's the right way either but that's what Wizzup did in his example and I'm not sure what else to do.

mastaraymond

2010-12-05 09:06:03

From: almost
I don't see any way of setting the width and height of it.
TMufasaBitmap.Width is read only.
And BitmapFromString returns an integer.
Maybe TMufasaBitmap.Something:= BitmapFromstring?

I don't think that's the right way either but that's what Wizzup did in his example and I'm not sure what else to do.

Don't know if the test files are delivered within an install..

http://git.villavu.com/?p=simba.git;a=tree;f=Tests/PS;h=7b00c8666a6ccead2d660d7027aa81910a698907;hb=HEAD

Check out http://git.villavu.com/?p=simba.git;a=blob_plain;f=Tests/PS/Several+bitmap+operations.simba;hb=HEAD

almost

2010-12-05 13:54:41

I looked through the test files and apparently bitmaps work when used just like in scar…
GF my time.
I don't see TBitmap or bitmaps being used as objects at all…

And for some reason it won't copy a bitmap onto a TForm.Canvas, you have to create a TImage or something and copy it.

program new;

var
Bmp: integer;
Form: TForm;
x, y: integer;
Image: TImage;



procedure InitForm;
begin
Form:= TForm.Create(nil);
Form.Caption := 'Freakin Fractals - By Almost';
Form.Color := 15582994;
Form.Font.Color := clWindowText;
Form.Font.Height := -11;
Form.Font.Name := 'MS Sans Serif';
Form.Font.Style := [];
Form.Visible := False;
Form.PixelsPerInch := 96;
Form.Windowstate:= WSMaximized;
Form.Height:= 500;
Form.Width:= 800;

Image:= TImage.Create(Form);
Image.Parent:= Form;
Image.SetBounds(0, 0, 200, 200);

DrawBitmap(Bmp, Image.Canvas, 0, 0);
end;





procedure SafeInitForm;
var
v: TVariantArray;
begin
setarraylength(v, 0);
ThreadSafeCall('InitForm', v);
end;





procedure ShowFormModal;
begin
Form.ShowModal;
end;





procedure SafeShowFormModal;
var
v: TVariantArray;
begin
SetArrayLength(v, 0);
ThreadSafeCall('ShowFormModal', v);
end;





begin
Bmp:= CreateBitmap(100, 100);
CopyClientToBitmap(Bmp,0,0,99,99);
for x:= 0 to 50 do
for y:= 0 to 50 do
FastSetPixel(Bmp, x, y, clwhite);
SafeInitForm;
SafeShowFormModal;
Form.Free;
FreeBitmap(Bmp);
end.

I don't see any differences, except the procedure DrawBitmap, which is an easier to use version of CopyCanvas.
And CreateBitmap is an easier to use version of BitmapFromString if you are just creating a blank.

almost

2010-12-05 15:05:40

Edit3:
Finally figured it out :O
TForm.OnPaint doesn't work correctly and was constantly activating causing the edit boxes and buttons and everything to freeze up and causing the form to be unable to close.
Might have a working simba version very soon.

Exit2:
This was supposed to be an edit on to the last post, oops =P

Edit4:
Got a working version for simba.
I will put it up but simba has some issues.
There is no way to do TTabSheet.OnMouseDown, there is no TProgressBar, TForm.Paint won't work right, and there is a TSaveDialog.Execute but not a TColorDialog.Execute
And I think that's all, I don't really remember.

Freddy1990

2010-12-10 18:02:01

This is really nice work! :)

WT-Fakawi

2010-12-11 11:25:30

Beautiful work. Do the Mays curve too. f(x) = f(1 - x) iirc. Made that on a Psion series 3 :)

almost

2010-12-11 14:03:54

Thanks guys =)
I'm now trying to make a 3d fractal.
But it's never been done and its somewhat overwhelming