CSE 20232 Lecture 36 – Procedural Fractals

1 / 22

# CSE 20232 Lecture 36 – Procedural Fractals - PowerPoint PPT Presentation

CSE 20232 Lecture 36 – Procedural Fractals. Line replacement approach Koch Star (Snowflake) Area replacement approach Sierpenski Triangle Iterated Function System approach Heighway Dragon. Line replacement.

I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.

## PowerPoint Slideshow about 'CSE 20232 Lecture 36 – Procedural Fractals' - lapis

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.

- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript
CSE 20232Lecture 36 – Procedural Fractals
• Line replacement approach
• Koch Star (Snowflake)
• Area replacement approach
• Sierpenski Triangle
• Iterated Function System approach
• Heighway Dragon
Line replacement
• Fractal shapes are based on lines or curves that are replaced by sequences of similar lines or curves at each level of recursion
• Shapes are “self-similar”
• Same/similar shapes at every level
• Examples
• Koch Star (Snowflake)
• Sierpenski Dragon
• Heighway Dragon
Area Replacement
• Fractal shapes are based on simple shapes that are replaced or “cut out” with collections of the same or similar shapes
• Again, these are self-similar at all levels of detail
• Examples
• Box Fractal (our Square)
• Sierpenski Carpet
Iterated Function System
• A method of generating a fractal by repeated application of a set of functions
• Each application typically moves one point on the fractal to another
• Examples
• Mandelbrot & Julia Sets (escape time measure)
• Heighway Dragon (two functions selected at random)
• Fern (4 functions randomly chosen with set frequencies)
Koch Star
• Based on 3 Koch Curves (triangle shape)
• Start each curve with a line segment
• Subdivide segment into thirds
• Replace middle third with two sides of an equilateral triangle that would have had the replaced edge segment as its third side
• These “bump-outs” always go on the same side of the original line
• Original segment after first replacement
Koch Star
• Initial shape (3 edges forming an equilateral triangle)
• Snowflake shown at detail levels 1, 2, 3, 4
• Images from wikipedia.com
Koch Star

// need to pass WinStuff &X or use it globally

void KochStar::draw(void)

{

if (Xwin->isOpen())

{

// call function to draw (after subdividing as necessary)

// each of the three triangle edges

subdivide_edge_and_draw(pt[0],pt[1],depth);

subdivide_edge_and_draw(pt[1],pt[2],depth);

subdivide_edge_and_draw(pt[2],pt[0],depth);

}

}

// NOTE: the corner points are in the vector<Point> pt;

// and each has an x and y coordinate. KochStar is a class

// that inherits from Shape and the outline of any shape is

// a polygon of edges between point pairs in the sequence

// pt[0] to pt[1], pt[1] to pt[2], ..., pt[n-1] to pt[0]

Koch Star edge manipulation

void KochStar::subdivide_edge_and_draw(

const Point& a, const Point& b, int rec_depth)

{

if (rec_depth > 1)

{

// Point ab1 is 1/3 distance from a to b

Point ab1( (2.0*a.getx()+b.getx()) / 3.0,

(2.0*a.gety()+b.gety()) / 3.0);

// Point ab2 is 2/3 distance from a to b

Point ab2( (a.getx()+2.0*b.getx()) / 3.0,

(a.gety()+2.0*b.gety()) / 3.0);

// calculate length of current edge (a,b)

double dx = b.getx() - a.getx();

double dy = b.gety() - a.gety();

double L = sqrt(dx*dx + dy*dy);

Koch Star edge manipulation

// calculate the direction of the current edge (a,b)

double theta = atan2(dy,dx);

// increase angle by 60 degrees

theta += PI/3.0;

if (theta < 0.0)

theta = 2.0*PI + theta;

// calculate coordinates of point bumped out from triangle

// it starts at point ab1 and runs at angle theta for 1/3 the

// original edge length

double outx = ab1.getx() + L*cos(theta)/3.0;

double outy = ab1.gety() + L*sin(theta)/3.0;

Koch Star edge manipulation

// create a Point with these coordiantes

Point bump(outx,outy);

// make recursive calls to further subdivide edges and draw

// note: rec_depth is decreased by 1 in each call

subdivide_edge_and_draw(a,ab1,rec_depth-1); // edge (a,ab1)

subdivide_edge_and_draw(ab1,bump,rec_depth-1); // edge (ab1,bump)

subdivide_edge_and_draw(bump,ab2,rec_depth-1); // edge (bump,ab2)

subdivide_edge_and_draw(ab2,b,rec_depth-1); // edge (ab2,b)

}

else

// now draw the small edge piece from a to b

Xwin->X_draw_edge(a.getx(),a.gety(),b.getx(),b.gety(),colorX);

}

Sierpenski Dragon
• Based on 4 curves (square shape)
• Start each curve with a line segment
• Subdivide segment into fourths
• Replace middle two segments with three sides of a square that would have had the replaced edge segment as its fourth side
• These “bump-outs” always go out and then in
• Original segment after first replacement
Sierpenski Dragon
• Initial shape (4 edges forming a square)
• Dragon shown at detail levels 1, 2, 3
• Based on a square shape
• Replace the square with 5, each having a side length 1/3rd that of the original
• Replacement squares go in each corner and the center
• Original after 1st replacement after 2nd

void Square::draw()

{

if (Xwin->isOpen())

{

// if this is a depth 1 Square then actually draw it

if (depth == 1)

// Xlib code to draw 4 edges bounding the square

for (int i=0; i<4; i++)

Xwin->X_draw_edge(pt[i].getx(),pt[i].gety(),

pt[(i+1)%4].getx(),pt[(i+1)%4].gety(),

colorX);

else

// Otherwise, subdivide & draw smaller Squares

subdivide_and_draw();

}

}

Square subdivision

void Square::subdivide_and_draw(void)

{

double mult=1.0; // 0.5 or other value for interesting shapes

if (depth > 1)

{

// new squares have sides 1/3 length of original

double newSide = fabs(pt[0].getx()-pt[2].getx())/3.0;

// Center is halfway between opposite corners pt[0] & pt[2]

double cx = 0.5*(pt[0].getx()+pt[2].getx());

double cy = 0.5*(pt[0].gety()+pt[2].gety());

// 5 new squares 1/3 side size as originals

Square s1(Xwin,Point(cx,cy),newSide);

Square s2(Xwin,Point(cx+mult*newSide,cy+mult*newSide),newSide);

Square s3(Xwin,Point(cx+mult*newSide,cy-mult*newSide),newSide);

Square s4(Xwin,Point(cx-mult*newSide,cy+mult*newSide),newSide);

Square s5(Xwin,Point(cx-mult*newSide,cy-mult*newSide),newSide);

Square subdivision

// set color of 5 new Squares same as this one

int r, g, b;

getColor(r,g,b);

s1.setColor(r,g,b); s2.setColor(r,g,b);

s3.setColor(r,g,b); s4.setColor(r,g,b);

s5.setColor(r,g,b);

// set depth to 1 less than this Square

s1.setDepth(depth-1); s2.setDepth(depth-1);

s3.setDepth(depth-1); s4.setDepth(depth-1);

s5.setDepth(depth-1);

// draw the 5 smaller Squares

s1.draw(); s2.draw();

s3.draw(); s4.draw();

s5.draw();

}

}

• Based on a triangle shape
• Replace the triangle with 3, each having a side length 1/2 that of the original
• Replacement triangles go in each corner
• Original after 1st replacement after 2nd
Heighway Dragon
• Producible in several ways
• Folding
• Fold strip of paper in half, again and again, in same direction
• Unfold so each fold is 90 degrees and look at shape edge-on
• Line replacement
• Replace with two segments L/sqrt(2) forming an isosceles triangle with original
• The replace each of these in turn, the same way, but alternate direction of bump, left, right, left, …
• Levels of detail 1,2,3,4 from wikipedia.com
Heighway Dragon
• Producible in several ways
• Iterative Function System
• Randomly alternate between these two functions to derive next point Z from previous
• Z = ((1+j)*Z)/2
• Z = 1 –((1-j)*Z)/2
• The UNION of all such points is the Dragon
• Example: 100,000 iterations
Heighway Dragon IFS (main)

// as in Mandelbrot set program, image size is ROWS x COLUMNS,

// complex plane is LEFT..RIGHT, TOP..BOTTOM

for (r=0;r<ROWS;r++)

for (c=0;c<COLUMNS;c++)

image[r][c] = 0; // set all pixels to black

Z.setReal(0.0);

Z.setImaginary(0.0);

for (int i=0; i<count; i++)

{

nextPoint(Z); // finds next Z in IFS defining dragon

r = (int)((TOP-Z.getImaginary())/dy); // find image row

c = (int)((Z.getReal()- LEFT)/dx); // find image column

if (0 <= r && r < ROWS && 0 <= c && c < COLUMNS)

image[r][c] = 32 + i%224; // set pixel color

else

cout << "bad r,c" << r << ' ' << c << endl;

}

Heighway Dragon IFS (calc)

// the Heighway Dragon is defined by applying each of the

// following functions to the previous value of Z in order

// to find the next value of Z. The choice of which to

// apply is random.

void nextPoint(Complex& Z)

{

if (rand()%2)

Z = 0.5*Complex(1.0,1.0)*Z;

else

Z = 1.0 - 0.5*Complex(1.0,-1.0)*Z;

}

A Fractal Shape Inheritance Hierarchy
• Point
• Simple location in 2D plane
• Shape
• Polygon with edges between sequence of Point pairs
• KochStar : Shape
• Triangle based, edge division and replacement
• Square : Shape
• Square based, area division and replacement