Click here to Skip to main content
6,595,444 members and growing! (16,860 online)
Email Password   helpLost your password?
Multimedia » General Graphics » Graphics     Intermediate

Fractal Snow

By Tomas Petricek

Describes how to draw snowflakes using fractals and contains a nice snow screensaver.
C#, VC7.1, Windows, .NET 1.1VS.NET2003, Dev
Posted:13 Dec 2003
Views:108,444
Bookmarked:59 times
Announcements
Loading...
 
Search    
Advanced Search
Add to IE Search
printPrint   add Share
      Discuss Discuss   Broken Article?Report  
33 votes for this article.
Popularity: 7.02 Rating: 4.63 out of 5

1

2
2 votes, 6.1%
3
5 votes, 15.2%
4
26 votes, 78.8%
5

Snow generatedd using fractals

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)

First type of snow flakes

Drawing snowflake

  1. Six fractal branches are drawn from the center of the snowflake to the edge.
  2. Line is divided to two parts with lengths in specified ratio.
  3. Two new lines are drawn under specified angle from found point.
  4. Operation (from number 2 to 4) is repeated on two newly created lines.

Second type (PointType)

Second type of snow flakes

Drawing snowflake

  1. Six fractal branches are created (no drawing at this time!) from the center of the snowflake to the edge.
  2. Line is divided to two parts with lengths in specified ratio.
  3. Two new lines are created (no drawing) under specified angle from found point.
  4. 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.
  5. After count of repetitions is exceeded, all residuary lines are drawn.

Source code

UML class diagram

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();
}

Screen saver

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 Xenik (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.

  1. Create a fractal Christmas tree by Marc Clifton.
  2. Christian and James' Code Project Screensaver by Christian Graus and James T. Johnson.
  3. How to develop a screen saver in C# by Rakesh Rajan.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Tomas Petricek


Member
I live in Prague, the capital city of Czech republic (most of the time Smile). I've been very interested in functional programming recently and I have a passion for the new Microsoft F# language. I'm writing a book about Functional Programming in the Real World that shows the ideas using examples in C# 3.0 and F#.

I've been Microsoft MVP (for C#) since 2004 and I'm one of the most active members of the F# community. I'm a computer science student at Charles University of Prague. My hobbies include photography, fractals and of course many things related to computers (except fixing them). My favorite book writers are Terry Pratchett and Philip K Dick and I like paintings by M. C. Escher.

PS: My favorite codeproject icon is Sheep.
Location: Czech Republic Czech Republic

Other popular General Graphics articles:

  • A flexible charting library for .NET
    Looking for a way to draw 2D line graphs with C#? Here's yet another charting class library with a high degree of configurability, that is also easy to use.
  • CxImage
    CxImage is a C++ class to load, save, display, transform BMP, JPEG, GIF, PNG, TIFF, MNG, ICO, PCX, TGA, WMF, WBMP, JBG, J2K images.
  • 3D Pie Chart
    A class library for drawing 3D pie charts.
  • Barcode Image Generation Library
    This library was designed to give an easy class for developers to use when they need to generate barcode images from a string of data.
  • ImageStone
    An article on a library for image manipulation.
Article Top
You must Sign In to use this message board.
FAQ FAQ 
 
Noise Tolerance  Layout  Per page   
 Msgs 1 to 24 of 24 (Total in Forum: 24) (Refresh)FirstPrevNext
GeneralCode HELP! =) PinmemberStephLeda2:25 21 Oct '09  
Generalmultithreading Pinmemberzsevgymko3:29 25 Feb '05  
GeneralScreen saver preview (VB.NET) PinmemberJohn Wells19:34 5 Jun '04  
Generalwindow in top left corner? Pinmemberjeffreylreed15:54 17 Apr '04  
GeneralRe: window in top left corner? PinmemberTomas Petricek7:17 18 Apr '04  
GeneralNice one PinmemberRajesh Pillai1:31 26 Dec '03  
GeneralGreat job. PinmemberTodd Smith9:41 18 Dec '03  
GeneralMissing XML PinmemberBill Seddon23:37 14 Dec '03  
GeneralRe: Missing XML PinmemberTomas Petricek7:07 15 Dec '03  
GeneralNow we just have to combine the two PineditorMarc Clifton15:02 14 Dec '03  
GeneralRe: Now we just have to combine the two PinmemberTomas Petricek7:17 15 Dec '03  
GeneralExcellent! Pinmemberjdunlap11:40 14 Dec '03  
GeneralRe: Excellent! PinmemberTomas Petricek7:08 15 Dec '03  
GeneralMultiple Monitor Support? PinmemberDerek Price7:54 14 Dec '03  
GeneralRe: Multiple Monitor Support? PinmemberTomas Petricek8:12 14 Dec '03  
GeneralRe: Multiple Monitor Support? PinmemberDerek Price9:00 14 Dec '03  
GeneralRe: Multiple Monitor Support? PinmemberTomas Petricek9:25 14 Dec '03  
GeneralRe: Multiple Monitor Support? PinmemberDerek Price9:40 14 Dec '03  
GeneralRe: Multiple Monitor Support? PinmemberTomas Petricek10:14 14 Dec '03  
GeneralRe: Multiple Monitor Support? PinmemberDerek Price10:25 14 Dec '03  
GeneralRe: Multiple Monitor Support? PinmemberDerek Price11:41 15 Dec '03  
GeneralRe: Multiple Monitor Support? PinmemberHugo Hallman10:58 21 May '04  
GeneralRe: Multiple Monitor Support? PinmemberDerek Price11:14 21 May '04  
GeneralRe: Multiple Monitor Support? PinmemberTrollslayer23:38 17 Dec '03  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 13 Dec 2003
Editor: Smitha Vijayan
Copyright 2003 by Tomas Petricek
Everything else Copyright © CodeProject, 1999-2009
Web22 | Advertise on the Code Project