1 / 22

CSE 20232 Lecture 36 – Procedural Fractals

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.

Download Presentation

CSE 20232 Lecture 36 – Procedural Fractals

An Image/Link below is provided (as is) to download presentation 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. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


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

  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. 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. 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. 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. Koch Star • Initial shape (3 edges forming an equilateral triangle) • Snowflake shown at detail levels 1, 2, 3, 4 • Images from wikipedia.com

  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<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]

  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. 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. 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. 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. Sierpenski Dragon • Initial shape (4 edges forming a square) • Dragon shown at detail levels 1, 2, 3

  13. Square Gasket • Based on a square shape • Start with a single square • 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

  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. 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. 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. 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 1st replacement after 2nd

  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. 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. 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. 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. 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 • SerpGasket* : Shape • Triangle based, area subdivision and replacement • SerpDragon* : Shape • Square based, edge division and replacement

More Related