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) }