Academic Tutorials



English | French | Portugese | German | Italian
Home Advertise Payments Recommended Websites Interview Questions FAQs
News Source Codes E-Books Downloads Jobs Web Hosting
Chats

Graphics
Graphics Introduction
Graphics Printmaking
Graphics Photography
Graphics for Web
Computer graphics
Computer graphics II
Graphics C++, SDL
Graphics QuickCG
Graphics Light and Color
Graphics Color Model
Graphics Image
Graphics 2D Drawing
Graphics Flood Fill
Graphics Clipping
Graphics Fractals
Graphics Sierpinski
Graphics Julia
Graphics Fire Effect
Graphics Tunnel Effect
graphics Raycasting
Graphics Raycaster
Graphics Floor & Ceiling
Graphics Sprites
Graphics Filtering
Graphics Fourier Trans
Graphics FT on Images
Graphics DC Component
Graphics Texture Gen..
Graphics Random Noise
Graphics Clouds

HTML Tutorials
HTML Tutorial
XHTML Tutorial
CSS Tutorial
TCP/IP Tutorial
CSS 1.0
CSS 2.0
HLML
XML Tutorials
XML Tutorial
XSL Tutorial
XSLT Tutorial
DTD Tutorial
Schema Tutorial
XForms Tutorial
XSL-FO Tutorial
XML DOM Tutorial
XLink Tutorial
XQuery Tutorial
XPath Tutorial
XPointer Tutorial
RDF Tutorial
SOAP Tutorial
WSDL Tutorial
RSS Tutorial
WAP Tutorial
Web Services Tutorial
Browser Scripting
JavaScript Tutorial
VBScript Tutorial
DHTML Tutorial
HTML DOM Tutorial
WMLScript Tutorial
E4X Tutorial
Server Scripting
ASP Tutorial
PERL Tutorial
SQL Tutorial
ADO Tutorial
CVS
Python
Apple Script
PL/SQL Tutorial
SQL Server
PHP
.NET (dotnet)
Microsoft.Net
ASP.Net
.Net Mobile
C# : C Sharp
ADO.NET
VB.NET
VC++
Multimedia
SVG Tutorial
Flash Tutorial
Media Tutorial
SMIL Tutorial
Photoshop Tutorial
Gimp Tutorial
Matlab
Gnuplot Programming
GIF Animation Tutorial
Scientific Visualization Tutorial
Graphics
Web Building
Web Browsers
Web Hosting
W3C Tutorial
Web Building
Web Quality
Web Semantic
Web Careers
Weblogic Tutorial
SEO
Web Site Hosting
Domain Name
Java Tutorials
Java Tutorial
JSP Tutorial
Servlets Tutorial
Struts Tutorial
EJB Tutorial
JMS Tutorial
JMX Tutorial
Eclipse
J2ME
JBOSS
Programming Langauges
C Tutorial
C++ Tutorial
Visual Basic Tutorial
Data Structures Using C
Cobol
Assembly Language
Mainframe
Forth Programming
Lisp Programming
Pascal
Delphi
Fortran
OOPs
Data Warehousing
CGI Programming
Emacs Tutorial
Gnome
ILU
Soft Skills
Communication Skills
Time Management
Project Management
Team Work
Leadership Skills
Corporate Communication
Negotiation Skills
Database Tutorials
Oracle
MySQL
Operating System
BSD
Symbian
Unix
Internet
IP-Masquerading
IPC
MIDI
Software Testing
Testing
Firewalls
SAP Module
ERP
ABAP
Business Warehousing
SAP Basis
Material Management
Sales & Distribution
Human Resource
Netweaver
Customer Relationship Management
Production and Planning
Networking Programming
Corba Tutorial
Networking Tutorial
Microsoft Office
Microsoft Word
Microsoft Outlook
Microsoft PowerPoint
Microsoft Publisher
Microsoft Excel
Microsoft Front Page
Microsoft InfoPath
Microsoft Access
Accounting
Financial Accounting
Managerial Accounting
Network Sites


Sierpinski Fractals


Previoushome Next







Sierpinski Fractals


A D V E R T I S E M E N T

Introduction



There are quite a lot of fractals named after Waclaw Sierpinski, a Polish mathematician who lived from 1882 to 1969.

These include the Sierpinski Triangle, the Sierpinski Carpet, the Sierpinski Pyramid (the 3D version of the Sierpinski Triangle) and the Sierpinski Cube (the 3D version of the Sierpinski Carpet). The 2D figures will be described here.

Sierpinski Triangle



The Sierpinski Triangle, also called Sierpinski Gasket and Sierpinski Sieve, can be drawn by hand as follows:

Start with a single triangle. This is the only triangle in this direction, all the others will be upside down:


Inside this triangle, draw a smaller upside down triangle. It's corners should be exactly in the centers of the sides of the large triangle:



Now, draw 3 smaller triangles in each of the 3 triangles that are pointing upwards, again with the corners in the centers of the sides of the triangles that point upwards:



Now there are 9 triangles pointing upwards. In each of these 9, draw again smaller upside down triangles:



In the 27 triangles pointing upwards, again draw 27 triangles pointing downwards:



Rinse, repeat.

After infinite steps, and if all triangles pointing upwards would be filled, you have the Sierpinski Sieve.

Every step, more triangles have to be drawn. This is a recursive process, and it can be drawn the same way with a computer.

With Recursion



We'll now program that what was drawn by hand on the computer, by making a triangle drawing function that'll call itself again 3 times, until n steps of recursions are reached. This program is made so that it works for any initial triangle, it doesn't have to be symmetrical, the only condition is that the corners lie inside the screen.

The main function sets up the screen and calls the drawSierpinski function. The drawSierpinski function itself will draw only one triangle: the initial one that points upwards. Then it'll call the function subTriangle, and that is the actual recursive function, that'll draw all the upside down triangles.

The function subTriangle draws a single upside down triangle, with the 3 corners you give it with it's parameters. Then it'll call itself 3 times again, to draw 3 smaller triangles. For these 3 triangles, new corners are used of course, and these have to be calculated. In the following image, if the black triangle is the big triangle the subTriangle function has drawn, then the 3 red triangles are the new ones that have to be calculated:



The corners of the big triangle are a1, a2 and a3. The corners of one of the smaller triangles are b1, b2 and b3 as you can see on the image. If we see all these points as vectors, the the formulas for the points b (with the points a being known) are:

b3 = (a1 + a2) / 2, because b3 lies in the center between a1 and a2, this point is the average of a1 and a2!

b1 = b3 + (a1 - a3) / 2: if you examine well, you'll see that the point b1 is the sum of the point b3 and the vector (a1 - a3) / 2, it's divided through 2 because the corresponding side of the smaller triangle is half as big.

And finally,

b2 = b3 + (a2 - a3) / 2: this is very similar to the other formula, but with the other side.

For the other 2 small triangles, something similar is done.

In the code, we aren't using a vector class, so x and y are separate variables, and because of the way vector additions work, we simply have to do the same thing twice, once for x, and once for y, with the same formulas.

For the coordinates of triangle corners, floating point numbers are used for more precision.

With this knowledge the program can be made, the comments in the code below will explain how it works:


		//Declaration of the drawSierpinski function. The coordinates are the 3 outer corners
		of the Sierpinski Triangle.
void drawSierpinski(float x1, float y1, float x2, float y2, float x3, float y3);
//Declaration of the subTriangle function, the coordinates are the 3 corners, and n is the number of
recursions.
void subTriangle(int n, float x1, float y1, float x2, float y2, float x3, float y3);

//depth is the number of recursive steps
int depth = 7;

//The main function sets up the screen and then calls the drawSierpinski function
int main(int argc, char *argv[])
{
    screen(640, 480, 0, "Sierpinski Triangle");
    cls(RGB_White); //Make the background white
    drawSierpinski(10, h - 10, w - 10, h - 10, w / 2, 10); //Call the sierpinski function (works with any
	corners inside the screen)
    //After drawing the whole thing, redraw the screen and wait until the any key is pressed
    redraw();
    sleep();
    return(0);   
}

//This function will draw only one triangle, the outer triangle (the only not upside down one),
and then start the recursive function
void drawSierpinski(float x1, float y1, float x2, float y2, float x3, float y3)
{
        //Draw the 3 sides of the triangle as black lines
        drawLine(int(x1), int(y1), int(x2), int(y2), RGB_Black);
        drawLine(int(x1), int(y1), int(x3), int(y3), RGB_Black);
        drawLine(int(x2), int(y2), int(x3), int(y3), RGB_Black);
        
        //Call the recursive function that'll draw all the rest. The 3 corners of it are always 
		the centers of sides, so they're averages
        subTriangle
        (
            1, //This represents the first recursion
            (x1 + x2) / 2, //x coordinate of first corner
            (y1 + y2) / 2, //y coordinate of first corner
            (x1 + x3) / 2, //x coordinate of second corner
            (y1 + y3) / 2, //y coordinate of second corner
            (x2 + x3) / 2, //x coordinate of third corner
            (y2 + y3) / 2  //y coordinate of third corner
        );            
}    

//The recursive function that'll draw all the upside down triangles
void subTriangle(int n, float x1, float y1, float x2, float y2, float x3, float y3)
{   
    //Draw the 3 sides as black lines
    drawLine(int(x1), int(y1), int(x2), int(y2), RGB_Black);
    drawLine(int(x1), int(y1), int(x3), int(y3), RGB_Black);
    drawLine(int(x2), int(y2), int(x3), int(y3), RGB_Black);        
    
    //Calls itself 3 times with new corners, but only if the current number of recursions is 
	smaller than the maximum depth
    if(n < depth)
    {
        //Smaller triangle 1
        subTriangle
        (
            n+1, //Number of recursions for the next call increased with 1
            (x1 + x2) / 2 + (x2 - x3) / 2, //x coordinate of first corner
            (y1 + y2) / 2 + (y2 - y3) / 2, //y coordinate of first corner
            (x1 + x2) / 2 + (x1 - x3) / 2, //x coordinate of second corner
            (y1 + y2) / 2 + (y1 - y3) / 2, //y coordinate of second corner
            (x1 + x2) / 2, //x coordinate of third corner
            (y1 + y2) / 2  //y coordinate of third corner
        );
        //Smaller triangle 2
        subTriangle
        (
            n+1, //Number of recursions for the next call increased with 1
            (x3 + x2) / 2 + (x2 - x1) / 2, //x coordinate of first corner
            (y3 + y2) / 2 + (y2 - y1) / 2, //y coordinate of first corner
            (x3 + x2) / 2 + (x3 - x1) / 2, //x coordinate of second corner
            (y3 + y2) / 2 + (y3 - y1) / 2, //y coordinate of second corner
            (x3 + x2) / 2, //x coordinate of third corner
            (y3 + y2) / 2  //y coordinate of third corner
        );
        //Smaller triangle 3
        subTriangle
        (
            n+1, //Number of recursions for the next call increased with 1
            (x1 + x3) / 2 + (x3 - x2) / 2, //x coordinate of first corner
            (y1 + y3) / 2 + (y3 - y2) / 2, //y coordinate of first corner
            (x1 + x3) / 2 + (x1 - x2) / 2, //x coordinate of second corner
            (y1 + y3) / 2 + (y1 - y2) / 2, //y coordinate of second corner
            (x1 + x3) / 2, //x coordinate of third corner
            (y1 + y3) / 2  //y coordinate of third corner        
        );                
    }             
}

Here's what you see after running the program:



With "AND"


The method given above is only one of the very many ways to draw Sierpinski Triangles. One of these ways is with the AND operator. If you take of a pixel the x-coordinate as an integer, and the y-coordinate as an integer, and use the AND operator on them, if the result is 0, draw a pixel of one color, otherwise another. You'll then see a Sierpinski Triangle pop up!

The AND operator on two integers, takes both integers as a binary number, and uses AND on each of the corresponding bits. The AND operator on bits works as follows::

Operation
Result
0 AND 0
0
0 AND 1
0
1 AND 0
0
1 AND 1
1

This is done for every bit of the integer, and only if the resulting integer is in binary 0000000000000000, the pixel is given another color.

The code is a very simple double loop that goes through every pixel and checks if x & y is 0 or not, where "&" is the binary AND operator in C++. By using "x & y" inside an if condition, it'll only be false in the case x & y is 0, and in all other cases a white pixel is drawn, so the result will be a black sierpinski triangle on a white background.

int main(int argc, char *argv[])
{
    screen(256, 256, 0, "AND");
    for(int x = 0; x < w; x++)
    for(int y = 0; y < h; y++)
    {
        if(x & y) pset(x, y, RGB_White);
    }    
    redraw();
    sleep();
    return 0;
}

The result looks best if the screen sizes are powers of 2, otherwise you see only a part of the triangle.



With a Random Function



Another totally different way to draw an approximation of the Sierpinski Triangle works as follows:

1) define 3 points with coordinates: a (ax, ay), b (bx, by) and c (cx, cy). These will become the corners of the large outer triangle.

2) define another point, p (px, py) and place it in a corner of the triangle (for example px = ax and py = ay).

3) draw a point at location (px, py) with a pencil

4) roll a theoretical die with 3 sides (side 0, side 1 and side 2), or just make a random choice between "0", "1" and "2".

5) now change the coordinates of point p, depending on what number you rolled:

  • if you rolled 0, p = (p+a) / 2
  • if you rolled 1, p = (p+b) / 2
  • if you rolled 2, p = (p+c) / 2
6) go back to step 2, there place the point at the new position of p, and keep looping through this until you get tired

Even though the whole process is randomized, after enough steps, the result will look more and more like a Sierpinski Triangle!

This isn't too hard to code, the comments explain how everything works:

//How much pixels should be randomly chosen and drawn
#define numSteps 10000

int main(int argc, char *argv[])
{
    //create the screen and make it white
    screen(256, 256, 0, "Sierpinski Triangle");
    cls(RGB_White);
    
    //the 3 corners of the outer triangle
    float ax = 10;
    float ay = h - 10;
    float bx = w - 10;
    float by = h - 10;
    float cx = w / 2;
    float cy = 10;

    //initial coordinates for the point px
    float px = ax;
    float py = ay;
    
    //do the process numSteps times
    for(int n = 0; n < numSteps; n++)
    {
        //draw the pixel
        pset(int(px), int(py), RGB_Black);
        
        //pick a random number 0, 1 or 2
        switch(abs(rand() % 3))
        {
            //depending on the number, choose another new coordinate for point p
            case 0:
                px = (px + ax) / 2.0;
                py = (py + ay) / 2.0;
                break;
            case 1:
                px = (px + bx) / 2.0;
                py = (py + by) / 2.0;
                break;
            case 2:
                px = (px + cx) / 2.0;
                py = (py + cy) / 2.0;
                break;
        }
    }
    
    //redraw, sleep and end the program
    redraw();
    sleep();
    return(0);     
}

The bigger you make the numSteps value, the more pixels will be drawn. These images show the result for 1000, 10000 and 100000 steps:

 

By playing a bit with the formulas you can get other shapes, like for example this one:



Gotten by changing some of the divisions through 2.0 into divisions through 3.0.

With Rectangle Recursion



Yet another way to draw a Sierpinski Triangle is with a recursive function that uses rectangles. The recursion process works as follows: Change every rectangle into an L-shape:



The L-shape itself consists out of 3 rectangles, which are again converted into an L-shape, etc...



If you keep doing this long enough, it'll look more and more like a Sierpinski Triangle. This is again something that can be programmed with a recursive function, pretty similar to the recursive code given higher, but this times rectangles are drawn, and new coordinates for 3 new rectangles have to be calculated every time.


		//the coordinates are 2 corners of the rectangle, n is the current recursion step
void drawSierpinski(int n, int x1, int y1, int x2, int y2);

//how much recursions maximum (after log_2(screenWidth) recursions the rectangles are
smaller than a pixel)
#define maxRecursions 8

int main(int argc, char *argv[])
{
    //create the screen and make it white
    screen(256, 256, 0, "Sierpinski Triangle");          
    
    //start the recursive function
    drawSierpinski(1, 0, 0, w - 1, h - 1);
    
    //redraw, sleep, etc...
    redraw();
    sleep();
    return(0);
}  

void drawSierpinski(int n, int x1, int y1, int x2, int y2)
{
    //draw white rectangle in the upper right part, thereby making a black L
    drawRect((x1 + x2) / 2, y1, x2 - 1, (y1 + y2) / 2 - 1, RGB_White);
    
    //call itself 3 times again, now for the 3 new rectangles in the L shape
    if(n < maxRecursions)
    {
        drawSierpinski(n + 1, x1, y1, (x1 + x2) / 2, (y1 + y2) / 2);
        drawSierpinski(n + 1, x1, (y1 + y2) / 2, (x1 + x2) / 2, y2);
        drawSierpinski(n + 1, (x1 + x2) / 2, (y1 + y2) / 2, x2, y2);
    }    
}

Here's the result for 3, 5 and 8 recursions:



To study the recursion a bit better, try to see what happens when the drawSierpinski function calls itself only 1 time instead of 3 (the other 2 calls are commented out): now, if maxRecursions is 8, only 8 rectangles are drawn, each one smaller than the previous one:



Now, we enable two of the calls to itself, and already more squares are being drawn, but the shape isn't so complex yet. Now on the right is 1 big square, left of it 2 half squares, left of those 4 1/4th squares, left of that 8 1/8th squares, and so on, with to the leftmost row 128 squares that are 128 times smaller than the big square on the right.



And finally, if we enable all 3 calls to itself, we get the Sierpinski Triangle, and so many squares are drawn that almost everything is white:



There's even another way to get a Sierpinski Triangle: with a cellular automaton, but this might be covered in a later article.

Sierpinski Carpet


With Rectangle Recursion


A different fractal is the Sierpinski Carpet. To draw one by hand, start with a white square, and then draw a black square in the center with each side 1/3th of the size of the original square:



Now, around the black square, are 8 white squares. In each of these 8, draw again a black square that is 1/8th smaller, and in the 8*8=64 new white squares, do it yet again:



Keep doing this until infinity, and you get a sierpinski carpet!

To draw it, we can use a recursive function that's pretty similar to the one used for the sierpinski triangle with rectangles, but now the function has to call itself 8 times instead of only 3, and use different coordinates. The coordinates x1,y1-x2,y2 get divided in 9 sections, in the center one the rectangle is drawn with rect, and the other 8 ones are used as parameters for the drawCarpet calls of the next recursion step.

//the coordinates are 2 corners of the rectangle, n is the current recursion step
void drawCarpet(int n, float x1, float y1, float x2, float y2);

//how much recursions maximum
#define maxRecursions 6

int main(int argc, char *argv[])
{
    //create the screen and make it white, use powers of 3 for the screen size for best result
    screen(243, 243, 0, "Sierpinski Carpet"); 
    cls(RGB_White);         
    
    //start the recursive function
    drawCarpet(1, 0, 0, w - 1, h - 1);
    
    //redraw, sleep, etc...
    redraw();
    sleep();
    return(0);
}  

void drawCarpet(int n, float x1, float y1, float x2, float y2)
{
    //draw black rectangle with 1/3th the size in the center of the given coordinates
    drawRect(int((2 * x1 + x2) / 3.0), int((2 * y1 + y2) / 3.0),
	 int((x1 + 2 * x2) / 3.0) - 1, int((y1 + 2 * y2) / 3.0) - 1, RGB_Black);
   
    //call itself 8 times again, now for the 8 new rectangles around the one that was just drawn
    if(n < maxRecursions)
    {
        drawCarpet(n + 1, x1                 , y1                 , (2 * x1 + x2) / 3.0, (2 * y1 + y2) / 3.0);
        drawCarpet(n + 1, (2 * x1 + x2) / 3.0, y1                 , (x1 + 2 * x2) / 3.0, (2 * y1 + y2) / 3.0);
        drawCarpet(n + 1, (x1 + 2 * x2) / 3.0, y1                 , x2                 , (2 * y1 + y2) / 3.0);
        drawCarpet(n + 1,  x1                , (2 * y1 + y2) / 3.0, (2 * x1 + x2) / 3.0, (y1 + 2 * y2) / 3.0);
        drawCarpet(n + 1, (x1 + 2 * x2) / 3.0, (2 * y1 + y2) / 3.0, x2                 , (y1 + 2 * y2) / 3.0);
        drawCarpet(n + 1, x1                 , (y1 + 2 * y2) / 3.0, (2 * x1 + x2) / 3.0,  y2                );
        drawCarpet(n + 1, (2 * x1 + x2) / 3.0, (y1 + 2 * y2) / 3.0, (x1 + 2 * x2) / 3.0,  y2                );
        drawCarpet(n + 1, (x1 + 2 * x2) / 3.0, (y1 + 2 * y2) / 3.0, x2                 ,  y2                );
    }    
}

And here's the result for 6 recursion steps:



If you want a bigger one, use a resolution of 729*729 pixels and 7 recursions.

With Ternary Numbers



There's also a method to draw the Sierpinski Carpet that's similar to the "AND" method for drawing the sierpinski triangle. Namely, you do a calculation for each pixel to check whether or not it should be colored.

This method is a bit more complex though, because you have to work in base 3, i.e. with ternary numbers. Ternary numbers have digits that can be '0', '1' or '2'.

The method works as follows:

Take both the coordinates of the pixel as integers written in ternary notation. For every digit, check if NOT both corresponding digits are '1'. If this never happens, then the point belongs to the carpet.

To find the first (rightmost) ternary digit of a number, modulo divide it though 3 (modulo division through 3 works as follows: 0%3=0, 1%3=1, 2%3=2, 3%3=0, 4%3=1, 5%3=2, 6%3=0, 7%3=1, etc.....).
To find the second ternary digit, first divide the number through 3 (integer division, i.e. remove the numbers behind the point), and then modulo divide it though 3.
To find the third ternary digit, divide it through 9, then modulo divide through 3.
To find the fourth, divide through 27, then modulo divide through 3,
etc...

The example below uses a resolution of 243 by 243 pixels, so we have to check only the first 5 ternary digits of the pixel coordinates, since with 5 ternary digits you can represent all numbers from 0 to 242.

The condition in the "if", is written out on many lines, and the condition checks for each of the 5 digits if NOT both the one from the x coordinate and the one from the y coordinate are together 1. If the condition is true, a white pixel is drawn at x,y.

int main(int argc, char *argv[])
{
    screen(243, 243, 0, "Sierpinski Carpet");
    for(int x = 0; x < w; x++)
    for(int y = 0; y < h; y++)
    {
        if
        (
            //Not both the first (rightmost) digits are '1' in base 3
            !(
                   (x / 1) % 3 == 1
                && (y / 1) % 3 == 1
            )

            &&

            //Not both the second digits are '1' in base 3
            !(
                   (x / 3) % 3 == 1
                && (y / 3) % 3 == 1
            )

            &&

            //Not both the third digits are '1' in base 3
            !(
                   (x / 9) % 3 == 1
                && (y / 9) % 3 == 1
            )

            &&

            //Not both the fourth digits are '1' in base 3
            !(
                   (x / 27) % 3 == 1
                && (y / 27) % 3 == 1
            )

            &&

            //Not both the fifth digits are '1' in base 3
            !(
                   (x / 81) % 3 == 1
                && (y / 81) % 3 == 1
            )
        )
        pset(x, y, RGB_White);
            
    }   
    redraw();
    sleep();
    return(0);
}

The result looks exactly the same as from the previous program, even though this one uses a totally different method:



If you want to increase the resolution, you have to add an extra condition for the 6th digit (where you divide through 243), etc... for every time you triple the resolution.

The condition that checks for the 5th digit (the 5th ternary digit from the right) is the one that's responsible for the big black square in the center.
The condition that checks for the 4th digit, is the one responsible for the 8 smaller squares around the center square,
etc...

If you remove the condition for the 5th digit, the center black square is gone, and instead you get this:



If you remove instead for example the condition that checks for the 3th digit, all the black squares of the third order are gone while all others are left:



So if you triple the resolution, the square that is now the center square will become a square in the top left, and you need an even bigger black square in the new center, which is why you need a new condition that checks for the 6th digit then.

© Lode Vandevenne. Reproduced with permission.


Be the first one to comment on this page.




  Graphics eBooks
More Links » »
 
 Graphics FAQs
More Links » »
 
 Graphics Interview Questions
More Links » »
 
 Graphics Articles
More Links » »
 
 Graphics News
More Links » »
 
 Graphics Jobs
More Links » »

Share And Enjoy:These icons link to social bookmarking sites where readers can share and discover new web pages.
  • blinkbits
  • BlinkList
  • blogmarks
  • co.mments
  • connotea
  • del.icio.us
  • De.lirio.us
  • digg
  • Fark
  • feedmelinks
  • Furl
  • LinkaGoGo
  • Ma.gnolia
  • NewsVine
  • Netvouz
  • RawSugar
  • Reddit
  • scuttle
  • Shadows
  • Simpy
  • Smarking
  • Spurl
  • TailRank
  • Wists
  • YahooMyWeb

Previoushome Next

Keywords: Sierpinski Fractals, Graphics, Graphics, Graphics tutorial, Graphics tutorial pdf, history of Graphics, learn Graphics

HTML Quizzes
HTML Quiz
XHTML Quiz
CSS Quiz
TCP/IP Quiz
CSS 1.0 Quiz
CSS 2.0 Quiz
HLML Quiz
XML Quizzes
XML Quiz
XSL Quiz
XSLT Quiz
DTD Quiz
Schema Quiz
XForms Quiz
XSL-FO Quiz
XML DOM Quiz
XLink Quiz
XQuery Quiz
XPath Quiz
XPointer Quiz
RDF Quiz
SOAP Quiz
WSDL Quiz
RSS Quiz
WAP Quiz
Web Services Quiz
Browser Scripting Quizzes
JavaScript Quiz
VBScript Quiz
DHTML Quiz
HTML DOM Quiz
WMLScript Quiz
E4X Quiz
Server Scripting Quizzes
ASP Quiz
PERL Quiz
SQL Quiz
ADO Quiz
CVS Quiz
Python Quiz
Apple Script Quiz
PL/SQL Quiz
SQL Server Quiz
PHP Quiz
.NET (dotnet) Quizzes
Microsoft.Net Quiz
ASP.Net Quiz
.Net Mobile Quiz
C# : C Sharp Quiz
ADO.NET Quiz
VB.NET Quiz
VC++ Quiz
Multimedia Quizzes
SVG Quiz
Flash Quiz
Media Quiz
SMIL Quiz
Photoshop Quiz
Gimp Quiz
Matlab Quiz
Gnuplot Programming Quiz
GIF Animation Quiz
Scientific Visualization Quiz
Graphics Quiz
Web Building Quizzes
Web Browsers Quiz
Web Hosting Quiz
W3C Quiz
Web Building Quiz
Web Quality Quiz
Web Semantic Quiz
Web Careers Quiz
Weblogic Quiz
SEO Quiz
Web Site Hosting Quiz
Domain Name Quiz
Java Quizzes
Java Quiz
JSP Quiz
Servlets Quiz
Struts Quiz
EJB Quiz
JMS Quiz
JMX Quiz
Eclipse Quiz
J2ME Quiz
JBOSS Quiz
Programming Langauges Quizzes
C Quiz
C++ Quiz
Visual Basic Quiz
Data Structures Using C Quiz
Cobol Quiz
Assembly Language Quiz
Mainframe Quiz
Forth Programming Quiz
Lisp Programming Quiz
Pascal Quiz
Delphi Quiz
Fortran Quiz
OOPs Quiz
Data Warehousing Quiz
CGI Programming Quiz
Emacs Quiz
Gnome Quiz
ILU Quiz
Soft Skills Quizzes
Communication Skills Quiz
Time Management Quiz
Project Management Quiz
Team Work Quiz
Leadership Skills Quiz
Corporate Communication Quiz
Negotiation Skills Quiz
Database Quizzes
Oracle Quiz
MySQL Quiz
Operating System Quizzes
BSD Quiz
Symbian Quiz
Unix Quiz
Internet Quiz
IP-Masquerading Quiz
IPC Quiz
MIDI Quiz
Software Testing Quizzes
Testing Quiz
Firewalls Quiz
SAP Module Quizzes
ERP Quiz
ABAP Quiz
Business Warehousing Quiz
SAP Basis Quiz
Material Management Quiz
Sales & Distribution Quiz
Human Resource Quiz
Netweaver Quiz
Customer Relationship Management Quiz
Production and Planning Quiz
Networking Programming Quizzes
Corba Quiz
Networking Quiz
Microsoft Office Quizzes
Microsoft Word Quiz
Microsoft Outlook Quiz
Microsoft PowerPoint Quiz
Microsoft Publisher Quiz
Microsoft Excel Quiz
Microsoft Front Page Quiz
Microsoft InfoPath Quiz
Microsoft Access Quiz
Accounting Quizzes
Financial Accounting Quiz
Managerial Accounting Quiz
Testimonials | Contact Us | Link to Us | Site Map
Copyright ? 2008. Academic Tutorials.com. All rights reserved Privacy Policies | About Us
Our Portals : Academic Tutorials | Best eBooksworld | Beyond Stats | City Details | Interview Questions | Discussions World | Excellent Mobiles | Free Bangalore | Give Me The Code | Gog Logo | Indian Free Ads | Jobs Assist | New Interview Questions | One Stop FAQs | One Stop GATE | One Stop GRE | One Stop IAS | One Stop MBA | One Stop SAP | One Stop Testing | Webhosting in India | Dedicated Server in India | Sirf Dosti | Source Codes World | Tasty Food | Tech Archive | Testing Interview Questions | Tests World | The Galz | Top Masala | Vyom | Vyom eBooks | Vyom International | Vyom Links | Vyoms | Vyom World | Important Websites
Copyright ? 2003-2024 Vyom Technosoft Pvt. Ltd., All Rights Reserved.