28
11
The Chaos Game is a simple method to generate fractals. Given a starting point, a length ratio r and a set of 2D points, repeatedly do the following:
- From your set of points, pick one at random (uniformly).
- Average that point and the last drawn point (or the starting point) using r and 1 - r as the weights (i.e. r = 0 means you get the starting point, r = 1 means you get the random point and r = 0.5 means you get the point halfway in between.)
- Draw the resultant point.
For instance, if you picked the vertices of an equilateral triangle and r = 0.5, the plotted points would map out a Sierpinski triangle:
You're to write a program or function which "plays" the chaos game to create a fractal.
Input
You may write either a program or a function, and take following inputs via ARGV, STDIN or function argument:
- The number of points to plot.
- The starting coordinate (which has to be plotted, too!).
- The averaging weight r in the interval [0,1].
- A list of points to choose from.
Output
You may render on screen or write an image file. If the result is rasterised, it needs to be at least 600 pixels on each side, all points must be on the canvas, and at least 75% of the horizontal and vertical extent of the image must be used for points (this is to avoid answers with a single black pixels saying "it's really far zoomed out"). The x and y axis must be on the same scale (that is the line from (0,0) to (1,1) must be at a 45 degree angle) and each point plotted in the chaos game must be represented as a single pixel (if your plotting method anti-aliases the point, it may be spread over 2x2 pixels).
Colours are your choice, but you need at least two distinguishable colours: one for the background and one for the dots plotted during the chaos game. You may but don't have to plot the input points.
Please include three interesting example outputs in your answer.
Scoring
This is code golf, so the shortest answer (in bytes) wins.
Edit: You no longer need to plot the input points, as they aren't really visible as single pixels anyway.
What does "each point plotted ... must be represented as a single pixel" mean? Is it a) that no anti-aliasing should be used; or b) that the number of points in the second colour must be equal to the first item from the input? Note that b) is impossible to guarantee unless the iteration procedure has a test for "Does this pixel coincide with a previously plotted one?", because if the random number selector selects the same point enough times in a row then the position will converge to that point. – Peter Taylor – 2014-09-25T22:27:02.107
@PeterTaylor It was intended to avoid people plotting large dots as the points (like Mathematica does by default), but I've already noticed that anti-aliasing causes some trouble with ensuring single pixels in Soham's answer. I think I'll relax this to "must not be larger than 2x2 pixels", which should cover all the anti-aliasing trouble. – Martin Ender – 2014-09-25T22:29:09.327
I think I misunderstood something: You do always take the 'mean' of the last point you plotted and a random point of the current list. Then you add that new point to the list. Is that correct? It seems that if you have many points in one 'corner' you will get many more there but it is unlikely to get out of that cloud - at least my code always 'converges' pretty fast to points that are too close to each other to really enhance the picture. – flawr – 2014-09-26T15:26:45.043
1@flawr no, you don't add the new point to the list. The list is fixed - the algorithm only cares about the last point that was plotted, not the ones before it. – Nathaniel – 2014-09-26T15:37:24.403
Thanks, that explains a lot, should perhaps be clarified in the question. – flawr – 2014-09-26T15:46:48.993