RosettaCodeData/Task/Death-Star/Sidef/death-star.sidef

63 lines
1.5 KiB
Text
Raw Permalink Normal View History

2016-12-05 23:44:36 +01:00
func hitf(sph, x, y) {
2019-09-12 10:33:56 -07:00
x -= sph[0]
y -= sph[1]
var z = (sph[3]**2 - (x**2 + y**2))
2016-12-05 23:44:36 +01:00
2019-09-12 10:33:56 -07:00
z < 0 && return nil
2016-12-05 23:44:36 +01:00
2019-09-12 10:33:56 -07:00
z.sqrt!
[sph[2] - z, sph[2] + z]
2016-12-05 23:44:36 +01:00
}
func normalize(v) {
2019-09-12 10:33:56 -07:00
v / v.abs
2016-12-05 23:44:36 +01:00
}
func dot(x, y) {
2019-09-12 10:33:56 -07:00
max(0, x*y)
2016-12-05 23:44:36 +01:00
}
2019-09-12 10:33:56 -07:00
var pos = [120, 120, 0, 120]
var neg = [-77, -33, -100, 190]
var light = normalize(Vector(-12, 13, -10))
2016-12-05 23:44:36 +01:00
func draw(k, amb) {
2019-09-12 10:33:56 -07:00
STDOUT.binmode(':raw')
print ("P5\n", pos[0]*2 + 3, " ", pos[1]*2 + 3, "\n255\n")
2016-12-05 23:44:36 +01:00
for y in ((pos[1] - pos[3] - 1) .. (pos[1] + pos[3] + 1)) {
2019-09-12 10:33:56 -07:00
var row = []
2016-12-05 23:44:36 +01:00
for x in ((pos[0] - pos[3] - 1) .. (pos[0] + pos[3] + 1)) {
2019-09-12 10:33:56 -07:00
var hit = 0
var hs = []
var h = hitf(pos, x, y)
2016-12-05 23:44:36 +01:00
if (!h) { hit = 0; h = [0, 0] }
elsif (!(hs = hitf(neg, x, y))) { hit = 1; hs = [0, 0] }
elsif (hs[0] > h[0]) { hit = 1 }
elsif (hs[1] > h[0]) { hit = (hs[1] > h[1] ? 0 : 2) }
2019-09-12 10:33:56 -07:00
else { hit = 1 }
var (val, v)
2016-12-05 23:44:36 +01:00
given(hit) {
when (0) { val = 0}
2019-09-12 10:33:56 -07:00
when (1) { v = Vector(x-pos[0], y-pos[1], h[0]-pos[2]) }
default { v = Vector(neg[0]-x, neg[1]-y, neg[2]-hs[1]) }
2016-12-05 23:44:36 +01:00
}
2019-09-12 10:33:56 -07:00
if (defined(v)) {
v = normalize(v)
val = int((dot(v, light)**k + amb) * 255)
val = (val > 255 ? 255 : (val < 0 ? 0 : val))
}
row.append(val)
2016-12-05 23:44:36 +01:00
}
2019-09-12 10:33:56 -07:00
print 'C*'.pack(row...)
2016-12-05 23:44:36 +01:00
}
}
2019-09-12 10:33:56 -07:00
draw(2, 0.2)