FlickerShowMedia
YaBB Newbies
Offline
Posts: 14
New programmer, working with Koch example
Apr 30th , 2009, 4:03pm
Alright, so I'm a (semi)new programmer, but I've realized my initial goal of a custom cellular autonoma was a tad grand, so I'm starting small and working up. I've always loved fractals, and I'd like to be able to write code to draw custom fractal curves. I've begun trying to alter the Koch Curve example, but I've hit a wall. I've found where (i think) the angle is set, but when I reset it from 60 to 45, it doesn't change that much. To test it I set it to 89 (near-right angle, but still a triangle) and it was still at a semi-sharp inward angle. I'd like to be able to have all angle-based calculation done by a variable, because I'd like to set the angle dependent on the position of the mouse. Ok, so here's what I've done to the code so far, if anybody can tell me how to directly control the angle, that'd be exactly what I'm looking for. I've added room for it to breathe on all sides following some sketches and counting on graph paper to get the points that it ever approaches, as well as sped up the refresh rate and disabled redrawing the background, for debugging purposes. KochFractal k; void setup() { size(1024, 512); background(0); frameRate(24); // Animate slowly k = new KochFractal(); smooth(); } void draw() { //background(0); // Draws the snowflake! k.render(); // Iterate k.nextLevel(); // Let's not do it more than 5 times. . . if (k.getCount() > 15) { k.restart(); } } // A class to manage the list of line segments in the snowflake pattern class KochFractal { Point start; // A point for the start Point end; // A point for the end ArrayList lines; // A list to keep track of all the lines int count; public KochFractal() { start = new Point(width/4, height*2/5); end = new Point(width*3/4, height*2/5); lines = new ArrayList(); restart(); } void nextLevel() { // For every line that is in the arraylist // create 4 more lines in a new arraylist lines = iterate(lines); count++; } void restart() { count = 0; // Reset count lines.clear(); // Empty the array list lines.add(new KochLine(start,end)); // Add the initial line (from one end point to the other) } int getCount() { return count; } // This is easy, just draw all the lines void render() { for(int i = 0; i < lines.size(); i++) { KochLine l = (KochLine)lines.get(i); l.render(); } } //I CHANGED IT SO IT CALCULATED FROM THE ENDS, NOW WHAT? // This is where the **MAGIC** happens // Step 1: Create an empty arraylist // Step 2: For every line currently in the arraylist // - calculate 4 line segments based on Koch algorithm // - add all 4 line segments into the new arraylist // Step 3: Return the new arraylist and it becomes the list of line segments for the structure // As we do this over and over again, each line gets broken into 4 lines, which gets broken into 4 lines, and so on. . . ArrayList iterate(ArrayList before) { ArrayList now = new ArrayList(); //Create emtpy list for(int i = 0; i < before.size(); i++) { KochLine l = (KochLine)lines.get(i); // A line segment inside the list // Calculate 5 koch points (done for us by the line object) Point a = l.start(); //Point b = l.kochleft(); Point c = l.kochmiddle(); //Point d = l.kochright(); Point e = l.end(); // Make line segments between all the points and add them /* now.add(new KochLine(a,b)); now.add(new KochLine(b,c)); now.add(new KochLine(c,d)); now.add(new KochLine(d,e)); */ now.add(new KochLine(a,c)); now.add(new KochLine(c,e)); } return now; } } // A class to describe one line segment in the fractal // Includes methods to calculate midpoints along the line according to the Koch algorithm class KochLine { // Two points, // a is the "left" point and // b is the "right point Point a,b; KochLine(Point a_, Point b_) { a = a_.copy(); b = b_.copy(); } void render() { stroke(255); line(a.x,a.y,b.x,b.y); } Point start() { return a.copy(); } Point end() { return b.copy(); } // This is easy, just 1/3 of the way Point kochleft() { float x = a.x + (b.x - a.x) / 3f; float y = a.y + (b.y - a.y) / 3f; return new Point(x,y); } // More complicated, have to use a little trig to figure out where this point is! Point kochmiddle() { float x = a.x + .5f * (b.x - a.x) + (sin(radians(360))*(b.y-a.y)) / 2; float y = a.y + .5f * (b.y - a.y) - (sin(radians(300))*(b.x-a.x)) / 2; return new Point(x,y); } // Easy, just 2/3 of the way Point kochright() { float x = a.x + 2*(b.x - a.x) / 3f; float y = a.y + 2*(b.y - a.y) / 3f; return new Point(x,y); } } class Point { float x,y; Point(float x_, float y_) { x = x_; y = y_; } Point copy() { return new Point(x,y); } } (the fractal I'm attempting to draw right now is the Levy C Curve, which can be found by google it's name (I can't post links... too new)