H = 100 W = 100 C0 = [0] * 3 C1 = [255] * 3 I = Array.new(H) { Array.new(W) { C1.dup } } def p(y, x, c, a = 1.0) y, x = y.to_i, x.to_i return if x < 0 || x >= W || y < 0 || y >= H || a <= 0 I[y][x] = a >= 1.0 ? c : (0..2).map { (c[it] * a + I[y][x][it] * (1 - a)).round } end def c(cx, cy, r, c) (2*r).times do |dy| (2*r).times do |dx| y = cy + dy - r x = cx + dx - r p(y, x, c) if (x-cx)**2 + (y-cy)**2 <= r**2 end end end def l(y0, x0, y1, x1, c, w) dy = y1 - y0 dx = x1 - x0 l = Math.hypot(dx, dy) return if l == 0 s = (l * 2).to_i (0..s).each do |i| t = i.to_f / s cy = y0 + dy * t cx = x0 + dx * t (-w..w).each do |oy| (-w..w).each do |ox| p(cy + oy, cx + ox, c) if ox**2 + oy**2 <= w**2 end end end end def r(x, y, w, h, c, a = 1) h.times do |dy| w.times do |dx| p(y + dy, x + dx, c, a) end end end srand(42) c(H/2, W/2, 50, [255, 165, 0]) c(H/2, W/2, 47, C1) c(H/2, W/2, 44, [255, 165, 0]) 10.times do |t| u = t * Math::PI / 5 lx = 50 + 45 * Math.sin(u) ly = 50 - 45 * Math.cos(u) l(ly, lx, H/2, W/2, C1, 1) end 10.times do |dy| 10.times do |dx| x = dx * 10 y = dy * 10 next if x < W/2 next if (x - 45)**2 + (y - 45)**2 > 55**2 next if rand < 0.5 c = [[255, 165, 0], [255, 140, 0], [255, 215, 0], [255, 205, 114], [255, 210, 127], [255, 192, 76], [255, 169, 12], [255, 228, 178]].sample r(x, y, 10, 10, c, 0.75) end end r(30, 35, 6, 25, C0) r(64, 35, 6, 25, C0) puts "P3" puts "#{W} #{H}" puts "255" I.each do |l| puts l.map { it * " " } * " " end