Fractal snow screensaver
Introduction
This article describes some basic characteristics of fractals and shows how to draw snowflakes using fractals. Source code contains object for drawing one snowflake and Windows forms control for falling snow. This control is used for creating screensaver applications. In the screensaver applications, snowflakes are created using random settings, so there are almost unlimited variations of snowflakes.
Fractals
Fractals are geometrical shapes, where a certain pattern repeats itself depending on zoom. That means, when you zoom in a part of the object, it looks the same way or is very similar like the original object before the zoom.
In programs, fractals are created using recursion. Same (or very similar) drawing operation is repeated until depth of recursion exceeds specified number. In my application, the drawing operation is performed on the line connecting the center of the snowflake with its edge and then on new lines created in first step.
Snowflakes
Application uses two slightly different algorithms to make more various snowflakes. These two methods have same input parameters with same meaning, so it is very simple to use both methods for drawing snowflakes.
If you want to learn more about how snowflakes are generated and what each input parameter does, install screensaver and go to Settings - Snowflake Preview.
First type (LineType)
Drawing snowflake
- Six fractal branches are drawn from the center of the snowflake to the edge.
- Line is divided to two parts with lengths in specified ratio.
- Two new lines are drawn under specified angle from found point.
- Operation (from number 2 to 4) is repeated on two newly created lines.
Second type (PointType)
Drawing snowflake
- Six fractal branches are created (no drawing at this time!) from the center of the snowflake to the edge.
- Line is divided to two parts with lengths in specified ratio.
- Two new lines are created (no drawing) under specified angle from found point.
- Operation (from number 2 to 4) is repeated on two newly created lines and on third line from found point to the point at the edge.
- After count of repetitions is exceeded, all residuary lines are drawn.
Source code
UML class diagram
Snow flake drawing
Following function is the simplified recursive function used for drawing the first type of snowflakes:
This code uses function Rotate
. This function rotates point around
specified center and is implemented in SnowFlake.cs.
// Ratio used for calculating dividing point private const float fBranching=0.3f; // Ratio used for decreasing length of lines private const float fShrinking=0.6f; // Maximal depth of recursion private const int iMaxDepth=5; // Angle between parent and child line (in degrees) private const int iBranchAngle=35; // Draw snowflake branch // output - Graphics to draw on // start - Starting point of line // end - Ending point of line // depth - Depth of recursion private void DrawBranch(Graphics output, PointF start,PointF end,int depth) { if (depth==iMaxDepth) return; DrawLine(output,pn,start,end); // calculate dividing point PointF cnt=new PointF(start.X+(end.X-start.X)*fBranching, start.Y+(end.Y-start.Y)*fBranching); // calculate point used as end (after rotation) of two new lines PointF nend=new PointF(cnt.X+(end.X-start.X)*fShrinking, cnt.Y+(end.Y-start.Y)*fShrinking); // recursion - draw two new lines DrawBranch(output,cnt,Rotate(nend,cnt,iBranchAngle),depth+1); DrawBranch(output,cnt,Rotate(nend,cnt,-iBranchAngle),depth+1); }
Using this code
Using SnowFlake
SnowFlake
object can be used to draw snowflakes. It has two methods
for drawing. First method Draw(Graphics, PointF)
can be used for normal
drawing and second method Draw(Graphics, PointF, int)
allows you to
specify alpha value for drawn pixels. Second method is used in screensavers for
snowflake melting. RandomSnowFlake
is class derived from
SnowFlake
. Only one difference is that, all properties of snowflake are
generated from random numbers in constructor, so you don't have to set all properties
if you want to create snowflake.
// Draw snowflakes in Paint event handler
private void Form_Paint(object sender, PaintEventArgs pe)
{
Random rndGen=new Random();
pe.Graphics.Clear(Color.Black);
SnowFlake flake=new SnowFlake(),
random=new RandomSnowFlake(rndGen.Next(Int32.MaxValue));
// draw snowflake
flake.Draw(pe.Graphics,new PointF(70.0f,70.0f));
// draw melting snowflake
flake.Draw(pe.Graphics,new PointF(70.0f,140.0f,128));
// draw random snowflake
random.Draw(pe.Graphics,new PointF(105.0f,105.0f));
}
Using SnowControl
SnowControl
is the control for creating falling snowflakes. This is
exactly the same control as control filling the whole screen of screensaver. This
control can be added to a Form
using designer, or manually using code
similar to following:
This control has a lot of properties, that are described in Screen saver settings section.
SnowControl snowCtrl;
public Form()
{
// Create control
snowCtrl=new SnowControl();
Controls.Add(snowCtrl);
snowCtrl.Dock=DockStyle.Fill;
}
private void Form_Load(object sender,EventArgs e)
{
// Start animation
snowCtrl.Start();
}
SnowControl and Screensaver settings
Environment
Property called StopFalling
is length in pixels from bottom of the
screen, where falling snowflakes will stop falling. If this property is less than
zero, snowflakes will fall outside the screen. Falling snowflakes are affected by
wind. The WindForce
specifies how the snowflakes will be inflected by
wind and WindChanging
determinates how fast will the direction of wind
change.
Snowflakes
You can change number of snowflakes displayed on screen (MaxFlakes
)
and color of snowflakes (FlakeColor
). Size and speed properties are
randomly generated between specified maximal and minimal values
(MinSpeed
, MaxSpeed
and MinSize
,
MaxSize
).
When snowflake falls to the bottom of the screen, it stays at this location for a
specified number of frames (MeltingStart
), after this time the snowflake
starts melting and it melts for a number of frames specified by
MeltingFluency
property.
Background
Background of screensaver can be any image compatible with .NET, solid color or gradient from two colors (top and bottom color). Note that if you set background to image and you have more snowflakes, then the screensaver can be very slow!
Thanks to...
Thanks to Adam Abonyi for this idea, useful remarks and big help during the composition of this English article. Additional thanks to the authors of the following articles.
Related articles
Marc's fractal tree was a great inspiration for this article and other two contains useful information about creating screensavers, including multiple monitors support and how to draw screensaver preview in .NET.
- Create a fractal Christmas tree by Marc Clifton.
- Christian and James' Code Project Screensaver by Christian Graus and James T. Johnson.
- How to develop a screen saver in C# by Rakesh Rajan.