|
| 1 | +# Visualize: Superformula |
| 2 | +# from Form+Code in Design, Art, and Architecture |
| 3 | +# by Casey Reas, Chandler McWilliams, and LUST |
| 4 | +# Princeton Architectural Press, 2010 |
| 5 | +# ISBN 9781568989372 |
| 6 | +# |
| 7 | +# Get Processing at http://www.processing.org/download |
| 8 | + |
| 9 | +attr_reader :scaler, :m, :n1, :n2, :n3 |
| 10 | + |
| 11 | +def settings |
| 12 | + size(700, 700) |
| 13 | + smooth(4) |
| 14 | +end |
| 15 | + |
| 16 | +def setup |
| 17 | + sketch_title('Superformula') |
| 18 | + no_fill |
| 19 | + stroke(255) |
| 20 | + @scaler = 200.0 |
| 21 | + @m = 2 |
| 22 | + @n1 = 18.0 |
| 23 | + @n2 = 1.0 |
| 24 | + @n3 = 1.0 |
| 25 | +end |
| 26 | + |
| 27 | +def draw |
| 28 | + background(0) |
| 29 | + push_matrix |
| 30 | + translate(width / 2, height / 2) |
| 31 | + newscaler = scaler |
| 32 | + 16.downto(0) do |s| |
| 33 | + begin_shape |
| 34 | + mm = m + s |
| 35 | + nn1 = n1 + s |
| 36 | + nn2 = n2 + s |
| 37 | + nn3 = n3 + s |
| 38 | + newscaler *= 0.98 |
| 39 | + sscaler = newscaler |
| 40 | + points = superformula(mm, nn1, nn2, nn3) |
| 41 | + curve_vertex( |
| 42 | + points[points.length - 1].x * sscaler, |
| 43 | + points[points.length - 1].y * sscaler |
| 44 | + ) |
| 45 | + (0...points.length).each do |i| |
| 46 | + curve_vertex(points[i].x * sscaler, points[i].y * sscaler) |
| 47 | + end |
| 48 | + curve_vertex(points[0].x * sscaler, points[0].y * sscaler) |
| 49 | + end_shape |
| 50 | + end |
| 51 | + pop_matrix |
| 52 | +end |
| 53 | + |
| 54 | +def superformula(m, n1, n2, n3) |
| 55 | + num_points = 360 |
| 56 | + phi = TWO_PI / num_points |
| 57 | + (0..num_points).map { |i| superformula_point(m, n1, n2, n3, phi * i) } |
| 58 | +end |
| 59 | + |
| 60 | +def superformula_point(m, n1, n2, n3, phi) |
| 61 | + t1 = cos(m * phi / 4) |
| 62 | + t1 = t1.abs |
| 63 | + t1 **= n2 |
| 64 | + t2 = sin(m * phi / 4) |
| 65 | + t2 = t2.abs |
| 66 | + t2 **= n3 |
| 67 | + r = (t1 + t2)**(1 / n1) |
| 68 | + return Vec2D.new if r.abs.zero? |
| 69 | + x = cos(phi) / r |
| 70 | + y = sin(phi) / r |
| 71 | + Vec2D.new(x, y) |
| 72 | +end |
0 commit comments