2016-12-05 23:44:36 +01:00
|
|
|
|
func normalize (vec) { vec »/» (vec »*« vec -> sum.sqrt) }
|
2017-09-23 10:01:46 +02:00
|
|
|
|
func dot (x, y) { -(x »*« y -> sum) `max` 0 }
|
2016-12-05 23:44:36 +01:00
|
|
|
|
|
|
|
|
|
|
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 pixels = []
|
|
|
|
|
|
var r2 = (rad * rad)
|
|
|
|
|
|
var range = (-rad .. rad)
|
|
|
|
|
|
for x,y in (range ~X range) {
|
|
|
|
|
|
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)
|
2017-09-23 10:01:46 +02:00
|
|
|
|
var pixel = (0 `max` (intensity*depth -> int) `min` depth)
|
2016-12-05 23:44:36 +01:00
|
|
|
|
pixels << pixel
|
|
|
|
|
|
}
|
|
|
|
|
|
else {
|
|
|
|
|
|
pixels << 0
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return pixels
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var outfile = %f'sphere-sidef.pgm'
|
|
|
|
|
|
var out = outfile.open('>:raw')
|
|
|
|
|
|
|
|
|
|
|
|
out.say("P5\n#{x} #{y}\n#{depth}") # .pgm header
|
2017-09-23 10:01:46 +02:00
|
|
|
|
out.print(draw_sphere((x-1)/2, .9, .2).map{.chr}.join)
|
2016-12-05 23:44:36 +01:00
|
|
|
|
out.close
|