Download presentation
Presentation is loading. Please wait.
Published byEmmalee Aymond Modified over 10 years ago
1
1 Line replacement approach Koch Star (Snowflake) Area replacement approach Sierpenski Triangle Iterated Function System approach Heighway Dragon CSE 20232 Lecture 34 – Procedural Fractals
2
2 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
3
3 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 Triangle (our Gasket) Sierpenski Carpet
4
4 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)
5
5 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
6
6 Koch Star Initial shape (3 edges forming an equilateral triangle) Snowflake shown at detail levels 1, 2, 3, 4 Images from wikipedia.com
7
7 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 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]
8
8 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);
9
9 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;
10
10 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); }
11
11 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
12
12 Sierpenski Dragon Initial shape (4 edges forming a square) Dragon shown at detail levels 1, 2, 3
13
13 Square Gasket Based on a square shape Start with a single square Replace the square with 5, each having a side length 1/3 rd that of the original Replacement squares go in each corner and the center Original after 1 st replacement after 2 nd
14
14 Square Gasket 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(); }
15
15 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);
16
16 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(); }
17
17 Sierpenski Gasket Based on a triangle shape Start with a single triangle Replace the triangle with 3, each having a side length 1/2 that of the original Replacement triangles go in each corner Original after 1 st replacement after 2 nd
18
18 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 Start with a line (length L) 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
19
19 Heighway Dragon Producible in several ways Iterative Function System Start with Z as the origin of the complex plane 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
20
20 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; }
21
21 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; }
22
22 Our Fractal Shape Inheritance Hierarchy (for last homework) 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 SerpGasket* : Shape Triangle based, area subdivision and replacement SerpDragon* : Shape Square based, edge division and replacement * you will complete these based on given examples
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.