RosettaCodeData/Task/Draw-a-sphere/D/draw-a-sphere.d

41 lines
1.3 KiB
D
Raw Permalink Normal View History

2013-04-10 16:57:12 -07:00
import std.stdio, std.math, std.algorithm, std.numeric;
2015-02-20 00:35:01 -05:00
alias V3 = double[3];
immutable light = normalize([30.0, 30.0, -50.0]);
2013-04-10 16:57:12 -07:00
2015-02-20 00:35:01 -05:00
V3 normalize(V3 v) pure @nogc {
2013-04-10 16:57:12 -07:00
v[] /= dotProduct(v, v) ^^ 0.5;
2015-02-20 00:35:01 -05:00
return v;
2013-04-10 16:57:12 -07:00
}
2015-02-20 00:35:01 -05:00
double dot(in ref V3 x, in ref V3 y) pure nothrow @nogc {
2013-04-10 16:57:12 -07:00
immutable double d = dotProduct(x, y);
return d < 0 ? -d : 0;
}
2015-02-20 00:35:01 -05:00
void drawSphere(in double R, in double k, in double ambient) @nogc {
2013-04-10 16:57:12 -07:00
enum shades = ".:!*oe&#%@";
2015-02-20 00:35:01 -05:00
foreach (immutable i; cast(int)floor(-R) .. cast(int)ceil(R) + 1) {
2013-04-10 16:57:12 -07:00
immutable double x = i + 0.5;
2015-02-20 00:35:01 -05:00
foreach (immutable j; cast(int)floor(-2 * R) ..
cast(int)ceil(2 * R) + 1) {
2013-04-10 16:57:12 -07:00
immutable double y = j / 2. + 0.5;
if (x ^^ 2 + y ^^ 2 <= R ^^ 2) {
2015-02-20 00:35:01 -05:00
immutable vec = [x, y, (R^^2 - x^^2 - y^^2) ^^ 0.5]
.normalize;
2013-04-10 16:57:12 -07:00
immutable double b = dot(light, vec) ^^ k + ambient;
2015-02-20 00:35:01 -05:00
int intensity = cast(int)((1 - b) * (shades.length-1));
intensity = min(shades.length - 1, max(intensity, 0));
shades[intensity].putchar;
2013-04-10 16:57:12 -07:00
} else
2015-02-20 00:35:01 -05:00
' '.putchar;
2013-04-10 16:57:12 -07:00
}
2015-02-20 00:35:01 -05:00
'\n'.putchar;
2013-04-10 16:57:12 -07:00
}
}
void main() {
drawSphere(20, 4, 0.1);
drawSphere(10, 2, 0.4);
}