#!/usr/bin/ruby # ## http://rosettacode.org/wiki/Draw_a_sphere # # Generates a PGM image. func normalize (vec) { vec »/» (vec »*« vec -> sum.sqrt) } func dot (x, y) { -(x »*« y -> sum) `max` 0 } var x = var y = 255 x += 1 if x.is_even # must be odd var light = normalize([ 3, 2, -5 ]) var depth = 255 func draw_sphere(rad, k, ambient) { var r2 = (rad * rad) var r = (-rad .. rad) gather { for x in (r), y in (r) { if ((var x2 = x*x) + (var y2 = y*y) < r2) { var vector = normalize([x, y, (r2 - x2 - y2).sqrt]) var intensity = (dot(light, vector)**k + ambient) take(0 `max` (intensity*depth -> int) `min` depth) } else { take(0) } } } } var outfile = %f'sphere-sidef.pgm' var out = outfile.open('>:raw') out.say("P5\n#{x} #{y}\n#{depth}") # .pgm header out.write(draw_sphere((x-1)/2, .9, .2).map{.chr}.join) out.close