CDE
This commit is contained in:
parent
518da4a923
commit
764da6cbbb
6144 changed files with 83610 additions and 11 deletions
109
Task/Death-Star/D/death-star.d
Normal file
109
Task/Death-Star/D/death-star.d
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
import std.stdio, std.math, std.numeric, std.algorithm;
|
||||
|
||||
struct V3 {
|
||||
double[3] v;
|
||||
|
||||
@property V3 normalize() pure nothrow const {
|
||||
immutable double len = dotProduct(v, v).sqrt();
|
||||
//return V3(v[] / len);
|
||||
return V3([v[0] / len, v[1] / len, v[2] / len]);
|
||||
}
|
||||
|
||||
double dot(in ref V3 y) pure nothrow const {
|
||||
immutable double d = dotProduct(v, y.v);
|
||||
return d < 0 ? -d : 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const struct Sphere { double cx, cy, cz, r; }
|
||||
|
||||
void drawSphere(in double k, in double ambient, in V3 light) nothrow {
|
||||
/** Check if a ray (x,y, -inf).(x, y, inf) hits a sphere; if so,
|
||||
return the intersecting z values. z1 is closer to the eye */
|
||||
static bool hitSphere(in ref Sphere sph,
|
||||
in double x0, in double y0,
|
||||
out double z1,
|
||||
out double z2) pure nothrow {
|
||||
immutable double x = x0 - sph.cx;
|
||||
immutable double y = y0 - sph.cy;
|
||||
immutable double zsq = sph.r ^^ 2 - (x ^^ 2 + y ^^ 2);
|
||||
if (zsq < 0)
|
||||
return false;
|
||||
immutable double szsq = sqrt(zsq);
|
||||
z1 = sph.cz - szsq;
|
||||
z2 = sph.cz + szsq;
|
||||
return true;
|
||||
}
|
||||
|
||||
enum string shades = ".:!*oe&#%@";
|
||||
// positive and negative spheres
|
||||
immutable pos = Sphere(20, 20, 0, 20);
|
||||
immutable neg = Sphere(1, 1, -6, 20);
|
||||
|
||||
foreach (int i; cast(int)floor(pos.cy - pos.r) ..
|
||||
cast(int)ceil(pos.cy + pos.r) + 1) {
|
||||
immutable double y = i + 0.5;
|
||||
jloop:
|
||||
foreach (int j; cast(int)floor(pos.cx - 2 * pos.r) ..
|
||||
cast(int)ceil(pos.cx + 2 * pos.r) + 1) {
|
||||
immutable double x = (j - pos.cx) / 2.0 + 0.5 + pos.cx;
|
||||
|
||||
enum Hit { background, posSphere, negSphere }
|
||||
Hit hitResult;
|
||||
double zb1, zs2;
|
||||
{
|
||||
double zb2, zs1;
|
||||
if (!hitSphere(pos, x, y, zb1, zb2)) {
|
||||
// Ray lands in blank space, draw bg
|
||||
hitResult = Hit.background;
|
||||
} else if (!hitSphere(neg, x, y, zs1, zs2)) {
|
||||
// Ray hits pos sphere but not neg one,
|
||||
// draw pos sphere surface
|
||||
hitResult = Hit.posSphere;
|
||||
} else if (zs1 > zb1) {
|
||||
// ray hits both, but pos front surface is closer
|
||||
hitResult = Hit.posSphere;
|
||||
} else if (zs2 > zb2) {
|
||||
// pos sphere surface is inside neg sphere,
|
||||
// show bg
|
||||
hitResult = Hit.background;
|
||||
} else if (zs2 > zb1) {
|
||||
// Back surface on neg sphere is inside pos
|
||||
// sphere, the only place where neg sphere
|
||||
// surface will be shown
|
||||
hitResult = Hit.negSphere;
|
||||
} else {
|
||||
hitResult = Hit.posSphere;
|
||||
}
|
||||
}
|
||||
|
||||
V3 vec_;
|
||||
final switch (hitResult) {
|
||||
case Hit.background:
|
||||
putchar(' ');
|
||||
continue jloop;
|
||||
case Hit.posSphere:
|
||||
vec_ = V3([x - pos.cx, y - pos.cy, zb1 - pos.cz]);
|
||||
break;
|
||||
case Hit.negSphere:
|
||||
vec_ = V3([neg.cx - x, neg.cy - y, neg.cz - zs2]);
|
||||
break;
|
||||
}
|
||||
immutable V3 nvec = vec_.normalize;
|
||||
|
||||
immutable double b = light.dot(nvec) ^^ k + ambient;
|
||||
int intensity = cast(int)((1 - b) * shades.length);
|
||||
intensity = min(shades.length, max(0, intensity));
|
||||
putchar(shades[intensity]);
|
||||
}
|
||||
|
||||
putchar('\n');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void main() {
|
||||
enum light = V3([-50, 30, 50]).normalize;
|
||||
drawSphere(2, 0.5, light);
|
||||
}
|
||||
94
Task/Death-Star/DWScript/death-star.dwscript
Normal file
94
Task/Death-Star/DWScript/death-star.dwscript
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
const cShades = '.:!*oe&#%@';
|
||||
|
||||
type TVector = array [0..2] of Float;
|
||||
|
||||
var light : TVector = [-50.0, 30, 50];
|
||||
|
||||
procedure Normalize(var v : TVector);
|
||||
begin
|
||||
var len := Sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
|
||||
v[0] /= len; v[1] /= len; v[2] /= len;
|
||||
end;
|
||||
|
||||
function Dot(x, y : TVector) : Float;
|
||||
begin
|
||||
var d :=x[0]*y[0] + x[1]*y[1] + x[2]*y[2];
|
||||
if d<0 then
|
||||
Result:=-d
|
||||
else Result:=0;
|
||||
end;
|
||||
|
||||
type
|
||||
TSphere = record
|
||||
cx, cy, cz, r : Float;
|
||||
end;
|
||||
|
||||
const big : TSphere = (cx: 20; cy: 20; cz: 0; r: 20);
|
||||
const small : TSphere = (cx: 7; cy: 7; cz: -10; r: 15);
|
||||
|
||||
function HitSphere(sph : TSphere; x, y : Float; var z1, z2 : Float) : Boolean;
|
||||
begin
|
||||
x -= sph.cx;
|
||||
y -= sph.cy;
|
||||
var zsq = sph.r * sph.r - (x * x + y * y);
|
||||
if (zsq < 0) then Exit False;
|
||||
zsq := Sqrt(zsq);
|
||||
z1 := sph.cz - zsq;
|
||||
z2 := sph.cz + zsq;
|
||||
Result:=True;
|
||||
end;
|
||||
|
||||
procedure DrawSphere(k, ambient : Float);
|
||||
var
|
||||
i, j, intensity : Integer;
|
||||
b : Float;
|
||||
x, y, zb1, zb2, zs1, zs2 : Float;
|
||||
vec : TVector;
|
||||
begin
|
||||
for i:=Trunc(big.cy-big.r) to Trunc(big.cy+big.r)+1 do begin
|
||||
y := i + 0.5;
|
||||
for j := Trunc(big.cx-2*big.r) to Trunc(big.cx+2*big.r) do begin
|
||||
x := (j-big.cx)/2 + 0.5 + big.cx;
|
||||
|
||||
if not HitSphere(big, x, y, zb1, zb2) then begin
|
||||
Print(' ');
|
||||
continue;
|
||||
end;
|
||||
if not HitSphere(small, x, y, zs1, zs2) then begin
|
||||
vec[0] := x - big.cx;
|
||||
vec[1] := y - big.cy;
|
||||
vec[2] := zb1 - big.cz;
|
||||
end else begin
|
||||
if zs1 < zb1 then begin
|
||||
if zs2 > zb2 then begin
|
||||
Print(' ');
|
||||
continue;
|
||||
end;
|
||||
if zs2 > zb1 then begin
|
||||
vec[0] := small.cx - x;
|
||||
vec[1] := small.cy - y;
|
||||
vec[2] := small.cz - zs2;
|
||||
end else begin
|
||||
vec[0] := x - big.cx;
|
||||
vec[1] := y - big.cy;
|
||||
vec[2] := zb1 - big.cz;
|
||||
end;
|
||||
end else begin
|
||||
vec[0] := x - big.cx;
|
||||
vec[1] := y - big.cy;
|
||||
vec[2] := zb1 - big.cz;
|
||||
end;
|
||||
end;
|
||||
|
||||
Normalize(vec);
|
||||
b := Power(Dot(light, vec), k) + ambient;
|
||||
intensity := Round((1 - b) * Length(cShades));
|
||||
Print(cShades[ClampInt(intensity+1, 1, Length(cShades))]);
|
||||
end;
|
||||
PrintLn('');
|
||||
end;
|
||||
end;
|
||||
|
||||
Normalize(light);
|
||||
|
||||
DrawSphere(2, 0.3);
|
||||
Loading…
Add table
Add a link
Reference in a new issue