Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
7
Task/Death-Star/00-META.yaml
Normal file
7
Task/Death-Star/00-META.yaml
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
category:
|
||||
- Geometric Subtraction
|
||||
from: http://rosettacode.org/wiki/Death_Star
|
||||
note: Constructive Solid Geometry
|
||||
requires:
|
||||
- Graphics
|
||||
13
Task/Death-Star/00-TASK.txt
Normal file
13
Task/Death-Star/00-TASK.txt
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
;Task:
|
||||
Display a region that consists of a large sphere with part of a smaller sphere removed from it as a result of geometric subtraction.
|
||||
|
||||
(This will basically produce a shape like a "death star".)
|
||||
|
||||
|
||||
;Related tasks:
|
||||
* [[Draw_a_sphere|draw a sphere]]
|
||||
* [[Draw_a_cuboid|draw a cuboid]]
|
||||
* [[Draw_a_rotating_cube|draw a rotating cube]]
|
||||
* [[Write_language_name_in_3D_ASCII|write language name in 3D ASCII]]
|
||||
<br><br>
|
||||
|
||||
67
Task/Death-Star/11l/death-star.11l
Normal file
67
Task/Death-Star/11l/death-star.11l
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
T Sphere
|
||||
Float cx, cy, cz, r
|
||||
F (cx, cy, cz, r)
|
||||
.cx = cx
|
||||
.cy = cy
|
||||
.cz = cz
|
||||
.r = r
|
||||
|
||||
F dotp(v1, v2)
|
||||
V d = dot(v1, v2)
|
||||
R I d < 0 {-d} E 0.0
|
||||
|
||||
F hit_sphere(sph, x0, y0)
|
||||
V x = x0 - sph.cx
|
||||
V y = y0 - sph.cy
|
||||
V zsq = sph.r ^ 2 - (x ^ 2 + y ^ 2)
|
||||
I zsq < 0
|
||||
R (0B, 0.0, 0.0)
|
||||
V szsq = sqrt(zsq)
|
||||
R (1B, sph.cz - szsq, sph.cz + szsq)
|
||||
|
||||
F draw_sphere(k, ambient, light)
|
||||
V shades = ‘.:!*oe&#%@’
|
||||
V pos = Sphere(20.0, 20.0, 0.0, 20.0)
|
||||
V neg = Sphere(1.0, 1.0, -6.0, 20.0)
|
||||
|
||||
L(i) Int(floor(pos.cy - pos.r)) .< Int(ceil(pos.cy + pos.r) + 1)
|
||||
V y = i + 0.5
|
||||
L(j) Int(floor(pos.cx - 2 * pos.r)) .< Int(ceil(pos.cx + 2 * pos.r) + 1)
|
||||
V x = (j - pos.cx) / 2.0 + 0.5 + pos.cx
|
||||
|
||||
V (h, zb1, zb2) = hit_sphere(pos, x, y)
|
||||
Int hit_result
|
||||
Float zs2
|
||||
I !h
|
||||
hit_result = 0
|
||||
E
|
||||
(h, V zs1, zs2) = hit_sphere(neg, x, y)
|
||||
I !h
|
||||
hit_result = 1
|
||||
E I zs1 > zb1
|
||||
hit_result = 1
|
||||
E I zs2 > zb2
|
||||
hit_result = 0
|
||||
E I zs2 > zb1
|
||||
hit_result = 2
|
||||
E
|
||||
hit_result = 1
|
||||
|
||||
V vec = (0.0, 0.0, 0.0)
|
||||
I hit_result == 0
|
||||
print(‘ ’, end' ‘’)
|
||||
L.continue
|
||||
E I hit_result == 1
|
||||
vec = (x - pos.cx, y - pos.cy, zb1 - pos.cz)
|
||||
E I hit_result == 2
|
||||
vec = (neg.cx - x, neg.cy - y, neg.cz - zs2)
|
||||
vec = normalize(vec)
|
||||
|
||||
V b = dotp(light, vec) ^ k + ambient
|
||||
V intensity = Int((1 - b) * shades.len)
|
||||
intensity = min(shades.len, max(0, intensity))
|
||||
print(shades[intensity], end' ‘’)
|
||||
print()
|
||||
|
||||
V light = normalize((-50.0, 30.0, 50.0))
|
||||
draw_sphere(2, 0.5, light)
|
||||
143
Task/Death-Star/Ada/death-star.ada
Normal file
143
Task/Death-Star/Ada/death-star.ada
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
with Ada.Numerics.Elementary_Functions;
|
||||
with Ada.Numerics.Generic_Real_Arrays;
|
||||
|
||||
with SDL.Video.Windows.Makers;
|
||||
with SDL.Video.Renderers.Makers;
|
||||
with SDL.Video.Palettes;
|
||||
with SDL.Events.Events;
|
||||
|
||||
procedure Death_Star is
|
||||
|
||||
Width : constant := 400;
|
||||
Height : constant := 400;
|
||||
|
||||
package Float_Arrays is
|
||||
new Ada.Numerics.Generic_Real_Arrays (Float);
|
||||
use Ada.Numerics.Elementary_Functions;
|
||||
use Float_Arrays;
|
||||
|
||||
Window : SDL.Video.Windows.Window;
|
||||
Renderer : SDL.Video.Renderers.Renderer;
|
||||
|
||||
subtype Vector_3 is Real_Vector (1 .. 3);
|
||||
|
||||
type Sphere_Type is record
|
||||
Cx, Cy, Cz : Integer;
|
||||
R : Integer;
|
||||
end record;
|
||||
|
||||
function Normalize (V : Vector_3) return Vector_3 is
|
||||
(V / Sqrt (V * V));
|
||||
|
||||
procedure Hit (S : Sphere_Type;
|
||||
X, Y : Integer;
|
||||
Z1, Z2 : out Float;
|
||||
Is_Hit : out Boolean)
|
||||
is
|
||||
NX : constant Integer := X - S.Cx;
|
||||
NY : constant Integer := Y - S.Cy;
|
||||
Zsq : constant Integer := S.R * S.R - (NX * NX + NY * NY);
|
||||
Zsqrt : Float;
|
||||
begin
|
||||
if Zsq >= 0 then
|
||||
Zsqrt := Sqrt (Float (Zsq));
|
||||
Z1 := Float (S.Cz) - Zsqrt;
|
||||
Z2 := Float (S.Cz) + Zsqrt;
|
||||
Is_Hit := True;
|
||||
return;
|
||||
end if;
|
||||
Z1 := 0.0;
|
||||
Z2 := 0.0;
|
||||
Is_Hit := False;
|
||||
end Hit;
|
||||
|
||||
procedure Draw_Death_Star (Pos, Neg : Sphere_Type;
|
||||
K, Amb : Float;
|
||||
Dir : Vector_3)
|
||||
is
|
||||
Vec : Vector_3;
|
||||
ZB1, ZB2 : Float;
|
||||
ZS1, ZS2 : Float;
|
||||
Is_Hit : Boolean;
|
||||
S : Float;
|
||||
Lum : Integer;
|
||||
begin
|
||||
for Y in Pos.Cy - Pos.R .. Pos.Cy + Pos.R loop
|
||||
for X in Pos.Cx - Pos.R .. Pos.Cx + Pos.R loop
|
||||
Hit (Pos, X, Y, ZB1, ZB2, Is_Hit);
|
||||
if not Is_Hit then
|
||||
goto Continue;
|
||||
end if;
|
||||
Hit (Neg, X, Y, ZS1, ZS2, Is_Hit);
|
||||
if Is_Hit then
|
||||
if ZS1 > ZB1 then
|
||||
Is_Hit := False;
|
||||
elsif ZS2 > ZB2 then
|
||||
goto Continue;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
if Is_Hit then
|
||||
Vec := (Float (Neg.Cx - X),
|
||||
Float (Neg.Cy - Y),
|
||||
Float (Neg.Cz) - ZS2);
|
||||
else
|
||||
Vec := (Float (X - Pos.Cx),
|
||||
Float (Y - Pos.Cy),
|
||||
ZB1 - Float (Pos.Cz));
|
||||
end if;
|
||||
S := Float'Max (0.0, Dir * Normalize (Vec));
|
||||
|
||||
Lum := Integer (255.0 * (S ** K + Amb) / (1.0 + Amb));
|
||||
Lum := Integer'Max (0, Lum);
|
||||
Lum := Integer'Min (Lum, 255);
|
||||
|
||||
Renderer.Set_Draw_Colour ((SDL.Video.Palettes.Colour_Component (Lum),
|
||||
SDL.Video.Palettes.Colour_Component (Lum),
|
||||
SDL.Video.Palettes.Colour_Component (Lum),
|
||||
255));
|
||||
Renderer.Draw (Point => (SDL.C.int (X + Width / 2),
|
||||
SDL.C.int (Y + Height / 2)));
|
||||
<<Continue>>
|
||||
end loop;
|
||||
end loop;
|
||||
end Draw_Death_Star;
|
||||
|
||||
procedure Wait is
|
||||
use type SDL.Events.Event_Types;
|
||||
Event : SDL.Events.Events.Events;
|
||||
begin
|
||||
loop
|
||||
while SDL.Events.Events.Poll (Event) loop
|
||||
if Event.Common.Event_Type = SDL.Events.Quit then
|
||||
return;
|
||||
end if;
|
||||
end loop;
|
||||
delay 0.100;
|
||||
end loop;
|
||||
end Wait;
|
||||
|
||||
Direction : constant Vector_3 := Normalize ((20.0, -40.0, -10.0));
|
||||
Positive : constant Sphere_Type := (0, 0, 0, 120);
|
||||
Negative : constant Sphere_Type := (-90, -90, -30, 100);
|
||||
begin
|
||||
if not SDL.Initialise (Flags => SDL.Enable_Screen) then
|
||||
return;
|
||||
end if;
|
||||
|
||||
SDL.Video.Windows.Makers.Create (Win => Window,
|
||||
Title => "Death star",
|
||||
Position => SDL.Natural_Coordinates'(X => 10, Y => 10),
|
||||
Size => SDL.Positive_Sizes'(Width, Height),
|
||||
Flags => 0);
|
||||
SDL.Video.Renderers.Makers.Create (Renderer, Window.Get_Surface);
|
||||
Renderer.Set_Draw_Colour ((0, 0, 0, 255));
|
||||
Renderer.Fill (Rectangle => (0, 0, Width, Height));
|
||||
|
||||
Draw_Death_Star (Positive, Negative, 1.5, 0.2, Direction);
|
||||
Window.Update_Surface;
|
||||
|
||||
Wait;
|
||||
Window.Finalize;
|
||||
SDL.Finalise;
|
||||
end Death_Star;
|
||||
80
Task/Death-Star/AutoHotkey/death-star.ahk
Normal file
80
Task/Death-Star/AutoHotkey/death-star.ahk
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
#NoEnv
|
||||
SetBatchLines, -1
|
||||
#SingleInstance, Force
|
||||
|
||||
; Uncomment if Gdip.ahk is not in your standard library
|
||||
#Include, Gdip.ahk
|
||||
|
||||
; Settings
|
||||
X := 200, Y := 200, Width := 200, Height := 200 ; Location and size of sphere
|
||||
rotation := 60 ; degrees
|
||||
ARGB := 0xFFFF0000 ; Color=Solid Red
|
||||
|
||||
If !pToken := Gdip_Startup() ; Start gdi+
|
||||
{
|
||||
MsgBox, 48, gdiplus error!, Gdiplus failed to start. Please ensure you have gdiplus on your system
|
||||
ExitApp
|
||||
}
|
||||
OnExit, Exit
|
||||
|
||||
Gui, -Caption +E0x80000 +LastFound +AlwaysOnTop +ToolWindow +OwnDialogs ; Create GUI
|
||||
Gui, Show, NA ; Show GUI
|
||||
hwnd1 := WinExist() ; Get a handle to this window we have created in order to update it later
|
||||
hbm := CreateDIBSection(A_ScreenWidth, A_ScreenHeight) ; Create a gdi bitmap drawing area
|
||||
hdc := CreateCompatibleDC() ; Get a device context compatible with the screen
|
||||
obm := SelectObject(hdc, hbm) ; Select the bitmap into the device context
|
||||
pGraphics := Gdip_GraphicsFromHDC(hdc) ; Get a pointer to the graphics of the bitmap, for use with drawing functions
|
||||
Gdip_SetSmoothingMode(pGraphics, 4) ; Set the smoothing mode to antialias = 4 to make shapes appear smother
|
||||
|
||||
Gdip_TranslateWorldTransform(pGraphics, X, Y)
|
||||
Gdip_RotateWorldTransform(pGraphics, rotation)
|
||||
|
||||
; Base ellipse
|
||||
pBrush := Gdip_CreateLineBrushFromRect(0, 0, Width, Height, ARGB, 0xFF000000)
|
||||
Gdip_FillEllipse(pGraphics, pBrush, 0, 0, Width, Height)
|
||||
|
||||
; First highlight ellipse
|
||||
pBrush := Gdip_CreateLineBrushFromRect(Width*0.1, Height*0.01, Width*0.8, Height*0.6, 0x33FFFFFF, 0x00FFFFFF)
|
||||
Gdip_FillEllipse(pGraphics, pBrush, Width*0.1, Height*0.01, Width*0.8, Height*0.6)
|
||||
|
||||
; Second highlight ellipse
|
||||
pBrush := Gdip_CreateLineBrushFromRect(Width*0.3, Height*0.02, Width*0.3, Height*0.2, 0xBBFFFFFF, 0x00FFFFFF)
|
||||
Gdip_FillEllipse(pGraphics, pBrush, Width*0.3, Height*0.02, Width*0.3, Height*0.2)
|
||||
|
||||
|
||||
; Reset variables for smaller subtracted sphere
|
||||
X-=150
|
||||
Y-=10
|
||||
Width*=0.5
|
||||
Height*=0.4
|
||||
rotation-=180
|
||||
|
||||
Gdip_TranslateWorldTransform(pGraphics, X, Y)
|
||||
Gdip_RotateWorldTransform(pGraphics, rotation)
|
||||
|
||||
; Base ellipse
|
||||
pBrush := Gdip_CreateLineBrushFromRect(0, 0, Width, Height, ARGB, 0xFF000000)
|
||||
Gdip_FillEllipse(pGraphics, pBrush, 0, 0, Width, Height)
|
||||
|
||||
; First highlight ellipse
|
||||
pBrush := Gdip_CreateLineBrushFromRect(Width*0.1, Height*0.01, Width*0.8, Height*0.6, 0x33FFFFFF, 0x00FFFFFF)
|
||||
Gdip_FillEllipse(pGraphics, pBrush, Width*0.1, Height*0.01, Width*0.8, Height*0.6)
|
||||
|
||||
; Second highlight ellipse
|
||||
pBrush := Gdip_CreateLineBrushFromRect(Width*0.3, Height*0.02, Width*0.3, Height*0.2, 0xBBFFFFFF, 0x00FFFFFF)
|
||||
Gdip_FillEllipse(pGraphics, pBrush, Width*0.3, Height*0.02, Width*0.3, Height*0.2)
|
||||
|
||||
|
||||
UpdateLayeredWindow(hwnd1, hdc, 0, 0, A_ScreenWidth, A_ScreenHeight)
|
||||
SelectObject(hdc, obm) ; Select the object back into the hdc
|
||||
Gdip_DeletePath(Path)
|
||||
Gdip_DeleteBrush(pBrush)
|
||||
DeleteObject(hbm) ; Now the bitmap may be deleted
|
||||
DeleteDC(hdc) ; Also the device context related to the bitmap may be deleted
|
||||
Gdip_DeleteGraphics(G) ; The graphics may now be deleted
|
||||
Return
|
||||
|
||||
Exit:
|
||||
; gdi+ may now be shutdown on exiting the program
|
||||
Gdip_Shutdown(pToken)
|
||||
ExitApp
|
||||
26
Task/Death-Star/Brlcad/death-star.brlcad
Normal file
26
Task/Death-Star/Brlcad/death-star.brlcad
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
# We need a database to hold the objects
|
||||
opendb deathstar.g y
|
||||
|
||||
# We will be measuring in kilometers
|
||||
units km
|
||||
|
||||
# Create a sphere of radius 60km centred at the origin
|
||||
in sph1.s sph 0 0 0 60
|
||||
|
||||
# We will be subtracting an overlapping sphere with a radius of 40km
|
||||
# The resultant hole will be smaller than this, because we only
|
||||
# only catch the edge
|
||||
in sph2.s sph 0 90 0 40
|
||||
|
||||
# Create a region named deathstar.r which consists of big minus small sphere
|
||||
r deathstar.r u sph1.s - sph2.s
|
||||
|
||||
# We will use a plastic material texture with rgb colour 224,224,224
|
||||
# with specular lighting value of 0.1 and no inheritance
|
||||
mater deathstar.r "plastic sp=0.1" 224 224 224 0
|
||||
|
||||
# Clear the wireframe display and draw the deathstar
|
||||
B deathstar.r
|
||||
|
||||
# We now trigger the raytracer to see our finished product
|
||||
rt
|
||||
112
Task/Death-Star/C/death-star.c
Normal file
112
Task/Death-Star/C/death-star.c
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <unistd.h>
|
||||
|
||||
const char *shades = ".:!*oe&#%@";
|
||||
|
||||
double light[3] = { -50, 0, 50 };
|
||||
void normalize(double * v)
|
||||
{
|
||||
double len = sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
|
||||
v[0] /= len; v[1] /= len; v[2] /= len;
|
||||
}
|
||||
|
||||
double dot(double *x, double *y)
|
||||
{
|
||||
double d = x[0]*y[0] + x[1]*y[1] + x[2]*y[2];
|
||||
return d < 0 ? -d : 0;
|
||||
}
|
||||
|
||||
typedef struct { double cx, cy, cz, r; } sphere_t;
|
||||
|
||||
/* positive shpere and negative sphere */
|
||||
sphere_t pos = { 20, 20, 0, 20 }, neg = { 1, 1, -6, 20 };
|
||||
|
||||
/* 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 */
|
||||
int hit_sphere(sphere_t *sph, double x, double y, double *z1, double *z2)
|
||||
{
|
||||
double zsq;
|
||||
x -= sph->cx;
|
||||
y -= sph->cy;
|
||||
zsq = sph->r * sph->r - (x * x + y * y);
|
||||
if (zsq < 0) return 0;
|
||||
zsq = sqrt(zsq);
|
||||
*z1 = sph->cz - zsq;
|
||||
*z2 = sph->cz + zsq;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void draw_sphere(double k, double ambient)
|
||||
{
|
||||
int i, j, intensity, hit_result;
|
||||
double b;
|
||||
double vec[3], x, y, zb1, zb2, zs1, zs2;
|
||||
for (i = floor(pos.cy - pos.r); i <= ceil(pos.cy + pos.r); i++) {
|
||||
y = i + .5;
|
||||
for (j = floor(pos.cx - 2 * pos.r); j <= ceil(pos.cx + 2 * pos.r); j++) {
|
||||
x = (j - pos.cx) / 2. + .5 + pos.cx;
|
||||
|
||||
/* ray lands in blank space, draw bg */
|
||||
if (!hit_sphere(&pos, x, y, &zb1, &zb2))
|
||||
hit_result = 0;
|
||||
|
||||
/* ray hits pos sphere but not neg, draw pos sphere surface */
|
||||
else if (!hit_sphere(&neg, x, y, &zs1, &zs2))
|
||||
hit_result = 1;
|
||||
|
||||
/* ray hits both, but pos front surface is closer */
|
||||
else if (zs1 > zb1) hit_result = 1;
|
||||
|
||||
/* pos sphere surface is inside neg sphere, show bg */
|
||||
else if (zs2 > zb2) hit_result = 0;
|
||||
|
||||
/* back surface on neg sphere is inside pos sphere,
|
||||
the only place where neg sphere surface will be shown */
|
||||
else if (zs2 > zb1) hit_result = 2;
|
||||
else hit_result = 1;
|
||||
|
||||
switch(hit_result) {
|
||||
case 0:
|
||||
putchar('+');
|
||||
continue;
|
||||
case 1:
|
||||
vec[0] = x - pos.cx;
|
||||
vec[1] = y - pos.cy;
|
||||
vec[2] = zb1 - pos.cz;
|
||||
break;
|
||||
default:
|
||||
vec[0] = neg.cx - x;
|
||||
vec[1] = neg.cy - y;
|
||||
vec[2] = neg.cz - zs2;
|
||||
}
|
||||
|
||||
normalize(vec);
|
||||
b = pow(dot(light, vec), k) + ambient;
|
||||
intensity = (1 - b) * (sizeof(shades) - 1);
|
||||
if (intensity < 0) intensity = 0;
|
||||
if (intensity >= sizeof(shades) - 1)
|
||||
intensity = sizeof(shades) - 2;
|
||||
putchar(shades[intensity]);
|
||||
}
|
||||
putchar('\n');
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
double ang = 0;
|
||||
|
||||
while (1) {
|
||||
printf("\033[H");
|
||||
light[1] = cos(ang * 2);
|
||||
light[2] = cos(ang);
|
||||
light[0] = sin(ang);
|
||||
normalize(light);
|
||||
ang += .05;
|
||||
|
||||
draw_sphere(2, .3);
|
||||
usleep(100000);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
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 @nogc {
|
||||
immutable double len = dotProduct(v, v).sqrt;
|
||||
return [v[0] / len, v[1] / len, v[2] / len].V3;
|
||||
}
|
||||
|
||||
double dot(in ref V3 y) pure nothrow const @nogc {
|
||||
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 @nogc {
|
||||
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 = zsq.sqrt;
|
||||
z1 = sph.cz - szsq;
|
||||
z2 = sph.cz + szsq;
|
||||
return true;
|
||||
}
|
||||
|
||||
immutable shades = ".:!*oe&#%@";
|
||||
// Positive and negative spheres.
|
||||
immutable pos = Sphere(20, 20, 0, 20);
|
||||
immutable neg = Sphere(1, 1, -6, 20);
|
||||
|
||||
foreach (immutable 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 }
|
||||
|
||||
double zb1, zs2;
|
||||
immutable Hit hitResult = {
|
||||
double zb2, zs1;
|
||||
|
||||
if (!hitSphere(pos, x, y, zb1, zb2)) {
|
||||
// Ray lands in blank space, draw bg.
|
||||
return Hit.background;
|
||||
} else if (!hitSphere(neg, x, y, zs1, zs2)) {
|
||||
// Ray hits pos sphere but not neg one,
|
||||
// draw pos sphere surface.
|
||||
return Hit.posSphere;
|
||||
} else if (zs1 > zb1) {
|
||||
// ray hits both, but pos front surface is closer.
|
||||
return Hit.posSphere;
|
||||
} else if (zs2 > zb2) {
|
||||
// pos sphere surface is inside neg sphere,
|
||||
// show bg.
|
||||
return 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.
|
||||
return Hit.negSphere;
|
||||
} else {
|
||||
return Hit.posSphere;
|
||||
}
|
||||
}();
|
||||
|
||||
V3 vec_;
|
||||
final switch (hitResult) {
|
||||
case Hit.background:
|
||||
' '.putchar;
|
||||
continue JLOOP;
|
||||
case Hit.posSphere:
|
||||
vec_ = [x - pos.cx, y - pos.cy, zb1 - pos.cz].V3;
|
||||
break;
|
||||
case Hit.negSphere:
|
||||
vec_ = [neg.cx - x, neg.cy - y, neg.cz - zs2].V3;
|
||||
break;
|
||||
}
|
||||
immutable nvec = vec_.normalize;
|
||||
|
||||
immutable double b = light.dot(nvec) ^^ k + ambient;
|
||||
immutable intensity = cast(int)((1 - b) * shades.length);
|
||||
immutable normInt = min(shades.length, max(0, intensity));
|
||||
shades[normInt].putchar;
|
||||
}
|
||||
|
||||
'\n'.putchar;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void main() {
|
||||
immutable light = [-50, 30, 50].V3.normalize;
|
||||
drawSphere(2, 0.5, light);
|
||||
}
|
||||
94
Task/Death-Star/DWScript/death-star.dw
Normal file
94
Task/Death-Star/DWScript/death-star.dw
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);
|
||||
154
Task/Death-Star/Delphi/death-star.delphi
Normal file
154
Task/Death-Star/Delphi/death-star.delphi
Normal file
|
|
@ -0,0 +1,154 @@
|
|||
program Death_Star;
|
||||
|
||||
{$APPTYPE CONSOLE}
|
||||
|
||||
uses
|
||||
Winapi.Windows,
|
||||
System.SysUtils,
|
||||
system.Math,
|
||||
Vcl.Graphics,
|
||||
Vcl.Imaging.pngimage;
|
||||
|
||||
type
|
||||
TVector = array of double;
|
||||
|
||||
var
|
||||
light: TVector = [20, -40, -10];
|
||||
|
||||
function ClampInt(value, amin, amax: Integer): Integer;
|
||||
begin
|
||||
Result := Max(amin, Min(amax, value))
|
||||
end;
|
||||
|
||||
procedure Normalize(var v: TVector);
|
||||
begin
|
||||
var len := Sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
|
||||
v[0] := v[0] / len;
|
||||
v[1] := v[1] / len;
|
||||
v[2] := v[2] / len;
|
||||
end;
|
||||
|
||||
function Dot(x, y: TVector): Double;
|
||||
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: Double;
|
||||
end;
|
||||
|
||||
const
|
||||
pos: TSphere = (
|
||||
cx: 0;
|
||||
cy: 0;
|
||||
cz: 0;
|
||||
r: 120
|
||||
);
|
||||
|
||||
const
|
||||
neg: TSphere = (
|
||||
cx: -90;
|
||||
cy: -90;
|
||||
cz: -30;
|
||||
r: 80
|
||||
);
|
||||
|
||||
function HitSphere(sph: TSphere; x, y: double; var z1, z2: Double): Boolean;
|
||||
begin
|
||||
x := x - sph.cx;
|
||||
y := 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;
|
||||
|
||||
function DeathStar(pos, neg: TSphere; k, amb: Double; light: TVector): TBitmap;
|
||||
var
|
||||
w, h, yMax, xMax, s: double;
|
||||
zp1, zp2, zn1, zn2, b: Double;
|
||||
x, y: Integer;
|
||||
hit: Boolean;
|
||||
vec: TVector;
|
||||
intensity: Byte;
|
||||
ox, oy: Integer;
|
||||
begin
|
||||
w := pos.r * 4;
|
||||
h := pos.r * 3;
|
||||
ox := -trunc(pos.cx - w / 2);
|
||||
oy := -trunc(pos.cy - h / 2);
|
||||
|
||||
vec := [0, 0, 0];
|
||||
Result := TBitmap.Create;
|
||||
Result.SetSize(trunc(w), trunc(h));
|
||||
|
||||
yMax := pos.cy + pos.r;
|
||||
for y := Trunc(pos.cy - pos.r) to Trunc(yMax) do
|
||||
begin
|
||||
xMax := pos.cx + pos.r;
|
||||
for x := trunc(pos.cy - pos.r) to trunc(xMax) do
|
||||
begin
|
||||
hit := HitSphere(pos, x, y, zp1, zp2);
|
||||
if not hit then
|
||||
continue;
|
||||
|
||||
hit := HitSphere(neg, x, y, zn1, zn2);
|
||||
|
||||
if hit then
|
||||
begin
|
||||
if zn1 > zp1 then
|
||||
hit := false
|
||||
else if zn2 > zp2 then
|
||||
continue;
|
||||
end;
|
||||
|
||||
if hit then
|
||||
begin
|
||||
vec[0] := neg.cx - x;
|
||||
vec[1] := neg.cy - y;
|
||||
vec[2] := neg.cz - zn2;
|
||||
end
|
||||
else
|
||||
begin
|
||||
vec[0] := x - pos.cx;
|
||||
vec[1] := y - pos.cy;
|
||||
vec[2] := zp1 - pos.cz;
|
||||
end;
|
||||
|
||||
Normalize(vec);
|
||||
|
||||
s := max(0, dot(light, vec));
|
||||
|
||||
b := Power(s, k) + amb;
|
||||
|
||||
intensity := ClampInt(round(255 * b / (1 + amb)), 0, 254);
|
||||
|
||||
Result.Canvas.Pixels[x + ox, y + oy] := rgb(intensity, intensity, intensity);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
var
|
||||
bmp: TBitmap;
|
||||
|
||||
begin
|
||||
Normalize(light);
|
||||
bmp := DeathStar(pos, neg, 1.2, 0.3, light);
|
||||
|
||||
with TPngImage.Create do
|
||||
begin
|
||||
Assign(bmp);
|
||||
TransparentColor := clwhite;
|
||||
SaveToFile('out.png');
|
||||
bmp.Free;
|
||||
Free;
|
||||
end;
|
||||
end.
|
||||
17
Task/Death-Star/Frink/death-star.frink
Normal file
17
Task/Death-Star/Frink/death-star.frink
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
res = 254 / in
|
||||
v = callJava["frink.graphics.VoxelArray", "makeSphere", [1/2 inch res]]
|
||||
|
||||
dish = callJava["frink.graphics.VoxelArray", "makeSphere", [1/2 inch res]]
|
||||
dish.translate[round[.45 inch res], round[.45 inch res], round[.45 inch res]]
|
||||
v.remove[dish]
|
||||
|
||||
v.projectX[undef].show["X"]
|
||||
v.projectY[undef].show["Y"]
|
||||
v.projectZ[undef].show["Z"]
|
||||
|
||||
filename = "DeathStar.stl"
|
||||
print["Writing $filename..."]
|
||||
w = new Writer[filename]
|
||||
w.println[v.toSTLFormat["DeathStar", 1/(res mm)]]
|
||||
w.close[]
|
||||
println["done."]
|
||||
103
Task/Death-Star/Go/death-star.go
Normal file
103
Task/Death-Star/Go/death-star.go
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"image"
|
||||
"image/color"
|
||||
"image/png"
|
||||
"math"
|
||||
"os"
|
||||
)
|
||||
|
||||
type vector [3]float64
|
||||
|
||||
func (v *vector) normalize() {
|
||||
invLen := 1 / math.Sqrt(dot(v, v))
|
||||
v[0] *= invLen
|
||||
v[1] *= invLen
|
||||
v[2] *= invLen
|
||||
}
|
||||
|
||||
func dot(x, y *vector) float64 {
|
||||
return x[0]*y[0] + x[1]*y[1] + x[2]*y[2]
|
||||
}
|
||||
|
||||
type sphere struct {
|
||||
cx, cy, cz int
|
||||
r int
|
||||
}
|
||||
|
||||
func (s *sphere) hit(x, y int) (z1, z2 float64, hit bool) {
|
||||
x -= s.cx
|
||||
y -= s.cy
|
||||
if zsq := s.r*s.r - (x*x + y*y); zsq >= 0 {
|
||||
zsqrt := math.Sqrt(float64(zsq))
|
||||
return float64(s.cz) - zsqrt, float64(s.cz) + zsqrt, true
|
||||
}
|
||||
return 0, 0, false
|
||||
}
|
||||
|
||||
func deathStar(pos, neg *sphere, k, amb float64, dir *vector) *image.Gray {
|
||||
w, h := pos.r*4, pos.r*3
|
||||
bounds := image.Rect(pos.cx-w/2, pos.cy-h/2, pos.cx+w/2, pos.cy+h/2)
|
||||
img := image.NewGray(bounds)
|
||||
vec := new(vector)
|
||||
for y, yMax := pos.cy-pos.r, pos.cy+pos.r; y <= yMax; y++ {
|
||||
for x, xMax := pos.cx-pos.r, pos.cx+pos.r; x <= xMax; x++ {
|
||||
zb1, zb2, hit := pos.hit(x, y)
|
||||
if !hit {
|
||||
continue
|
||||
}
|
||||
zs1, zs2, hit := neg.hit(x, y)
|
||||
if hit {
|
||||
if zs1 > zb1 {
|
||||
hit = false
|
||||
} else if zs2 > zb2 {
|
||||
continue
|
||||
}
|
||||
}
|
||||
if hit {
|
||||
vec[0] = float64(neg.cx - x)
|
||||
vec[1] = float64(neg.cy - y)
|
||||
vec[2] = float64(neg.cz) - zs2
|
||||
} else {
|
||||
vec[0] = float64(x - pos.cx)
|
||||
vec[1] = float64(y - pos.cy)
|
||||
vec[2] = zb1 - float64(pos.cz)
|
||||
}
|
||||
vec.normalize()
|
||||
s := dot(dir, vec)
|
||||
if s < 0 {
|
||||
s = 0
|
||||
}
|
||||
lum := 255 * (math.Pow(s, k) + amb) / (1 + amb)
|
||||
if lum < 0 {
|
||||
lum = 0
|
||||
} else if lum > 255 {
|
||||
lum = 255
|
||||
}
|
||||
img.SetGray(x, y, color.Gray{uint8(lum)})
|
||||
}
|
||||
}
|
||||
return img
|
||||
}
|
||||
|
||||
func main() {
|
||||
dir := &vector{20, -40, -10}
|
||||
dir.normalize()
|
||||
pos := &sphere{0, 0, 0, 120}
|
||||
neg := &sphere{-90, -90, -30, 100}
|
||||
|
||||
img := deathStar(pos, neg, 1.5, .2, dir)
|
||||
f, err := os.Create("dstar.png")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
if err = png.Encode(f, img); err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
if err = f.Close(); err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
}
|
||||
23
Task/Death-Star/Haskell/death-star.hs
Normal file
23
Task/Death-Star/Haskell/death-star.hs
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
import Data.List (genericLength)
|
||||
|
||||
shades = ".:!*oe%#&@"
|
||||
n = genericLength shades
|
||||
dot a b = sum $ zipWith (*) a b
|
||||
normalize x = (/ sqrt (x `dot` x)) <$> x
|
||||
|
||||
deathStar r k amb = unlines $
|
||||
[ [ if x*x + y*y <= r*r
|
||||
then let vec = normalize $ normal x y
|
||||
b = (light `dot` vec) ** k + amb
|
||||
intensity = (1 - b)*(n - 1)
|
||||
in shades !! round ((0 `max` intensity) `min` n)
|
||||
else ' '
|
||||
| y <- map (/2.12) [- 2*r - 0.5 .. 2*r + 0.5] ]
|
||||
| x <- [ - r - 0.5 .. r + 0.5] ]
|
||||
where
|
||||
light = normalize [-30,-30,-50]
|
||||
normal x y
|
||||
| (x+r)**2 + (y+r)**2 <= r**2 = [x+r, y+r, sph2 x y]
|
||||
| otherwise = [x, y, sph1 x y]
|
||||
sph1 x y = sqrt (r*r - x*x - y*y)
|
||||
sph2 x y = r - sqrt (r*r - (x+r)**2 - (y+r)**2)
|
||||
40
Task/Death-Star/J/death-star.j
Normal file
40
Task/Death-Star/J/death-star.j
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
load'graphics/viewmat'
|
||||
mag =: +/&.:*:"1
|
||||
norm=: %"1 0 mag
|
||||
dot =: +/@:*"1
|
||||
|
||||
NB. (pos;posr;neg;negr) getvec (x,y)
|
||||
getvec =: 4 :0 "1
|
||||
pt =. y
|
||||
'pos posr neg negr' =. x
|
||||
if. (dot~ pt-}:pos) > *:posr do.
|
||||
0 0 0
|
||||
else.
|
||||
zb =. ({:pos) (-,+) posr -&.:*: pt mag@:- }:pos
|
||||
if. (dot~ pt-}:neg) > *:negr do.
|
||||
(pt,{:zb) - pos
|
||||
else.
|
||||
zs =. ({:neg) (-,+) negr -&.:*: pt mag@:- }:neg
|
||||
if. zs >&{. zb do. (pt,{:zb) - pos
|
||||
elseif. zs >&{: zb do. 0 0 0
|
||||
elseif. ({.zs) < ({:zb) do. neg - (pt,{.zs)
|
||||
elseif. do. (pt,{.zb) - pos end.
|
||||
end.
|
||||
end.
|
||||
)
|
||||
|
||||
|
||||
NB. (k;ambient;light) draw_sphere (pos;posr;neg;negr)
|
||||
draw_sphere =: 4 :0
|
||||
'pos posr neg negr' =. y
|
||||
'k ambient light' =. x
|
||||
vec=. norm y getvec ,"0// (2{.pos) +/ i: 200 j.~ 0.5+posr
|
||||
|
||||
b=. (mag vec) * ambient + k * 0>. light dot vec
|
||||
)
|
||||
|
||||
togray =: 256#. 255 255 255 <.@*"1 0 (%>./@,)
|
||||
|
||||
env=.(2; 0.5; (norm _50 30 50))
|
||||
sph=. 20 20 0; 20; 1 1 _6; 20
|
||||
'rgb' viewmat togray env draw_sphere sph
|
||||
214
Task/Death-Star/Java/death-star.java
Normal file
214
Task/Death-Star/Java/death-star.java
Normal file
|
|
@ -0,0 +1,214 @@
|
|||
import javafx.application.Application;
|
||||
import javafx.event.EventHandler;
|
||||
import javafx.geometry.Point3D;
|
||||
import javafx.scene.Group;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.input.KeyCode;
|
||||
import javafx.scene.input.KeyEvent;
|
||||
import javafx.scene.shape.MeshView;
|
||||
import javafx.scene.shape.TriangleMesh;
|
||||
import javafx.scene.transform.Rotate;
|
||||
import javafx.stage.Stage;
|
||||
public class DeathStar extends Application {
|
||||
|
||||
private static final int DIVISION = 200;// the bigger the higher resolution
|
||||
float radius = 300;// radius of the sphere
|
||||
|
||||
@Override
|
||||
public void start(Stage primaryStage) throws Exception {
|
||||
Point3D otherSphere = new Point3D(-radius, 0, -radius * 1.5);
|
||||
final TriangleMesh triangleMesh = createMesh(DIVISION, radius, otherSphere);
|
||||
MeshView a = new MeshView(triangleMesh);
|
||||
|
||||
a.setTranslateY(radius);
|
||||
a.setTranslateX(radius);
|
||||
a.setRotationAxis(Rotate.Y_AXIS);
|
||||
Scene scene = new Scene(new Group(a));
|
||||
// uncomment if you want to move the other sphere
|
||||
|
||||
// scene.setOnKeyPressed(new EventHandler<KeyEvent>() {
|
||||
// Point3D sphere = otherSphere;
|
||||
//
|
||||
// @Override
|
||||
// public void handle(KeyEvent e) {
|
||||
// KeyCode code = e.getCode();
|
||||
// switch (code) {
|
||||
// case UP:
|
||||
// sphere = sphere.add(0, -10, 0);
|
||||
// break;
|
||||
// case DOWN:
|
||||
// sphere = sphere.add(0, 10, 0);
|
||||
// break;
|
||||
// case LEFT:
|
||||
// sphere = sphere.add(-10, 0, 0);
|
||||
// break;
|
||||
// case RIGHT:
|
||||
// sphere = sphere.add(10, 0, 0);
|
||||
// break;
|
||||
// case W:
|
||||
// sphere = sphere.add(0, 0, 10);
|
||||
// break;
|
||||
// case S:
|
||||
// sphere = sphere.add(0, 0, -10);
|
||||
// break;
|
||||
// default:
|
||||
// return;
|
||||
// }
|
||||
// a.setMesh(createMesh(DIVISION, radius, sphere));
|
||||
//
|
||||
// }
|
||||
// });
|
||||
|
||||
primaryStage.setScene(scene);
|
||||
primaryStage.show();
|
||||
}
|
||||
|
||||
static TriangleMesh createMesh(final int division, final float radius, final Point3D centerOtherSphere) {
|
||||
Rotate rotate = new Rotate(180, centerOtherSphere);
|
||||
final int div2 = division / 2;
|
||||
|
||||
final int nPoints = division * (div2 - 1) + 2;
|
||||
final int nTPoints = (division + 1) * (div2 - 1) + division * 2;
|
||||
final int nFaces = division * (div2 - 2) * 2 + division * 2;
|
||||
|
||||
final float rDiv = 1.f / division;
|
||||
|
||||
float points[] = new float[nPoints * 3];
|
||||
float tPoints[] = new float[nTPoints * 2];
|
||||
int faces[] = new int[nFaces * 6];
|
||||
|
||||
int pPos = 0, tPos = 0;
|
||||
|
||||
for (int y = 0; y < div2 - 1; ++y) {
|
||||
float va = rDiv * (y + 1 - div2 / 2) * 2 * (float) Math.PI;
|
||||
float sin_va = (float) Math.sin(va);
|
||||
float cos_va = (float) Math.cos(va);
|
||||
|
||||
float ty = 0.5f + sin_va * 0.5f;
|
||||
for (int i = 0; i < division; ++i) {
|
||||
double a = rDiv * i * 2 * (float) Math.PI;
|
||||
float hSin = (float) Math.sin(a);
|
||||
float hCos = (float) Math.cos(a);
|
||||
points[pPos + 0] = hSin * cos_va * radius;
|
||||
points[pPos + 2] = hCos * cos_va * radius;
|
||||
points[pPos + 1] = sin_va * radius;
|
||||
|
||||
final Point3D point3D = new Point3D(points[pPos + 0], points[pPos + 1], points[pPos + 2]);
|
||||
double distance = centerOtherSphere.distance(point3D);
|
||||
if (distance <= radius) {
|
||||
Point3D subtract = centerOtherSphere.subtract(point3D);
|
||||
Point3D transform = rotate.transform(subtract);
|
||||
points[pPos + 0] = (float) transform.getX();
|
||||
points[pPos + 1] = (float) transform.getY();
|
||||
points[pPos + 2] = (float) transform.getZ();
|
||||
|
||||
}
|
||||
tPoints[tPos + 0] = 1 - rDiv * i;
|
||||
tPoints[tPos + 1] = ty;
|
||||
pPos += 3;
|
||||
tPos += 2;
|
||||
}
|
||||
tPoints[tPos + 0] = 0;
|
||||
tPoints[tPos + 1] = ty;
|
||||
tPos += 2;
|
||||
}
|
||||
|
||||
points[pPos + 0] = 0;
|
||||
points[pPos + 1] = -radius;
|
||||
points[pPos + 2] = 0;
|
||||
points[pPos + 3] = 0;
|
||||
points[pPos + 4] = radius;
|
||||
points[pPos + 5] = 0;
|
||||
pPos += 6;
|
||||
|
||||
int pS = (div2 - 1) * division;
|
||||
|
||||
float textureDelta = 1.f / 256;
|
||||
for (int i = 0; i < division; ++i) {
|
||||
tPoints[tPos + 0] = rDiv * (0.5f + i);
|
||||
tPoints[tPos + 1] = textureDelta;
|
||||
tPos += 2;
|
||||
}
|
||||
|
||||
for (int i = 0; i < division; ++i) {
|
||||
tPoints[tPos + 0] = rDiv * (0.5f + i);
|
||||
tPoints[tPos + 1] = 1 - textureDelta;
|
||||
tPos += 2;
|
||||
}
|
||||
|
||||
int fIndex = 0;
|
||||
for (int y = 0; y < div2 - 2; ++y) {
|
||||
for (int x = 0; x < division; ++x) {
|
||||
int p0 = y * division + x;
|
||||
int p1 = p0 + 1;
|
||||
int p2 = p0 + division;
|
||||
int p3 = p1 + division;
|
||||
|
||||
int t0 = p0 + y;
|
||||
int t1 = t0 + 1;
|
||||
int t2 = t0 + division + 1;
|
||||
int t3 = t1 + division + 1;
|
||||
|
||||
// add p0, p1, p2
|
||||
faces[fIndex + 0] = p0;
|
||||
faces[fIndex + 1] = t0;
|
||||
faces[fIndex + 2] = p1 % division == 0 ? p1 - division : p1;
|
||||
faces[fIndex + 3] = t1;
|
||||
faces[fIndex + 4] = p2;
|
||||
faces[fIndex + 5] = t2;
|
||||
fIndex += 6;
|
||||
|
||||
// add p3, p2, p1
|
||||
faces[fIndex + 0] = p3 % division == 0 ? p3 - division : p3;
|
||||
faces[fIndex + 1] = t3;
|
||||
faces[fIndex + 2] = p2;
|
||||
faces[fIndex + 3] = t2;
|
||||
faces[fIndex + 4] = p1 % division == 0 ? p1 - division : p1;
|
||||
faces[fIndex + 5] = t1;
|
||||
fIndex += 6;
|
||||
}
|
||||
}
|
||||
|
||||
int p0 = pS;
|
||||
int tB = (div2 - 1) * (division + 1);
|
||||
for (int x = 0; x < division; ++x) {
|
||||
int p2 = x, p1 = x + 1, t0 = tB + x;
|
||||
faces[fIndex + 0] = p0;
|
||||
faces[fIndex + 1] = t0;
|
||||
faces[fIndex + 2] = p1 == division ? 0 : p1;
|
||||
faces[fIndex + 3] = p1;
|
||||
faces[fIndex + 4] = p2;
|
||||
faces[fIndex + 5] = p2;
|
||||
fIndex += 6;
|
||||
}
|
||||
|
||||
p0 = p0 + 1;
|
||||
tB = tB + division;
|
||||
int pB = (div2 - 2) * division;
|
||||
|
||||
for (int x = 0; x < division; ++x) {
|
||||
int p1 = pB + x, p2 = pB + x + 1, t0 = tB + x;
|
||||
int t1 = (div2 - 2) * (division + 1) + x, t2 = t1 + 1;
|
||||
faces[fIndex + 0] = p0;
|
||||
faces[fIndex + 1] = t0;
|
||||
faces[fIndex + 2] = p1;
|
||||
faces[fIndex + 3] = t1;
|
||||
faces[fIndex + 4] = p2 % division == 0 ? p2 - division : p2;
|
||||
faces[fIndex + 5] = t2;
|
||||
fIndex += 6;
|
||||
}
|
||||
|
||||
TriangleMesh m = new TriangleMesh();
|
||||
m.getPoints().setAll(points);
|
||||
m.getTexCoords().setAll(tPoints);
|
||||
m.getFaces().setAll(faces);
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
launch(args);
|
||||
}
|
||||
|
||||
}
|
||||
41
Task/Death-Star/JavaScript/death-star.js
Normal file
41
Task/Death-Star/JavaScript/death-star.js
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body style="margin:0">
|
||||
<canvas id="myCanvas" width="250" height="250" style="border:1px solid #d3d3d3;">
|
||||
Your browser does not support the HTML5 canvas tag.
|
||||
</canvas>
|
||||
<script>
|
||||
var c = document.getElementById("myCanvas");
|
||||
var ctx = c.getContext("2d");
|
||||
//Fill the canvas with a dark gray background
|
||||
ctx.fillStyle = "#222222";
|
||||
ctx.fillRect(0,0,250,250);
|
||||
|
||||
// Create radial gradient for large base circle
|
||||
var grd = ctx.createRadialGradient(225,175,190,225,150,130);
|
||||
grd.addColorStop(0,"#EEEEEE");
|
||||
grd.addColorStop(1,"black");
|
||||
//Apply gradient and fill circle
|
||||
ctx.fillStyle = grd;
|
||||
ctx.beginPath();
|
||||
ctx.arc(125,125,105,0,2*Math.PI);
|
||||
ctx.fill();
|
||||
|
||||
// Create linear gradient for small inner circle
|
||||
var grd = ctx.createLinearGradient(75,90,102,90);
|
||||
grd.addColorStop(0,"black");
|
||||
grd.addColorStop(1,"gray");
|
||||
//Apply gradient and fill circle
|
||||
ctx.fillStyle = grd;
|
||||
ctx.beginPath();
|
||||
ctx.arc(90,90,30,0,2*Math.PI);
|
||||
ctx.fill();
|
||||
|
||||
//Add another small circle on top of the previous one to enhance the "shadow"
|
||||
ctx.fillStyle = "black";
|
||||
ctx.beginPath();
|
||||
ctx.arc(80,90,17,0,2*Math.PI);
|
||||
ctx.fill();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
18
Task/Death-Star/Julia/death-star.julia
Normal file
18
Task/Death-Star/Julia/death-star.julia
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
# run in REPL
|
||||
using GLMakie
|
||||
|
||||
function deathstar()
|
||||
n = 60
|
||||
θ = [0; (0.5: n - 0.5) / n; 1]
|
||||
φ = [(0: 2n - 2) * 2 / (2n - 1); 2]
|
||||
# if x is +0.9 radius units, replace it with the coordinates of sphere surface
|
||||
# at (1.2,0,0) center, radius 0.5 units
|
||||
x = [(x1 = cospi(φ)*sinpi(θ)) > 0.9 ? 1.2 - x1 * 0.5 : x1 for θ in θ, φ in φ]
|
||||
y = [sinpi(φ)*sinpi(θ) for θ in θ, φ in φ]
|
||||
z = [cospi(θ) for θ in θ, φ in φ]
|
||||
scene = Scene(backgroundcolor=:black)
|
||||
surface!(scene, x, y, z, color = rand(RGBAf0, 124, 124), show_axis=false)
|
||||
return scene
|
||||
end
|
||||
|
||||
scene = deathstar()
|
||||
14
Task/Death-Star/LSL/death-star.lsl
Normal file
14
Task/Death-Star/LSL/death-star.lsl
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
default {
|
||||
state_entry() {
|
||||
llSetPrimitiveParams([PRIM_NAME, "RosettaCode DeathStar"]);
|
||||
llSetPrimitiveParams([PRIM_DESC, llGetObjectName()]);
|
||||
llSetPrimitiveParams([PRIM_TYPE, PRIM_TYPE_SPHERE, PRIM_HOLE_CIRCLE, <0.0, 1.0, 0.0>, 0.0, <0.0, 0.0, 0.0>, <0.12, 1.0, 0.0>]);
|
||||
llSetPrimitiveParams([PRIM_ROTATION, <-0.586217, 0.395411, -0.586217, 0.395411>]);
|
||||
llSetPrimitiveParams([PRIM_TEXTURE, ALL_SIDES, TEXTURE_BLANK, ZERO_VECTOR, ZERO_VECTOR, 0.0]);
|
||||
llSetPrimitiveParams([PRIM_TEXT, llGetObjectName(), <1.0, 1.0, 1.0>, 1.0]);
|
||||
llSetPrimitiveParams([PRIM_COLOR, ALL_SIDES, <0.5, 0.5, 0.5>, 1.0]);
|
||||
llSetPrimitiveParams([PRIM_BUMP_SHINY, ALL_SIDES, PRIM_SHINY_HIGH, PRIM_BUMP_NONE]);
|
||||
llSetPrimitiveParams([PRIM_SIZE, <10.0, 10.0, 10.0>]);
|
||||
llSetPrimitiveParams([PRIM_OMEGA, <0.0, 0.0, 1.0>, 1.0, 1.0]);
|
||||
}
|
||||
}
|
||||
42
Task/Death-Star/Lua/death-star.lua
Normal file
42
Task/Death-Star/Lua/death-star.lua
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
function V3(x,y,z) return {x=x,y=y,z=z} end
|
||||
function dot(v,w) return v.x*w.x + v.y*w.y + v.z*w.z end
|
||||
function norm(v) local m=math.sqrt(dot(v,v)) return V3(v.x/m, v.y/m, v.z/m) end
|
||||
function clamp(n,lo,hi) return math.floor(math.min(math.max(lo,n),hi)) end
|
||||
function hittest(s, x, y)
|
||||
local z = s.r^2 - (x-s.x)^2 - (y-s.y)^2
|
||||
if z >= 0 then
|
||||
z = math.sqrt(z)
|
||||
return true, s.z-z, s.z+z
|
||||
end
|
||||
return false, 0, 0
|
||||
end
|
||||
|
||||
function deathstar(pos, neg, sun, k, amb)
|
||||
shades = {[0]=" ",".",":","!","*","o","e","&","#","%","@"}
|
||||
for y = pos.x-pos.r-0.5, pos.x+pos.r+0.5 do
|
||||
for x = pos.x-pos.r-0.5, pos.x+pos.r+0.5, 0.5 do
|
||||
local hitpos, pz1, pz2 = hittest(pos, x, y)
|
||||
local result, hitneg, nz1, nz2 = 0
|
||||
if hitpos then
|
||||
hitneg, nz1, nz2 = hittest(neg, x, y)
|
||||
if not hitneg or nz1 > pz1 then result = 1
|
||||
elseif nz2 > pz2 then result = 0
|
||||
elseif nz2 > pz1 then result = 2
|
||||
else result = 1
|
||||
end
|
||||
end
|
||||
local shade = 0
|
||||
if result > 0 then
|
||||
if result == 1 then
|
||||
shade = clamp((1-dot(sun, norm(V3(x-pos.x, y-pos.y, pz1-pos.z)))^k+amb) * #shades, 1, #shades)
|
||||
else
|
||||
shade = clamp((1-dot(sun, norm(V3(neg.x-x, neg.y-y, neg.z-nz2)))^k+amb) * #shades, 1, #shades)
|
||||
end
|
||||
end
|
||||
io.write(shades[shade])
|
||||
end
|
||||
io.write("\n")
|
||||
end
|
||||
end
|
||||
|
||||
deathstar({x=20, y=20, z=0, r=20}, {x=10, y=10, z=-15, r=10}, norm(V3(-2,1,3)), 2, 0.1)
|
||||
6
Task/Death-Star/Maple/death-star.maple
Normal file
6
Task/Death-Star/Maple/death-star.maple
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
with(plots):
|
||||
with(plottools):
|
||||
plots:-display(
|
||||
implicitplot3d(x^2 + y^2 + z^2 = 1, x = -1..0.85, y = -1..1, z = -1..1, style = surface, grid = [50,50,50]),
|
||||
translate(rotate(implicitplot3d(x^2 + y^2 + z^2 = 1, x = 0.85..1, y = -1..1, z = -1..1, style = surface, grid = [50,50,50]), 0, Pi, 0), 1.70, 0, 0),
|
||||
axes = none, scaling = constrained, color = gray)
|
||||
3
Task/Death-Star/Mathematica/death-star.math
Normal file
3
Task/Death-Star/Mathematica/death-star.math
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
RegionPlot3D[x^2 + y^2 + z^2 < 1 && (x + 1.7)^2 + y^2 + z^2 > 1,
|
||||
{x, -1, 1}, {y, -1, 1}, {z, -1, 1},
|
||||
Boxed -> False, Mesh -> False, Axes -> False, Background -> Black, PlotPoints -> 100]
|
||||
90
Task/Death-Star/Nim/death-star.nim
Normal file
90
Task/Death-Star/Nim/death-star.nim
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
import math
|
||||
|
||||
import bitmap, grayscale_image, nimPNG
|
||||
|
||||
type
|
||||
|
||||
Vector = array[3, float]
|
||||
|
||||
Sphere = object
|
||||
cx, cy, cz: int
|
||||
r: int
|
||||
|
||||
#---------------------------------------------------------------------------------------------------
|
||||
|
||||
func dot(x, y: Vector): float {.inline.} =
|
||||
x[0] * y[0] + x[1] * y[1] + x[2] * y[2]
|
||||
|
||||
#---------------------------------------------------------------------------------------------------
|
||||
|
||||
func normalize(v: var Vector) =
|
||||
let invLen = 1 / sqrt(dot(v, v))
|
||||
v[0] *= invLen
|
||||
v[1] *= invLen
|
||||
v[2] *= invLen
|
||||
|
||||
#---------------------------------------------------------------------------------------------------
|
||||
|
||||
func hit(s: Sphere; x, y: int): tuple[z1, z2: float; hit: bool] =
|
||||
let x = x - s.cx
|
||||
let y = y - s.cy
|
||||
let zsq = s.r * s.r - (x * x + y * y)
|
||||
if zsq >= 0:
|
||||
let zsqrt = sqrt(zsq.toFloat)
|
||||
result = (s.cz.toFloat - zsqrt, s.cz.toFloat, true)
|
||||
else:
|
||||
result = (0.0, 0.0, false)
|
||||
|
||||
#---------------------------------------------------------------------------------------------------
|
||||
|
||||
func deathStar(pos, neg: Sphere; k, amb: float; dir: Vector): GrayImage =
|
||||
|
||||
let w = pos.r * 4
|
||||
let h = pos.r * 3
|
||||
result = newGrayImage(w, h)
|
||||
var vect: Vector
|
||||
let deltaX = pos.cx - w div 2
|
||||
let deltaY = pos.cy - h div 2
|
||||
|
||||
let xMax = pos.cx + pos.r
|
||||
let yMax = pos.cy + pos.r
|
||||
for y in (pos.cy - pos.r)..yMax:
|
||||
for x in (pos.cx - pos.r)..xMax:
|
||||
let (zb1, zb2, posHit) = pos.hit(x, y)
|
||||
if not posHit: continue
|
||||
var (zs1, zs2, negHit) = neg.hit(x, y)
|
||||
if negHit:
|
||||
if zs1 > zb1: negHit = false
|
||||
elif zs2 > zb2: continue
|
||||
if negHit:
|
||||
vect[0] = (neg.cx - x).toFloat
|
||||
vect[1] = (neg.cy - y).toFloat
|
||||
vect[2] = neg.cz.toFloat - zs2
|
||||
else:
|
||||
vect[0] = (x - pos.cx).toFloat
|
||||
vect[1] = (y - pos.cy).toFloat
|
||||
vect[2] = zb1 - pos.cz.toFloat
|
||||
vect.normalize()
|
||||
var s = dot(dir, vect)
|
||||
if s < 0: s = 0
|
||||
var lum = (255 * (s.pow(k) + amb) / (1 + amb)).toInt
|
||||
if lum < 0: lum = 0
|
||||
elif lum > 255: lum = 255
|
||||
result[x - deltaX, y - deltaY] = Luminance(lum)
|
||||
|
||||
#———————————————————————————————————————————————————————————————————————————————————————————————————
|
||||
|
||||
var dir: Vector = [float 20, -40, -10]
|
||||
dir.normalize()
|
||||
let pos = Sphere(cx: 0, cy: 0, cz: 0, r: 120)
|
||||
let neg = Sphere(cx: -90, cy: -90, cz: -30, r: 100)
|
||||
|
||||
let grayImage = deathStar(pos, neg, 1.5, 0.2, dir)
|
||||
|
||||
# Save to PNG. We convert to an RGB image then transform the pixels
|
||||
# in a sequence of bytes (actually a copy) in order to call "savePNG24".
|
||||
let rgbImage = grayImage.toImage
|
||||
var data = newSeqOfCap[byte](rgbImage.pixels.len * 3)
|
||||
for color in rgbImage.pixels:
|
||||
data.add([color.r, color.g, color.b])
|
||||
echo savePNG24("death_star.png", data, rgbImage.w, rgbImage.h)
|
||||
19
Task/Death-Star/Openscad/death-star.scad
Normal file
19
Task/Death-Star/Openscad/death-star.scad
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
// We are performing geometric subtraction
|
||||
|
||||
difference() {
|
||||
|
||||
// Create the primary sphere of radius 60 centred at the origin
|
||||
|
||||
translate(v = [0,0,0]) {
|
||||
sphere(60);
|
||||
}
|
||||
|
||||
/*Subtract an overlapping sphere with a radius of 40
|
||||
The resultant hole will be smaller than this, because we only
|
||||
only catch the edge
|
||||
*/
|
||||
|
||||
translate(v = [0,90,0]) {
|
||||
sphere(40);
|
||||
}
|
||||
}
|
||||
17
Task/Death-Star/POV-Ray/death-star.povray
Normal file
17
Task/Death-Star/POV-Ray/death-star.povray
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
camera { perspective location <0.0 , .8 ,-3.0> look_at 0
|
||||
aperture .1 blur_samples 20 variance 1/100000 focal_point 0}
|
||||
|
||||
light_source{< 3,3,-3> color rgb 1}
|
||||
|
||||
sky_sphere { pigment{ color rgb <0,.2,.5>}}
|
||||
|
||||
plane {y,-5 pigment {color rgb .54} normal {hexagon} }
|
||||
|
||||
difference {
|
||||
sphere { 0,1 }
|
||||
sphere { <-1,1,-1>,1 }
|
||||
texture {
|
||||
pigment{ granite }
|
||||
finish { phong 1 reflection {0.10 metallic 0.5} }
|
||||
}
|
||||
}
|
||||
75
Task/Death-Star/Perl/death-star.pl
Normal file
75
Task/Death-Star/Perl/death-star.pl
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
use strict;
|
||||
|
||||
sub sq {
|
||||
my $s = 0;
|
||||
$s += $_ ** 2 for @_;
|
||||
$s;
|
||||
}
|
||||
|
||||
sub hit {
|
||||
my ($sph, $x, $y) = @_;
|
||||
$x -= $sph->[0];
|
||||
$y -= $sph->[1];
|
||||
|
||||
my $z = sq($sph->[3]) - sq($x, $y);
|
||||
return if $z < 0;
|
||||
|
||||
$z = sqrt $z;
|
||||
return $sph->[2] - $z, $sph->[2] + $z;
|
||||
}
|
||||
|
||||
sub normalize {
|
||||
my $v = shift;
|
||||
my $n = sqrt sq(@$v);
|
||||
$_ /= $n for @$v;
|
||||
$v;
|
||||
}
|
||||
|
||||
sub dot {
|
||||
my ($x, $y) = @_;
|
||||
my $s = $x->[0] * $y->[0] + $x->[1] * $y->[1] + $x->[2] * $y->[2];
|
||||
$s > 0 ? $s : 0;
|
||||
}
|
||||
|
||||
my $pos = [ 120, 120, 0, 120 ];
|
||||
my $neg = [ -77, -33, -100, 190 ];
|
||||
my $light = normalize([ -12, 13, -10 ]);
|
||||
sub draw {
|
||||
my ($k, $amb) = @_;
|
||||
binmode STDOUT, ":raw";
|
||||
print "P5\n", $pos->[0] * 2 + 3, " ", $pos->[1] * 2 + 3, "\n255\n";
|
||||
for my $y (($pos->[1] - $pos->[3] - 1) .. ($pos->[1] + $pos->[3] + 1)) {
|
||||
my @row = ();
|
||||
for my $x (($pos->[0] - $pos->[3] - 1) .. ($pos->[0] + $pos->[3] + 1)) {
|
||||
my ($hit, @hs) = 0;
|
||||
my @h = hit($pos, $x, $y);
|
||||
|
||||
if (!@h) { $hit = 0 }
|
||||
elsif (!(@hs = hit($neg, $x, $y))) { $hit = 1 }
|
||||
elsif ($hs[0] > $h[0]) { $hit = 1 }
|
||||
elsif ($hs[1] > $h[0]) { $hit = $hs[1] > $h[1] ? 0 : 2 }
|
||||
else { $hit = 1 }
|
||||
|
||||
my ($val, $v);
|
||||
if ($hit == 0) { $val = 0 }
|
||||
elsif ($hit == 1) {
|
||||
$v = [ $x - $pos->[0],
|
||||
$y - $pos->[1],
|
||||
$h[0] - $pos->[2] ];
|
||||
} else {
|
||||
$v = [ $neg->[0] - $x,
|
||||
$neg->[1] - $y,
|
||||
$neg->[2] - $hs[1] ];
|
||||
}
|
||||
if ($v) {
|
||||
normalize($v);
|
||||
$val = int((dot($v, $light) ** $k + $amb) * 255);
|
||||
$val = ($val > 255) ? 255 : ($val < 0) ? 0 : $val;
|
||||
}
|
||||
push @row, $val;
|
||||
}
|
||||
print pack("C*", @row);
|
||||
}
|
||||
}
|
||||
|
||||
draw(2, 0.2);
|
||||
123
Task/Death-Star/Phix/death-star.phix
Normal file
123
Task/Death-Star/Phix/death-star.phix
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
(phixonline)-->
|
||||
<span style="color: #000080;font-style:italic;">--
|
||||
-- demo\rosetta\DeathStar.exw
|
||||
-- ==========================
|
||||
--
|
||||
-- Translated from Go.
|
||||
--</span>
|
||||
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
|
||||
<span style="color: #008080;">include</span> <span style="color: #000000;">pGUI</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
|
||||
|
||||
<span style="color: #008080;">constant</span> <span style="color: #000000;">title</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"Death Star"</span>
|
||||
<span style="color: #004080;">Ihandle</span> <span style="color: #000000;">dlg</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">canvas</span>
|
||||
<span style="color: #004080;">cdCanvas</span> <span style="color: #000000;">cddbuffer</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">cdcanvas</span>
|
||||
|
||||
<span style="color: #008080;">function</span> <span style="color: #000000;">dot</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">sequence</span> <span style="color: #000000;">y</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #7060A8;">sum</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">sq_mul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">x</span><span style="color: #0000FF;">,</span><span style="color: #000000;">y</span><span style="color: #0000FF;">))</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
|
||||
<span style="color: #008080;">function</span> <span style="color: #000000;">normalize</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">v</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #004080;">atom</span> <span style="color: #000000;">len</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sqrt</span><span style="color: #0000FF;">(</span><span style="color: #000000;">dot</span><span style="color: #0000FF;">(</span><span style="color: #000000;">v</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">v</span><span style="color: #0000FF;">))</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">len</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">}</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #7060A8;">sq_mul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">v</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">/</span><span style="color: #000000;">len</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
|
||||
<span style="color: #008080;">enum</span> <span style="color: #000000;">X</span><span style="color: #0000FF;">,</span><span style="color: #000000;">Y</span><span style="color: #0000FF;">,</span><span style="color: #000000;">Z</span>
|
||||
|
||||
<span style="color: #008080;">function</span> <span style="color: #000000;">hit</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">atom</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">y</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">r</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000000;">x</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">X</span><span style="color: #0000FF;">]</span>
|
||||
<span style="color: #000000;">y</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">Y</span><span style="color: #0000FF;">]</span>
|
||||
<span style="color: #004080;">atom</span> <span style="color: #000000;">zsq</span> <span style="color: #0000FF;">:=</span> <span style="color: #000000;">r</span><span style="color: #0000FF;">*</span><span style="color: #000000;">r</span> <span style="color: #0000FF;">-</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">x</span><span style="color: #0000FF;">*</span><span style="color: #000000;">x</span> <span style="color: #0000FF;">+</span> <span style="color: #000000;">y</span><span style="color: #0000FF;">*</span><span style="color: #000000;">y</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">zsq</span> <span style="color: #0000FF;">>=</span> <span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #004080;">atom</span> <span style="color: #000000;">zsqrt</span> <span style="color: #0000FF;">:=</span> <span style="color: #7060A8;">sqrt</span><span style="color: #0000FF;">(</span><span style="color: #000000;">zsq</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">Z</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">-</span> <span style="color: #000000;">zsqrt</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">Z</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">+</span> <span style="color: #000000;">zsqrt</span><span style="color: #0000FF;">,</span> <span style="color: #004600;">true</span><span style="color: #0000FF;">}</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #004600;">false</span><span style="color: #0000FF;">}</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
|
||||
<span style="color: #008080;">procedure</span> <span style="color: #000000;">deathStar</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">width</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">height</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">atom</span> <span style="color: #000000;">k</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">atom</span> <span style="color: #000000;">amb</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">sequence</span> <span style="color: #000000;">direction</span><span style="color: #0000FF;">)</span>
|
||||
|
||||
<span style="color: #004080;">atom</span> <span style="color: #000000;">t0</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">time</span><span style="color: #0000FF;">()+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">t1</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">t0</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">lmul</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">255</span><span style="color: #0000FF;">/(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">+</span><span style="color: #000000;">amb</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">r</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">((</span><span style="color: #7060A8;">min</span><span style="color: #0000FF;">(</span><span style="color: #000000;">width</span><span style="color: #0000FF;">,</span><span style="color: #000000;">height</span><span style="color: #0000FF;">)-</span><span style="color: #000000;">40</span><span style="color: #0000FF;">)/</span><span style="color: #000000;">2</span><span style="color: #0000FF;">),</span>
|
||||
<span style="color: #000000;">cx</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">width</span><span style="color: #0000FF;">/</span><span style="color: #000000;">2</span><span style="color: #0000FF;">),</span>
|
||||
<span style="color: #000000;">cy</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">height</span><span style="color: #0000FF;">/</span><span style="color: #000000;">2</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">pos</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">},</span>
|
||||
<span style="color: #000000;">neg</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">r</span><span style="color: #0000FF;">*-</span><span style="color: #000000;">3</span><span style="color: #0000FF;">/</span><span style="color: #000000;">4</span><span style="color: #0000FF;">,</span><span style="color: #000000;">r</span><span style="color: #0000FF;">*-</span><span style="color: #000000;">3</span><span style="color: #0000FF;">/</span><span style="color: #000000;">4</span><span style="color: #0000FF;">,</span><span style="color: #000000;">r</span><span style="color: #0000FF;">*-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">/</span><span style="color: #000000;">4</span><span style="color: #0000FF;">}</span>
|
||||
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">y</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">r</span> <span style="color: #008080;">to</span> <span style="color: #0000FF;">+</span><span style="color: #000000;">r</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #7060A8;">time</span><span style="color: #0000FF;">()></span><span style="color: #000000;">t1</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #000080;font-style:italic;">-- Let the user know we aren't completely dead just yet</span>
|
||||
<span style="color: #7060A8;">IupSetStrAttribute</span><span style="color: #0000FF;">(</span><span style="color: #000000;">dlg</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"TITLE"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%s - drawing (%d%%)"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">title</span><span style="color: #0000FF;">,</span><span style="color: #000000;">100</span><span style="color: #0000FF;">*(</span><span style="color: #000000;">y</span><span style="color: #0000FF;">+</span><span style="color: #000000;">r</span><span style="color: #0000FF;">)/(</span><span style="color: #000000;">2</span><span style="color: #0000FF;">*</span><span style="color: #000000;">r</span><span style="color: #0000FF;">)})</span>
|
||||
<span style="color: #000000;">t1</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">time</span><span style="color: #0000FF;">()+</span><span style="color: #000000;">1</span>
|
||||
<span style="color: #000080;font-style:italic;">--
|
||||
-- Hmm, not entirely sure why this is needed, but without it
|
||||
-- after ~7 seconds the window gets a "(Not Responding)" and
|
||||
-- then something decides to force a full repaint, which at
|
||||
-- fullscreen will never finish in < 7s on this ancient box.
|
||||
-- I suppose this is the corrollary to the above, this time
|
||||
-- letting Windows 10 know the process is not quite dead...
|
||||
-- Currently and possibly forever neither of these routines
|
||||
-- exist in pGUI.js, the browser is more forgiving anyway.
|
||||
--</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #7060A8;">platform</span><span style="color: #0000FF;">()!=</span><span style="color: #004600;">JS</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #7060A8;">IupLoopStep</span><span style="color: #0000FF;">()=</span><span style="color: #004600;">IUP_CLOSE</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #7060A8;">IupExitLoop</span><span style="color: #0000FF;">()</span>
|
||||
<span style="color: #008080;">exit</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">x</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">r</span> <span style="color: #008080;">to</span> <span style="color: #0000FF;">+</span><span style="color: #000000;">r</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #004080;">atom</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">zb1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">zb2</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">hit1</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">:=</span> <span style="color: #000000;">hit</span><span style="color: #0000FF;">(</span><span style="color: #000000;">pos</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">y</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">r</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">hit1</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #004080;">atom</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">zs1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">zs2</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">hit2</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">:=</span> <span style="color: #000000;">hit</span><span style="color: #0000FF;">(</span><span style="color: #000000;">neg</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">y</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">r</span><span style="color: #0000FF;">/</span><span style="color: #000000;">2</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #008080;">not</span> <span style="color: #000000;">hit2</span> <span style="color: #008080;">or</span> <span style="color: #000000;">zs2</span><span style="color: #0000FF;"><=</span><span style="color: #000000;">zb2</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #004080;">bool</span> <span style="color: #000000;">dish</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">hit2</span> <span style="color: #008080;">and</span> <span style="color: #000000;">zs1</span><span style="color: #0000FF;"><=</span><span style="color: #000000;">zb1</span>
|
||||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">vec</span> <span style="color: #0000FF;">=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">dish</span><span style="color: #0000FF;">?</span><span style="color: #7060A8;">sq_sub</span><span style="color: #0000FF;">(</span><span style="color: #000000;">neg</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">x</span><span style="color: #0000FF;">,</span><span style="color: #000000;">y</span><span style="color: #0000FF;">,</span><span style="color: #000000;">zs2</span><span style="color: #0000FF;">}):{</span><span style="color: #000000;">x</span><span style="color: #0000FF;">,</span><span style="color: #000000;">y</span><span style="color: #0000FF;">,</span><span style="color: #000000;">zb1</span><span style="color: #0000FF;">})</span>
|
||||
<span style="color: #004080;">atom</span> <span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">dot</span><span style="color: #0000FF;">(</span><span style="color: #000000;">direction</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">normalize</span><span style="color: #0000FF;">(</span><span style="color: #000000;">vec</span><span style="color: #0000FF;">)),</span>
|
||||
<span style="color: #000000;">l</span> <span style="color: #0000FF;">=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;"><=</span><span style="color: #000000;">0</span><span style="color: #0000FF;">?</span><span style="color: #000000;">0</span><span style="color: #0000FF;">:</span><span style="color: #7060A8;">power</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">,</span><span style="color: #000000;">k</span><span style="color: #0000FF;">))</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">lum</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">and_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">#FF</span><span style="color: #0000FF;">,</span><span style="color: #000000;">lmul</span><span style="color: #0000FF;">*(</span><span style="color: #000000;">l</span><span style="color: #0000FF;">+</span><span style="color: #000000;">amb</span><span style="color: #0000FF;">))</span>
|
||||
<span style="color: #7060A8;">cdCanvasPixel</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cddbuffer</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">cx</span><span style="color: #0000FF;">+</span><span style="color: #000000;">x</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">cy</span><span style="color: #0000FF;">-</span><span style="color: #000000;">y</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">lum</span><span style="color: #0000FF;">*</span><span style="color: #000000;">#10101</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">t1</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">t0</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #7060A8;">IupSetStrAttribute</span><span style="color: #0000FF;">(</span><span style="color: #000000;">dlg</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"TITLE"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">title</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
|
||||
|
||||
<span style="color: #008080;">function</span> <span style="color: #000000;">redraw_cb</span><span style="color: #0000FF;">(</span><span style="color: #004080;">Ihandle</span> <span style="color: #000080;font-style:italic;">/*ih*/</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000080;font-style:italic;">/*posx*/</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">/*posy*/</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">width</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">height</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">IupGetIntInt</span><span style="color: #0000FF;">(</span><span style="color: #000000;">canvas</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"DRAWSIZE"</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #7060A8;">cdCanvasActivate</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cddbuffer</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #7060A8;">cdCanvasClear</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cddbuffer</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000000;">deathStar</span><span style="color: #0000FF;">(</span><span style="color: #000000;">width</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">height</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.5</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0.2</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">normalize</span><span style="color: #0000FF;">({</span><span style="color: #000000;">20</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">40</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">10</span><span style="color: #0000FF;">}))</span>
|
||||
<span style="color: #7060A8;">cdCanvasFlush</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cddbuffer</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #004600;">IUP_DEFAULT</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
|
||||
<span style="color: #008080;">function</span> <span style="color: #000000;">map_cb</span><span style="color: #0000FF;">(</span><span style="color: #004080;">Ihandle</span> <span style="color: #000000;">ih</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000000;">cdcanvas</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">cdCreateCanvas</span><span style="color: #0000FF;">(</span><span style="color: #004600;">CD_IUP</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">ih</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000000;">cddbuffer</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">cdCreateCanvas</span><span style="color: #0000FF;">(</span><span style="color: #004600;">CD_DBUFFER</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">cdcanvas</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #7060A8;">cdCanvasSetBackground</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cddbuffer</span><span style="color: #0000FF;">,</span> <span style="color: #004600;">CD_BLACK</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #004600;">IUP_DEFAULT</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
|
||||
<span style="color: #008080;">procedure</span> <span style="color: #000000;">main</span><span style="color: #0000FF;">()</span>
|
||||
<span style="color: #7060A8;">IupOpen</span><span style="color: #0000FF;">()</span>
|
||||
<span style="color: #000000;">canvas</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">IupCanvas</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"RASTERSIZE=340x340"</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #7060A8;">IupSetCallbacks</span><span style="color: #0000FF;">(</span><span style="color: #000000;">canvas</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">{</span><span style="color: #008000;">"MAP_CB"</span><span style="color: #0000FF;">,</span> <span style="color: #7060A8;">Icallback</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"map_cb"</span><span style="color: #0000FF;">),</span>
|
||||
<span style="color: #008000;">"ACTION"</span><span style="color: #0000FF;">,</span> <span style="color: #7060A8;">Icallback</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"redraw_cb"</span><span style="color: #0000FF;">)})</span>
|
||||
<span style="color: #000000;">dlg</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">IupDialog</span><span style="color: #0000FF;">(</span><span style="color: #000000;">canvas</span><span style="color: #0000FF;">,</span><span style="color: #008000;">`TITLE="%s"`</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">title</span><span style="color: #0000FF;">})</span>
|
||||
|
||||
<span style="color: #7060A8;">IupMap</span><span style="color: #0000FF;">(</span><span style="color: #000000;">dlg</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #7060A8;">IupSetAttribute</span><span style="color: #0000FF;">(</span><span style="color: #000000;">canvas</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"RASTERSIZE"</span><span style="color: #0000FF;">,</span> <span style="color: #004600;">NULL</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- release the minimum limitation</span>
|
||||
<span style="color: #7060A8;">IupShow</span><span style="color: #0000FF;">(</span><span style="color: #000000;">dlg</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #7060A8;">platform</span><span style="color: #0000FF;">()!=</span><span style="color: #004600;">JS</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #7060A8;">IupMainLoop</span><span style="color: #0000FF;">()</span>
|
||||
<span style="color: #7060A8;">IupClose</span><span style="color: #0000FF;">()</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
|
||||
|
||||
<span style="color: #000000;">main</span><span style="color: #0000FF;">()</span>
|
||||
<!--
|
||||
67
Task/Death-Star/Python/death-star.py
Normal file
67
Task/Death-Star/Python/death-star.py
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
import sys, math, collections
|
||||
|
||||
Sphere = collections.namedtuple("Sphere", "cx cy cz r")
|
||||
V3 = collections.namedtuple("V3", "x y z")
|
||||
|
||||
def normalize((x, y, z)):
|
||||
len = math.sqrt(x**2 + y**2 + z**2)
|
||||
return V3(x / len, y / len, z / len)
|
||||
|
||||
def dot(v1, v2):
|
||||
d = v1.x*v2.x + v1.y*v2.y + v1.z*v2.z
|
||||
return -d if d < 0 else 0.0
|
||||
|
||||
def hit_sphere(sph, x0, y0):
|
||||
x = x0 - sph.cx
|
||||
y = y0 - sph.cy
|
||||
zsq = sph.r ** 2 - (x ** 2 + y ** 2)
|
||||
if zsq < 0:
|
||||
return (False, 0, 0)
|
||||
szsq = math.sqrt(zsq)
|
||||
return (True, sph.cz - szsq, sph.cz + szsq)
|
||||
|
||||
def draw_sphere(k, ambient, light):
|
||||
shades = ".:!*oe&#%@"
|
||||
pos = Sphere(20.0, 20.0, 0.0, 20.0)
|
||||
neg = Sphere(1.0, 1.0, -6.0, 20.0)
|
||||
|
||||
for i in xrange(int(math.floor(pos.cy - pos.r)),
|
||||
int(math.ceil(pos.cy + pos.r) + 1)):
|
||||
y = i + 0.5
|
||||
for j in xrange(int(math.floor(pos.cx - 2 * pos.r)),
|
||||
int(math.ceil(pos.cx + 2 * pos.r) + 1)):
|
||||
x = (j - pos.cx) / 2.0 + 0.5 + pos.cx
|
||||
|
||||
(h, zb1, zb2) = hit_sphere(pos, x, y)
|
||||
if not h:
|
||||
hit_result = 0
|
||||
else:
|
||||
(h, zs1, zs2) = hit_sphere(neg, x, y)
|
||||
if not h:
|
||||
hit_result = 1
|
||||
elif zs1 > zb1:
|
||||
hit_result = 1
|
||||
elif zs2 > zb2:
|
||||
hit_result = 0
|
||||
elif zs2 > zb1:
|
||||
hit_result = 2
|
||||
else:
|
||||
hit_result = 1
|
||||
|
||||
if hit_result == 0:
|
||||
sys.stdout.write(' ')
|
||||
continue
|
||||
elif hit_result == 1:
|
||||
vec = V3(x - pos.cx, y - pos.cy, zb1 - pos.cz)
|
||||
elif hit_result == 2:
|
||||
vec = V3(neg.cx-x, neg.cy-y, neg.cz-zs2)
|
||||
vec = normalize(vec)
|
||||
|
||||
b = dot(light, vec) ** k + ambient
|
||||
intensity = int((1 - b) * len(shades))
|
||||
intensity = min(len(shades), max(0, intensity))
|
||||
sys.stdout.write(shades[intensity])
|
||||
print
|
||||
|
||||
light = normalize(V3(-50, 30, 50))
|
||||
draw_sphere(2, 0.5, light)
|
||||
42
Task/Death-Star/Q/death-star-1.q
Normal file
42
Task/Death-Star/Q/death-star-1.q
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
/ https://en.wikipedia.org/wiki/BMP_file_format
|
||||
/ BITMAPINFOHEADER / RGB24
|
||||
|
||||
/ generate a header
|
||||
|
||||
genheader:{[w;h]
|
||||
0x424d, "x"$(f2i4[54+4*h*w],0,0,0,0,54,0,0,0,40,0,0,0,
|
||||
f2i4[h],f2i4[w],1,0,24,0,0,0,0,0,
|
||||
f2i4[h*((w*3)+((w*3)mod 4))],
|
||||
19,11,0,0,19,11,0,0,0,0,0,0,0,0,0,0)};
|
||||
|
||||
/ generate a raster line at a vertical position
|
||||
|
||||
genrow:{[w;y;fcn]
|
||||
row:enlist 0i;xx:0i;do[w;row,:fcn[xx;y];xx+:1i];row,:((w mod 4)#0i);1_row};
|
||||
|
||||
/ generate a bitmap
|
||||
|
||||
genbitmap:{[w;h;fcn]
|
||||
ary:enlist 0i;yy:0i;do[h;ary,:genrow[w;yy;fcn];yy+:1i];"x"$1_ary};
|
||||
|
||||
/ deal with endianness
|
||||
/ might need to reverse last line if host computer is not a PC
|
||||
|
||||
f2i4:{[x] r:x;
|
||||
s0:r mod 256;r-:s0; r%:256;
|
||||
s1:r mod 256;r-:s1; r%:256;
|
||||
s2:r mod 256;r-:s2; r%:256;
|
||||
s3:r mod 256;
|
||||
"h"$(s0,s1,s2,s3)}
|
||||
|
||||
/ compose and write a file
|
||||
|
||||
writebmp:{[w;h;fcn;fn]
|
||||
fn 1: (genheader[h;w],genbitmap[w;h;fcn])};
|
||||
|
||||
/ / usage example:
|
||||
/ w:400;
|
||||
/ h:300;
|
||||
/ fcn:{x0:x-w%2;y0:y-h%2;r:175;$[(r*r)>((x0*x0)+(y0*y0));(0;0;255);(0;255;0)]};
|
||||
/ fn:`:demo.bmp;
|
||||
/ writebmp[w;h;fcn;fn];
|
||||
38
Task/Death-Star/Q/death-star-2.q
Normal file
38
Task/Death-Star/Q/death-star-2.q
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
w:400; h:300; r:150; l:-0.5 0.7 0.5
|
||||
sqrt0:{$[x>0;sqrt x;0]};
|
||||
|
||||
/ get x,y,z position of point on sphere given x,y,r
|
||||
|
||||
z:{[x;y;r]sqrt0((r*r)-((x*x)+(y*y)))};
|
||||
|
||||
/ get diffused light at point on sphere
|
||||
|
||||
is:{[x;y;r]
|
||||
z0:z[x;y;r];
|
||||
s:(x;y;z0)%r;
|
||||
$[z0>0;i:0.5*1+(+/)(s*l);i:0];
|
||||
i};
|
||||
|
||||
/ get pixel value at given image position
|
||||
|
||||
fcn:{[xpx;ypx]
|
||||
x:xpx-w%2;
|
||||
y:ypx-h%2;
|
||||
z1:z[x;y;r];
|
||||
x2:x+190;
|
||||
z2:170-z[x2;y;r];
|
||||
$[(r*r)<((x*x)+(y*y));
|
||||
$[y>-50;
|
||||
i:3#0;
|
||||
i:200 100 50];
|
||||
$[z2>z1;
|
||||
i:3#is[x;y;r]*140;
|
||||
i:3#is[(-1*x2);(-1*y);r]*120]
|
||||
];
|
||||
"i"$i};
|
||||
|
||||
/ do it ...
|
||||
|
||||
\l bmp.q
|
||||
fn:`:demo.bmp;
|
||||
writebmp[w;h;fcn;fn];
|
||||
54
Task/Death-Star/REXX/death-star.rexx
Normal file
54
Task/Death-Star/REXX/death-star.rexx
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
/*REXX program displays a sphere with another sphere subtracted where it's superimposed.*/
|
||||
call deathStar 2, .5, v3('-50 30 50')
|
||||
exit /*stick a fork in it, we're all done. */
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
dot: #=0; do j=1 for words(x); #=# + word(x,j)*word(y,j); end; return #
|
||||
dot.: procedure; parse arg x,y; d=dot(x,y); if d<0 then return -d; return 0
|
||||
ceil: procedure; parse arg x; _=trunc(x); return _+(x>0)*(x\=_)
|
||||
floor: procedure; parse arg x; _=trunc(x); return _-(x<0)*(x\=_)
|
||||
v3: procedure; parse arg a b c; #=sqrt(a**2 + b**2 + c**2); return a/# b/# c/#
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
sqrt: procedure; parse arg x; if x=0 then return 0; d=digits(); h= d+6; numeric digits
|
||||
m.=9; numeric form; parse value format(x,2,1,,0) 'E0' with g 'E' _ .; g=g*.5'e'_%2
|
||||
do j=0 while h>9; m.j= h; h= h % 2 + 1; end /*j*/
|
||||
do k=j+5 to 0 by -1; numeric digits m.k; g= (g +x/g)* .5; end /*k*/; return g
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
hitSphere: procedure expose !.; parse arg xx yy zz r,x0,y0; z= r*r -(x0-xx)**2-(y0-yy)**2
|
||||
if z<0 then return 0; _= sqrt(z); !.z1= zz - _; !.z2= zz + _; return 1
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
deathStar: procedure; parse arg k,ambient,sun /* [↓] display the deathstar to screen*/
|
||||
parse var sun s1 s2 s3 /*identify the light source coördinates*/
|
||||
if 5=="f5"x then shading= '.:!*oe&#%@' /*dithering chars for an EBCDIC machine*/
|
||||
else shading= '·:!ºoe@░▒▓' /* " " " " ASCII " */
|
||||
shadingL= length(shading) /*the number of dithering characters. */
|
||||
shades.= ' '; do i=1 for shadingL; shades.i= substr(shading, i, 1)
|
||||
end /*i*/
|
||||
ship= 20 20 0 20 ; parse var ship shipX shipY shipZ shipR
|
||||
hole= ' 1 1 -6 20' ; parse var hole holeX holeY holeZ .
|
||||
|
||||
do i=floor(shipY-shipR ) to ceil(shipY+shipR )+1; y= i +.5; @= /*@ is a single line of the deathstar to be displayed.*/
|
||||
do j=floor(shipX-shipR*2) to ceil(shipX+shipR*2)+1; !.= 0
|
||||
x=.5 * (j-shipX+1) + shipX; $bg= 0; $pos= 0; $neg= 0 /*$BG, $POS, and $NEG are boolean values. */
|
||||
?= hitSphere(ship, x, y); b1= !.z1; b2= !.z2 /*? is boolean, "true" indicates ray hits the sphere.*/
|
||||
/*$BG: if 1, its background; if zero, it's foreground.*/
|
||||
if \? then $bg= 1 /*ray lands in blank space, so draw the background. */
|
||||
else do; ?= hitSphere(hole, x, y); s1= !.z1; s2= !.z2
|
||||
if \? then $pos= 1 /*ray hits ship but not the hole, so draw ship surface. */
|
||||
else if s1>b1 then $pos=1 /*ray hits both, but ship front surface is closer. */
|
||||
else if s2>b2 then $bg= 1 /*ship surface is inside hole, so show the background. */
|
||||
else if s2>b1 then $neg=1 /*hole back surface is inside ship; the only place ··· */
|
||||
else $pos=1 /*························ a hole surface will be shown.*/
|
||||
end
|
||||
select
|
||||
when $bg then do; @= @' '; iterate j; end /*append a blank character to the line to be displayed. */
|
||||
when $pos then vec_= v3(x-shipX y-shipY b1-shipZ)
|
||||
when $neg then vec_= v3(holeX-x holeY-y holeZ-s2)
|
||||
end /*select*/
|
||||
|
||||
b=1 +min(shadingL, max(0, trunc((1 - (dot.(sun, v3(vec_))**k + ambient)) * shadingL)))
|
||||
@=@ || shades.b /*B: the ray's intensity│brightness*/
|
||||
end /*j*/ /* [↑] build a line for the sphere.*/
|
||||
|
||||
if @\='' then say strip(@, 'T') /*strip trailing blanks from line. */
|
||||
end /*i*/ /* [↑] show all lines for sphere. */
|
||||
return
|
||||
9
Task/Death-Star/Racket/death-star.rkt
Normal file
9
Task/Death-Star/Racket/death-star.rkt
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
#lang racket
|
||||
(require plot)
|
||||
(plot3d (polar3d (λ (φ θ) (real-part (- (sin θ) (sqrt (- (sqr 1/3) (sqr (cos θ)))))))
|
||||
#:samples 100 #:line-style 'transparent #:color 9)
|
||||
#:altitude 60 #:angle 80
|
||||
#:height 500 #:width 400
|
||||
#:x-min -1/2 #:x-max 1/2
|
||||
#:y-min -1/2 #:y-max 1/2
|
||||
#:z-min 0 #:z-max 1)
|
||||
87
Task/Death-Star/Raku/death-star.raku
Normal file
87
Task/Death-Star/Raku/death-star.raku
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
class sphere {
|
||||
has $.cx; # center x coordinate
|
||||
has $.cy; # center y coordinate
|
||||
has $.cz; # center z coordinate
|
||||
has $.r; # radius
|
||||
}
|
||||
|
||||
my $depth = 255; # image color depth
|
||||
|
||||
my $width = my $height = 255; # dimensions of generated .pgm; must be odd
|
||||
|
||||
my $s = ($width - 1)/2; # scaled dimension to build geometry
|
||||
|
||||
my @light = normalize([ 4, -1, -3 ]);
|
||||
|
||||
# positive sphere at origin
|
||||
my $pos = sphere.new(
|
||||
cx => 0,
|
||||
cy => 0,
|
||||
cz => 0,
|
||||
r => $s.Int
|
||||
);
|
||||
|
||||
# negative sphere offset to upper left
|
||||
my $neg = sphere.new(
|
||||
cx => (-$s*.90).Int,
|
||||
cy => (-$s*.90).Int,
|
||||
cz => (-$s*.3).Int,
|
||||
r => ($s*.7).Int
|
||||
);
|
||||
|
||||
sub MAIN ($outfile = 'deathstar-perl6.pgm') {
|
||||
spurt $outfile, ("P5\n$width $height\n$depth\n"); # .pgm header
|
||||
my $out = open( $outfile, :a, :bin ) orelse .die;
|
||||
say 'Working...';
|
||||
$out.write( Blob.new( |draw_ds(3, .15) ) );
|
||||
say 'File written.';
|
||||
$out.close;
|
||||
}
|
||||
|
||||
sub draw_ds ( $k, $ambient ) {
|
||||
my @pixels[$height];
|
||||
|
||||
(($pos.cy - $pos.r) .. ($pos.cy + $pos.r)).race.map: -> $y {
|
||||
my @row[$width];
|
||||
(($pos.cx - $pos.r) .. ($pos.cx + $pos.r)).map: -> $x {
|
||||
# black if we don't hit positive sphere, ignore negative sphere
|
||||
if not hit($pos, $x, $y, my $posz) {
|
||||
@row[$x + $s] = 0;
|
||||
next;
|
||||
}
|
||||
my @vec;
|
||||
# is front of positive sphere inside negative sphere?
|
||||
if hit($neg, $x, $y, my $negz) and $negz.min < $posz.min < $negz.max {
|
||||
# make black if whole positive sphere eaten here
|
||||
if $negz.min < $posz.max < $negz.max { @row[$x + $s] = 0; next; }
|
||||
# render inside of negative sphere
|
||||
@vec = normalize([$neg.cx - $x, $neg.cy - $y, -$negz.max - $neg.cz]);
|
||||
}
|
||||
else {
|
||||
# render outside of positive sphere
|
||||
@vec = normalize([$x - $pos.cx, $y - $pos.cy, $posz.max - $pos.cz]);
|
||||
}
|
||||
my $intensity = dot(@light, @vec) ** $k + $ambient;
|
||||
@row[$x + $s] = ($intensity * $depth).Int min $depth;
|
||||
}
|
||||
@pixels[$y + $s] = @row;
|
||||
}
|
||||
flat |@pixels.map: *.list;
|
||||
}
|
||||
|
||||
# normalize a vector
|
||||
sub normalize (@vec) { @vec »/» ([+] @vec »*« @vec).sqrt }
|
||||
|
||||
# dot product of two vectors
|
||||
sub dot (@x, @y) { -([+] @x »*« @y) max 0 }
|
||||
|
||||
# are the coordinates within the radius of the sphere?
|
||||
sub hit ($sphere, $x is copy, $y is copy, $z is rw) {
|
||||
$x -= $sphere.cx;
|
||||
$y -= $sphere.cy;
|
||||
my $z2 = $sphere.r * $sphere.r - $x * $x - $y * $y;
|
||||
return False if $z2 < 0;
|
||||
$z2 = $z2.sqrt;
|
||||
$z = $sphere.cz - $z2 .. $sphere.cz + $z2;
|
||||
True;
|
||||
}
|
||||
60
Task/Death-Star/Set-lang/death-star.set
Normal file
60
Task/Death-Star/Set-lang/death-star.set
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
set ! 32
|
||||
set ! 32
|
||||
set ! 46
|
||||
set ! 45
|
||||
set ! 126
|
||||
set ! 34
|
||||
set ! 34
|
||||
set ! 126
|
||||
set ! 45
|
||||
set ! 46
|
||||
set ! 10
|
||||
set ! 46
|
||||
set ! 39
|
||||
set ! 40
|
||||
set ! 95
|
||||
set ! 41
|
||||
set ! 32
|
||||
set ! 32
|
||||
set ! 32
|
||||
set ! 32
|
||||
set ! 32
|
||||
set ! 39
|
||||
set ! 46
|
||||
set ! 10
|
||||
set ! 124
|
||||
set ! 61
|
||||
set ! 61
|
||||
set ! 61
|
||||
set ! 61
|
||||
set ! 61
|
||||
set ! 61
|
||||
set ! 61
|
||||
set ! 61
|
||||
set ! 61
|
||||
set ! 61
|
||||
set ! 124
|
||||
set ! 10
|
||||
set ! 39
|
||||
set ! 46
|
||||
set ! 32
|
||||
set ! 32
|
||||
set ! 32
|
||||
set ! 32
|
||||
set ! 32
|
||||
set ! 32
|
||||
set ! 32
|
||||
set ! 32
|
||||
set ! 46
|
||||
set ! 39
|
||||
set ! 10
|
||||
set ! 32
|
||||
set ! 32
|
||||
set ! 126
|
||||
set ! 45
|
||||
set ! 46
|
||||
set ! 95
|
||||
set ! 95
|
||||
set ! 46
|
||||
set ! 45
|
||||
set ! 126
|
||||
62
Task/Death-Star/Sidef/death-star.sidef
Normal file
62
Task/Death-Star/Sidef/death-star.sidef
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
func hitf(sph, x, y) {
|
||||
x -= sph[0]
|
||||
y -= sph[1]
|
||||
|
||||
var z = (sph[3]**2 - (x**2 + y**2))
|
||||
|
||||
z < 0 && return nil
|
||||
|
||||
z.sqrt!
|
||||
[sph[2] - z, sph[2] + z]
|
||||
}
|
||||
|
||||
func normalize(v) {
|
||||
v / v.abs
|
||||
}
|
||||
|
||||
func dot(x, y) {
|
||||
max(0, x*y)
|
||||
}
|
||||
|
||||
var pos = [120, 120, 0, 120]
|
||||
var neg = [-77, -33, -100, 190]
|
||||
var light = normalize(Vector(-12, 13, -10))
|
||||
|
||||
func draw(k, amb) {
|
||||
STDOUT.binmode(':raw')
|
||||
print ("P5\n", pos[0]*2 + 3, " ", pos[1]*2 + 3, "\n255\n")
|
||||
|
||||
for y in ((pos[1] - pos[3] - 1) .. (pos[1] + pos[3] + 1)) {
|
||||
var row = []
|
||||
for x in ((pos[0] - pos[3] - 1) .. (pos[0] + pos[3] + 1)) {
|
||||
|
||||
var hit = 0
|
||||
var hs = []
|
||||
var h = hitf(pos, x, y)
|
||||
|
||||
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) }
|
||||
else { hit = 1 }
|
||||
|
||||
var (val, v)
|
||||
|
||||
given(hit) {
|
||||
when (0) { val = 0}
|
||||
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]) }
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
print 'C*'.pack(row...)
|
||||
}
|
||||
}
|
||||
|
||||
draw(2, 0.2)
|
||||
115
Task/Death-Star/Tcl/death-star-1.tcl
Normal file
115
Task/Death-Star/Tcl/death-star-1.tcl
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
package require Tcl 8.5
|
||||
|
||||
proc normalize vec {
|
||||
upvar 1 $vec v
|
||||
lassign $v x y z
|
||||
set len [expr {sqrt($x**2 + $y**2 + $z**2)}]
|
||||
set v [list [expr {$x/$len}] [expr {$y/$len}] [expr {$z/$len}]]
|
||||
return
|
||||
}
|
||||
|
||||
proc dot {a b} {
|
||||
lassign $a ax ay az
|
||||
lassign $b bx by bz
|
||||
return [expr {-($ax*$bx + $ay*$by + $az*$bz)}]
|
||||
}
|
||||
|
||||
# Intersection code; assumes that the vector is parallel to the Z-axis
|
||||
proc hitSphere {sphere x y z1 z2} {
|
||||
dict with sphere {
|
||||
set x [expr {$x - $cx}]
|
||||
set y [expr {$y - $cy}]
|
||||
set zsq [expr {$r**2 - $x**2 - $y**2}]
|
||||
if {$zsq < 0} {return 0}
|
||||
upvar 1 $z1 _1 $z2 _2
|
||||
set zsq [expr {sqrt($zsq)}]
|
||||
set _1 [expr {$cz - $zsq}]
|
||||
set _2 [expr {$cz + $zsq}]
|
||||
return 1
|
||||
}
|
||||
}
|
||||
|
||||
# How to do the intersection with our scene
|
||||
proc intersectDeathStar {x y vecName} {
|
||||
global big small
|
||||
if {![hitSphere $big $x $y zb1 zb2]} {
|
||||
# ray lands in blank space
|
||||
return 0
|
||||
}
|
||||
upvar 1 $vecName vec
|
||||
# ray hits big sphere; check if it hit the small one first
|
||||
set vec [if {
|
||||
![hitSphere $small $x $y zs1 zs2] || $zs1 > $zb1 || $zs2 <= $zb1
|
||||
} then {
|
||||
dict with big {
|
||||
list [expr {$x - $cx}] [expr {$y - $cy}] [expr {$zb1 - $cz}]
|
||||
}
|
||||
} else {
|
||||
dict with small {
|
||||
list [expr {$cx - $x}] [expr {$cy - $y}] [expr {$cz - $zs2}]
|
||||
}
|
||||
}]
|
||||
normalize vec
|
||||
return 1
|
||||
}
|
||||
|
||||
# Intensity calculators for different lighting components
|
||||
proc diffuse {k intensity L N} {
|
||||
expr {[dot $L $N] ** $k * $intensity}
|
||||
}
|
||||
proc specular {k intensity L N S} {
|
||||
# Calculate reflection vector
|
||||
set r [expr {2 * [dot $L $N]}]
|
||||
foreach l $L n $N {lappend R [expr {$l-$r*$n}]}
|
||||
normalize R
|
||||
# Calculate the specular reflection term
|
||||
return [expr {[dot $R $S] ** $k * $intensity}]
|
||||
}
|
||||
|
||||
# Simple raytracing engine that uses parallel rays
|
||||
proc raytraceEngine {diffparms specparms ambient intersector shades renderer fx tx sx fy ty sy} {
|
||||
global light
|
||||
for {set y $fy} {$y <= $ty} {set y [expr {$y + $sy}]} {
|
||||
set line {}
|
||||
for {set x $fx} {$x <= $tx} {set x [expr {$x + $sx}]} {
|
||||
if {![$intersector $x $y vec]} {
|
||||
# ray lands in blank space
|
||||
set intensity end
|
||||
} else {
|
||||
# ray hits something; we've got the normalized vector
|
||||
set b [expr {
|
||||
[diffuse {*}$diffparms $light $vec]
|
||||
+ [specular {*}$specparms $light $vec {0 0 -1}]
|
||||
+ $ambient
|
||||
}]
|
||||
set intensity [expr {int((1-$b) * ([llength $shades]-1))}]
|
||||
if {$intensity < 0} {
|
||||
set intensity 0
|
||||
} elseif {$intensity >= [llength $shades]-1} {
|
||||
set intensity end-1
|
||||
}
|
||||
}
|
||||
lappend line [lindex $shades $intensity]
|
||||
}
|
||||
{*}$renderer $line
|
||||
}
|
||||
}
|
||||
|
||||
# The general scene settings
|
||||
set light {-50 30 50}
|
||||
set big {cx 20 cy 20 cz 0 r 20}
|
||||
set small {cx 7 cy 7 cz -10 r 15}
|
||||
normalize light
|
||||
|
||||
# Render as text
|
||||
proc textDeathStar {diff spec lightBrightness ambient} {
|
||||
global big
|
||||
dict with big {
|
||||
raytraceEngine [list $diff $lightBrightness] \
|
||||
[list $spec $lightBrightness] $ambient intersectDeathStar \
|
||||
[split ".:!*oe&#%@ " {}] {apply {l {puts [join $l ""]}}} \
|
||||
[expr {$cx+floor(-$r)}] [expr {$cx+ceil($r)+0.5}] 0.5 \
|
||||
[expr {$cy+floor(-$r)+0.5}] [expr {$cy+ceil($r)+0.5}] 1
|
||||
}
|
||||
}
|
||||
textDeathStar 3 10 0.7 0.3
|
||||
18
Task/Death-Star/Tcl/death-star-2.tcl
Normal file
18
Task/Death-Star/Tcl/death-star-2.tcl
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
# Render as a picture (with many hard-coded settings)
|
||||
package require Tk
|
||||
proc guiDeathStar {photo diff spec lightBrightness ambient} {
|
||||
set row 0
|
||||
for {set i 255} {$i>=0} {incr i -1} {
|
||||
lappend shades [format "#%02x%02x%02x" $i $i $i]
|
||||
}
|
||||
raytraceEngine [list $diff $lightBrightness] \
|
||||
[list $spec $lightBrightness] $ambient intersectDeathStar \
|
||||
$shades {apply {l {
|
||||
upvar 2 photo photo row row
|
||||
$photo put [list $l] -to 0 $row
|
||||
incr row
|
||||
update
|
||||
}}} 0 40 0.0625 0 40 0.0625
|
||||
}
|
||||
pack [label .l -image [image create photo ds]]
|
||||
guiDeathStar ds 3 10 0.7 0.3
|
||||
81
Task/Death-Star/VBScript/death-star.vb
Normal file
81
Task/Death-Star/VBScript/death-star.vb
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
'deathstar ascii graphics
|
||||
|
||||
option explicit
|
||||
|
||||
const x_=0
|
||||
const y_=1
|
||||
const z_=2
|
||||
const r_=3
|
||||
|
||||
function clamp(x,b,t)
|
||||
if x<b then
|
||||
clamp=b
|
||||
elseif x>t then
|
||||
clamp =t
|
||||
else
|
||||
clamp=x
|
||||
end if
|
||||
end function
|
||||
|
||||
function dot(v,w) dot=v(x_)*w(x_)+v(y_)*w(y_)+v(z_)*w(z_): end function
|
||||
|
||||
function normal (byval v)
|
||||
dim ilen:ilen=1/sqr(dot(v,v)):
|
||||
v(x_)=v(x_)*ilen: v(y_)=v(y_)*ilen: v(z_)=v(z_)*ilen:
|
||||
normal=v:
|
||||
end function
|
||||
|
||||
function hittest(s,x,y)
|
||||
dim z
|
||||
z = s(r_)^2 - (x-s(x_))^2 - (y-s(y_))^2
|
||||
if z>=0 then
|
||||
z=sqr(z)
|
||||
hittest=array(s(z_)-z,s(z_)+z)
|
||||
else
|
||||
hittest=0
|
||||
end if
|
||||
end function
|
||||
|
||||
sub deathstar(pos, neg, sun, k, amb)
|
||||
dim x,y,shades,result,shade,hp,hn,xx,b
|
||||
shades=array(" ",".",":","!","*","o","e","&","#","%","@")
|
||||
for y = pos(y_)-pos(r_)-0.5 to pos(y_)+pos(r_)+0.5
|
||||
for x = pos(x_)-pos(r_)-0.5 to pos(x_)+pos(r_)+.5
|
||||
hp=hittest (pos, x, y)
|
||||
hn=hittest(neg,x,y)
|
||||
if not isarray(hp) then
|
||||
result=0
|
||||
elseif not isarray(hn) then
|
||||
result=1
|
||||
elseif hn(0)>hp(0) then
|
||||
result=1
|
||||
elseif hn(1)>hp(1) then
|
||||
result=0
|
||||
elseif hn(1)>hp(0) then
|
||||
result=2
|
||||
else
|
||||
result=1
|
||||
end if
|
||||
|
||||
shade=-1
|
||||
select case result
|
||||
case 0
|
||||
shade=0
|
||||
case 1
|
||||
xx=normal(array(x-pos(x_),y-pos(y_),hp(0)-pos(z_)))
|
||||
'shade=clamp(1-dot(sun,xx)^k+amb,1,ubound(shades))
|
||||
case 2
|
||||
xx=normal(array(neg(x_)-x,neg(y_)-y,neg(z_)-hn(1)))
|
||||
'shade=clamp(1-dot(sun,xx)^k+amb,1,ubound(shades))
|
||||
end select
|
||||
if shade <>0 then
|
||||
b=dot(sun,xx)^k+amb
|
||||
shade=clamp((1-b) *ubound(shades),1,ubound(shades))
|
||||
end if
|
||||
wscript.stdout.write string(2,shades(shade))
|
||||
next
|
||||
wscript.stdout.write vbcrlf
|
||||
next
|
||||
end sub
|
||||
|
||||
deathstar array(20, 20, 0, 20),array(10,10,-15,10), normal(array(-2,1,3)), 2, 0.1
|
||||
104
Task/Death-Star/Wren/death-star.wren
Normal file
104
Task/Death-Star/Wren/death-star.wren
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
import "dome" for Window
|
||||
import "graphics" for Canvas, Color, ImageData
|
||||
import "math" for Vector
|
||||
|
||||
var Normalize = Fn.new{ |vec|
|
||||
var invLen = 1 / vec.dot(vec).sqrt
|
||||
vec.x = vec.x * invLen
|
||||
vec.y = vec.y * invLen
|
||||
vec.z = vec.z * invLen
|
||||
}
|
||||
|
||||
class Sphere {
|
||||
construct new(cx, cy, cz, r) {
|
||||
_cx = cx
|
||||
_cy = cy
|
||||
_cz = cz
|
||||
_r = r
|
||||
}
|
||||
|
||||
cx { _cx }
|
||||
cy { _cy }
|
||||
cz { _cz }
|
||||
r { _r }
|
||||
|
||||
hit(x, y) {
|
||||
x = x - _cx
|
||||
y = y - _cy
|
||||
var zsq = _r*_r - x*x - y*y
|
||||
if (zsq >= 0) {
|
||||
var zsqrt = zsq.sqrt
|
||||
return [_cz - zsqrt, _cz + zsqrt, true]
|
||||
}
|
||||
return [0, 0, false]
|
||||
}
|
||||
}
|
||||
|
||||
class DeathStar {
|
||||
construct new(width, height) {
|
||||
Window.title = "Death star"
|
||||
Window.resize(width, height)
|
||||
Canvas.resize(width, height)
|
||||
}
|
||||
|
||||
init() {
|
||||
Canvas.cls(Color.white)
|
||||
var dir = Vector.new(20, -40, 10)
|
||||
Normalize.call(dir)
|
||||
var pos = Sphere.new(220, 190, 220, 120)
|
||||
var neg = Sphere.new(130, 100, 190, 100)
|
||||
deathStar(pos, neg, 1.5, 0.2, dir)
|
||||
}
|
||||
|
||||
deathStar(pos, neg, k, amb, dir) {
|
||||
var w = pos.r * 4
|
||||
var h = pos.r * 3
|
||||
var img = ImageData.create("deathStar", w, h)
|
||||
var vec = Vector.new(0, 0, 0)
|
||||
for (y in pos.cy - pos.r..pos.cy + pos.r) {
|
||||
for (x in pos.cx - pos.r..pos.cx + pos.r) {
|
||||
var res = pos.hit(x, y)
|
||||
var zb1 = res[0]
|
||||
var zb2 = res[1]
|
||||
var hit = res[2]
|
||||
if (!hit) continue
|
||||
res = neg.hit(x, y)
|
||||
var zs1 = res[0]
|
||||
var zs2 = res[1]
|
||||
hit = res[2]
|
||||
if (hit) {
|
||||
if (zs1 > zb1) {
|
||||
hit = false
|
||||
} else if (zs2 > zb2) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
if (hit) {
|
||||
vec.x = neg.cx - x
|
||||
vec.y = neg.cy - y
|
||||
vec.z = neg.cz - zs2
|
||||
} else {
|
||||
vec.x = x - pos.cx
|
||||
vec.y = y - pos.cy
|
||||
vec.z = zb1 - pos.cz
|
||||
}
|
||||
Normalize.call(vec)
|
||||
var s = dir.dot(vec)
|
||||
if (s < 0) s = 0
|
||||
var lum = 255 * (s.pow(k) + amb) / (1 + amb)
|
||||
lum = lum.clamp(0, 255)
|
||||
img.pset(x, y, Color.rgb(lum, lum, lum))
|
||||
}
|
||||
}
|
||||
img.draw(pos.cx - w/2, pos.cy - h/2)
|
||||
img.saveToFile("deathStar.png")
|
||||
}
|
||||
|
||||
update() {
|
||||
}
|
||||
|
||||
draw(alpha) {
|
||||
}
|
||||
}
|
||||
|
||||
var Game = DeathStar.new(400, 400)
|
||||
155
Task/Death-Star/Yabasic/death-star.basic
Normal file
155
Task/Death-Star/Yabasic/death-star.basic
Normal file
|
|
@ -0,0 +1,155 @@
|
|||
open window 100,100
|
||||
window origin "cc"
|
||||
backcolor 0,0,0
|
||||
clear window
|
||||
|
||||
tonos = 100
|
||||
interv = int(255 / tonos)
|
||||
dim shades(tonos)
|
||||
|
||||
shades(1) = 255
|
||||
for i = 2 to tonos
|
||||
shades(i) = shades(i-1) - interv
|
||||
next i
|
||||
|
||||
dim light(3)
|
||||
|
||||
light(0) = 30
|
||||
light(1) = 30
|
||||
light(2) = -50
|
||||
|
||||
|
||||
sub normalize(v())
|
||||
local long
|
||||
|
||||
long = sqrt(v(0)*v(0) + v(1)*v(1) + v(2)*v(2))
|
||||
v(0) = v(0) / long
|
||||
v(1) = v(1) / long
|
||||
v(2) = v(2) / long
|
||||
end sub
|
||||
|
||||
|
||||
sub punto(x(), y())
|
||||
local d
|
||||
|
||||
d = x(0)*y(0) + x(1)*y(1) + x(2)*y(2)
|
||||
if d < 0 then
|
||||
return -d
|
||||
else
|
||||
return 0
|
||||
end if
|
||||
end sub
|
||||
|
||||
|
||||
//* positive shpere and negative sphere */
|
||||
dim pos(3)
|
||||
dim neg(3)
|
||||
|
||||
// x, y, z, r
|
||||
|
||||
pos(0) = 10
|
||||
pos(1) = 10
|
||||
pos(2) = 0
|
||||
pos(3) = 20
|
||||
|
||||
neg(0) = 0
|
||||
neg(1) = 0
|
||||
neg(2) = -5
|
||||
neg(3) = 15
|
||||
|
||||
|
||||
sub hit_sphere(sph(), x, y)
|
||||
local zsq
|
||||
|
||||
x = x - sph(0)
|
||||
y = y - sph(1)
|
||||
zsq = sph(3) * sph(3) - (x * x + y * y)
|
||||
if (zsq < 0) then
|
||||
return 0
|
||||
else
|
||||
return sqrt(zsq)
|
||||
end if
|
||||
end sub
|
||||
|
||||
|
||||
sub draw_sphere(k, ambient)
|
||||
local i, j, intensity, hit_result, result, b, vec(3), x, y, zb1, zb2, zs1, zs2, ini1, fin1, ini2, fin2
|
||||
|
||||
ini1 = int(pos(1) - pos(3))
|
||||
fin1 = int(pos(1) + pos(3) + .5)
|
||||
for i = ini1 to fin1
|
||||
y = i + .5
|
||||
ini2 = int(pos(0) - 2 * pos(3))
|
||||
fin2 = int(pos(0) + 2 * pos(3) + .5)
|
||||
for j = ini2 to fin2
|
||||
x = (j - pos(0)) / 2 + .5 + pos(0)
|
||||
|
||||
// ray lands in blank space, draw bg
|
||||
result = hit_sphere(pos(), x, y)
|
||||
|
||||
if not result then
|
||||
hit_result = 0
|
||||
|
||||
//* ray hits pos sphere but not neg, draw pos sphere surface */
|
||||
else
|
||||
zb1 = pos(2) - result
|
||||
zb2 = pos(2) + result
|
||||
result = hit_sphere(neg(), x, y)
|
||||
if not result then
|
||||
hit_result = 1
|
||||
else
|
||||
zs1 = neg(2) - result
|
||||
zs2 = neg(2) + result
|
||||
if (zs1 > zb1) then
|
||||
hit_result = 1
|
||||
elseif (zs2 > zb2) then
|
||||
hit_result = 0
|
||||
elseif (zs2 > zb1) then
|
||||
hit_result = 2
|
||||
else
|
||||
hit_result = 1
|
||||
end if
|
||||
end if
|
||||
end if
|
||||
|
||||
if not hit_result then
|
||||
color 0,0,0
|
||||
dot x, y
|
||||
else
|
||||
switch(hit_result)
|
||||
case 1:
|
||||
vec(0) = x - pos(0)
|
||||
vec(1) = y - pos(1)
|
||||
vec(2) = zb1 - pos(2)
|
||||
break
|
||||
default:
|
||||
vec(0) = neg(0) - x
|
||||
vec(1) = neg(1) - y
|
||||
vec(2) = neg(2) - zs2
|
||||
end switch
|
||||
|
||||
normalize(vec())
|
||||
b = (punto(light(), vec())^k) + ambient
|
||||
intensity = (1 - b) * tonos
|
||||
if (intensity < 1) intensity = 1
|
||||
if (intensity > tonos) intensity = tonos
|
||||
color shades(intensity),shades(intensity),shades(intensity)
|
||||
dot x,y
|
||||
end if
|
||||
next j
|
||||
next i
|
||||
end sub
|
||||
|
||||
|
||||
ang = 0
|
||||
|
||||
while(true)
|
||||
//clear window
|
||||
light(1) = cos(ang * 2)
|
||||
light(2) = cos(ang)
|
||||
light(0) = sin(ang)
|
||||
normalize(light())
|
||||
ang = ang + .05
|
||||
|
||||
draw_sphere(2, .3)
|
||||
wend
|
||||
2
Task/Death-Star/Zig/death-star-1.zig
Normal file
2
Task/Death-Star/Zig/death-star-1.zig
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
const std = @import("std");
|
||||
const Allocator = std.mem.Allocator;
|
||||
29
Task/Death-Star/Zig/death-star-2.zig
Normal file
29
Task/Death-Star/Zig/death-star-2.zig
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
pub fn main() !void {
|
||||
// buffer stdout --------------------------------------
|
||||
const stdout_file = std.io.getStdOut().writer();
|
||||
var bw = std.io.bufferedWriter(stdout_file);
|
||||
const stdout = bw.writer();
|
||||
|
||||
// allocator ------------------------------------------
|
||||
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
||||
defer {
|
||||
const ok = gpa.deinit();
|
||||
std.debug.assert(ok == .ok);
|
||||
}
|
||||
const allocator = gpa.allocator();
|
||||
|
||||
// deathstar ------------------------------------------
|
||||
var dstar = try DeathStar(f32).init(allocator);
|
||||
defer dstar.deinit();
|
||||
|
||||
// print deathstar PGM to stdout ----------------------
|
||||
const comments = [_][]const u8{
|
||||
"Rosetta Code",
|
||||
"DeathStar",
|
||||
"https://rosettacode.org/wiki/Death_Star",
|
||||
};
|
||||
try dstar.print(stdout, comments[0..]);
|
||||
|
||||
// ----------------------------------------------------
|
||||
try bw.flush();
|
||||
}
|
||||
27
Task/Death-Star/Zig/death-star-3.zig
Normal file
27
Task/Death-Star/Zig/death-star-3.zig
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
fn Vector(comptime T: type) type {
|
||||
return struct {
|
||||
const Self = @This();
|
||||
x: T,
|
||||
y: T,
|
||||
z: T,
|
||||
|
||||
pub fn init(x: T, y: T, z: T) Self {
|
||||
return Self{ .x = x, .y = y, .z = z };
|
||||
}
|
||||
pub fn zero() Self {
|
||||
return Self{ .x = 0.0, .y = 0.0, .z = 0.0 };
|
||||
}
|
||||
fn dot(a: *const Self, b: *const Self) T {
|
||||
return a.x * b.x + a.y * b.y + a.z * b.z;
|
||||
}
|
||||
fn length(self: *const Self) T {
|
||||
return std.math.sqrt(self.dot(self));
|
||||
}
|
||||
pub fn normalize(self: *Self) void {
|
||||
const inv_length = 1 / self.length();
|
||||
self.*.x *= inv_length;
|
||||
self.*.y *= inv_length;
|
||||
self.*.z *= inv_length;
|
||||
}
|
||||
};
|
||||
}
|
||||
3
Task/Death-Star/Zig/death-star-4.zig
Normal file
3
Task/Death-Star/Zig/death-star-4.zig
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
fn SphereHit(comptime T: type) type {
|
||||
return struct { z1: T, z2: T };
|
||||
}
|
||||
25
Task/Death-Star/Zig/death-star-5.zig
Normal file
25
Task/Death-Star/Zig/death-star-5.zig
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
fn Sphere(comptime T: type) type {
|
||||
return struct {
|
||||
const Self = @This();
|
||||
cx: T,
|
||||
cy: T,
|
||||
cz: T,
|
||||
r: T,
|
||||
|
||||
pub fn init(cx: T, cy: T, cz: T, r: T) Self {
|
||||
return Self{ .cx = cx, .cy = cy, .cz = cz, .r = r };
|
||||
}
|
||||
/// 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.
|
||||
pub fn hit(self: *const Self, xx: T, yy: T) ?SphereHit(T) {
|
||||
const x = xx - self.cx;
|
||||
const y = yy - self.cy;
|
||||
var zsq = self.r * self.r - x * x - y * y;
|
||||
if (zsq >= 0) {
|
||||
var zsqrt = std.math.sqrt(zsq);
|
||||
return .{ .z1 = self.cz - zsqrt, .z2 = self.cz + zsqrt };
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
}
|
||||
101
Task/Death-Star/Zig/death-star-6.zig
Normal file
101
Task/Death-Star/Zig/death-star-6.zig
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
fn DeathStar(comptime T: type) type {
|
||||
return struct {
|
||||
const Self = @This();
|
||||
allocator: Allocator,
|
||||
w: usize,
|
||||
h: usize,
|
||||
img: ImageData(),
|
||||
|
||||
const Hit = enum { background, neg, pos };
|
||||
|
||||
pub fn init(allocator: Allocator) !Self {
|
||||
var dir = Vector(T).init(20, -40, 10);
|
||||
dir.normalize();
|
||||
// positive sphere and negative sphere
|
||||
const pos = Sphere(T).init(180, 240, 220, 120);
|
||||
const neg = Sphere(T).init(60, 150, 100, 100);
|
||||
|
||||
const k: T = 1.5;
|
||||
const amb: T = 0.2;
|
||||
|
||||
var w: usize = @intFromFloat(pos.r * 4);
|
||||
var h: usize = @intFromFloat(pos.r * 3);
|
||||
var img = try ImageData().init(allocator, "deathStar", w, h);
|
||||
|
||||
var vec = Vector(T).zero();
|
||||
|
||||
const start_y: usize = @intFromFloat(pos.cy - pos.r);
|
||||
const end_y: usize = @intFromFloat(pos.cy + pos.r);
|
||||
const start_x: usize = @intFromFloat(pos.cx - pos.r);
|
||||
const end_x: usize = @intFromFloat(pos.cx + pos.r);
|
||||
|
||||
for (start_y..end_y + 1) |j| {
|
||||
for (start_x..end_x + 1) |i| {
|
||||
const x: T = @floatFromInt(i);
|
||||
const y: T = @floatFromInt(j);
|
||||
|
||||
const result_pos = pos.hit(x, y);
|
||||
// ray lands in blank space, show bg
|
||||
if (result_pos == null)
|
||||
continue;
|
||||
|
||||
const zb1 = result_pos.?.z1;
|
||||
const zb2 = result_pos.?.z2;
|
||||
|
||||
const result_neg = neg.hit(x, y);
|
||||
|
||||
switch (calcHit(result_neg, zb1, zb2)) {
|
||||
.background => continue,
|
||||
.neg => {
|
||||
vec.x = neg.cx - x;
|
||||
vec.y = neg.cy - y;
|
||||
vec.z = neg.cz - result_neg.?.z2; // zs2
|
||||
},
|
||||
.pos => {
|
||||
vec.x = x - pos.cx;
|
||||
vec.y = y - pos.cy;
|
||||
vec.z = zb1 - pos.cz;
|
||||
},
|
||||
}
|
||||
vec.normalize();
|
||||
var s = dir.dot(&vec);
|
||||
if (s < 0) s = 0;
|
||||
const lum = 255 * (std.math.pow(T, s, k) + amb) / (1 + amb);
|
||||
const lumi: u8 = @intFromFloat(std.math.clamp(lum, 0, 255));
|
||||
img.pset(i, j, Gray{ .w = lumi });
|
||||
}
|
||||
}
|
||||
return Self{ .allocator = allocator, .w = w, .h = h, .img = img };
|
||||
}
|
||||
pub fn deinit(self: *Self) void {
|
||||
self.img.deinit();
|
||||
}
|
||||
pub fn print(self: *Self, writer: anytype, optional_comments: ?[]const []const u8) !void {
|
||||
try self.img.print(writer, optional_comments);
|
||||
}
|
||||
/// Ray has hit the positive sphere.
|
||||
/// How does it intersect the negative sphere ?
|
||||
fn calcHit(neg_hit: ?SphereHit(T), zb1: T, zb2: T) Hit {
|
||||
if (neg_hit) |result| {
|
||||
const zs1 = result.z1;
|
||||
const zs2 = result.z2;
|
||||
if (zs1 > zb1) {
|
||||
// ray hits both, but pos front surface is closer
|
||||
return Hit.pos;
|
||||
} else if (zs2 > zb2) {
|
||||
// pos sphere surface is inside neg sphere, show bg
|
||||
return 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
|
||||
return Hit.neg;
|
||||
} else {
|
||||
return Hit.pos;
|
||||
}
|
||||
} else {
|
||||
// ray hits pos sphere but not neg, draw pos sphere surface
|
||||
return Hit.pos;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
4
Task/Death-Star/Zig/death-star-7.zig
Normal file
4
Task/Death-Star/Zig/death-star-7.zig
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
const Gray = struct {
|
||||
w: u8,
|
||||
const black = Gray{ .w = 0 };
|
||||
};
|
||||
39
Task/Death-Star/Zig/death-star-8.zig
Normal file
39
Task/Death-Star/Zig/death-star-8.zig
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
fn ImageData() type {
|
||||
return struct {
|
||||
const Self = @This();
|
||||
allocator: Allocator,
|
||||
name: []const u8,
|
||||
w: usize,
|
||||
h: usize,
|
||||
image: []Gray,
|
||||
|
||||
pub fn init(allocator: Allocator, name: []const u8, w: usize, h: usize) !Self {
|
||||
const image = try allocator.alloc(Gray, h * w);
|
||||
// black background fill
|
||||
for (image) |*pixel| pixel.* = Gray.black;
|
||||
return Self{ .allocator = allocator, .image = image, .name = name, .w = w, .h = h };
|
||||
}
|
||||
pub fn deinit(self: *Self) void {
|
||||
self.allocator.free(self.image);
|
||||
}
|
||||
pub fn pset(self: *Self, x: usize, y: usize, gray: Gray) void {
|
||||
self.image[x * self.w + y] = gray;
|
||||
}
|
||||
/// Write PGM P2 ASCII to 'writer'
|
||||
pub fn print(self: *const Self, writer: anytype, optional_comments: ?[]const []const u8) !void {
|
||||
_ = try writer.print("P2\n", .{});
|
||||
|
||||
if (optional_comments) |lines| {
|
||||
for (lines) |line|
|
||||
_ = try writer.print("# {s}\n", .{line});
|
||||
}
|
||||
|
||||
_ = try writer.print("{d} {d}\n{d}\n", .{ self.w, self.h, 255 });
|
||||
|
||||
for (self.image, 0..) |pixel, i| {
|
||||
const sep = if (i % self.w == self.w - 1) "\n" else " ";
|
||||
_ = try writer.print("{d}{s}", .{ pixel.w, sep });
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue