34 lines
1.2 KiB
Scala
34 lines
1.2 KiB
Scala
object Sphere extends App {
|
|
private val (shades, light) = (Seq('.', ':', '!', '*', 'o', 'e', '&', '#', '%', '@'), Array(30d, 30d, -50d))
|
|
|
|
private def drawSphere(r: Double, k: Double, ambient: Double): Unit = {
|
|
def dot(x: Array[Double], y: Array[Double]) = {
|
|
val d = x.head * y.head + x(1) * y(1) + x.last * y.last
|
|
if (d < 0) -d else 0D
|
|
}
|
|
|
|
for (i <- math.floor(-r).toInt to math.ceil(r).toInt; x = i + .5)
|
|
println(
|
|
(for (j <- math.floor(-2 * r).toInt to math.ceil(2 * r).toInt; y = j / 2.0 + .5)
|
|
yield if (x * x + y * y <= r * r) {
|
|
|
|
def intensity(vec: Array[Double]) = {
|
|
val b = math.pow(dot(light, vec), k) + ambient
|
|
if (b <= 0) shades.length - 2
|
|
else math.max((1 - b) * (shades.length - 1), 0).toInt
|
|
}
|
|
|
|
shades(intensity(normalize(Array(x, y, scala.math.sqrt(r * r - x * x - y * y)))))
|
|
} else ' ').mkString)
|
|
}
|
|
|
|
private def normalize(v: Array[Double]): Array[Double] = {
|
|
val len = math.sqrt(v.head * v.head + v(1) * v(1) + v.last * v.last)
|
|
v.map(_ / len)
|
|
}
|
|
|
|
normalize(light).copyToArray(light)
|
|
drawSphere(20, 4, .1)
|
|
drawSphere(10, 2, .4)
|
|
|
|
}
|