Death Star: Difference between revisions

61,887 bytes added ,  22 days ago
m
→‎{{header|POV-Ray}}: Changed syntax highlight language to "pov" to make it work
m (changed a word to plural (;Tasks:).)
m (→‎{{header|POV-Ray}}: Changed syntax highlight language to "pov" to make it work)
(21 intermediate revisions by 12 users not shown)
Line 23:
* [[Write_language_name_in_3D_ASCII|write language name in 3D ASCII]]
<br><br>
 
=={{header|11l}}==
{{trans|Python}}
 
<syntaxhighlight lang="11l">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)</syntaxhighlight>
 
{{out}}
<pre>
eeeee:::::::
eeeeeeeee..............
ooeeeeeeeeee..................
ooooeeeeeeeee......................
oooooooeeeeeeee..........................
ooooooooooeeeee..............................
**ooooooooooeeee.................................
****ooooooooooee.....................................
!*****ooooooooooe.......................................
!!!*****ooooooooo:..........................................
:!!!!*****ooooooo:::...........................................
:::!!!!*****ooooo!:::::...........................................
::::!!!!!*****ooo!!!!::::............................................
.::::!!!!*****oo*!!!!!::::............................................
...::::!!!!*********!!!!:::::............................................
...::::!!!!****o*****!!!!!::::............................................
....::::!!!!***ooo******!!!!!::::............................................
....::::!!!!*ooooooo*****!!!!!:::::...........................................
...::::!!!!!oooooooooo*****!!!!!:::::..........................................
:::::!!!!eeooooooooooo******!!!!!:::::.........................................
!!!!!eeeeeeeooooooooooo******!!!!!:::::........................................
eeeeeeeeeeeeoooooooooooo******!!!!!:::::.......................................
eeeeeeeeeeeeeoooooooooooo******!!!!!!:::::.....................................
eeeeeeeeeeeeeeoooooooooooo******!!!!!!:::::....................................
eeeeeeeeeeeeeeoooooooooooo*******!!!!!!:::::.................................
eeeeeeeeeeeeeeeooooooooooooo******!!!!!!::::::..............................:
eeeeeeeeeeeeeeeooooooooooooo*******!!!!!!:::::::..........................:
eeeeeeeeeeeeeeeeoooooooooooooo*******!!!!!!!:::::::.....................::!
eeeeeeeeeeeeeeeeeooooooooooooo********!!!!!!!:::::::::..............::::!
eeeeeeeeeeeeeeeeeoooooooooooooo********!!!!!!!!::::::::::::::::::::::!*
eeeeeeeeeeeeeeeeeeooooooooooooooo********!!!!!!!!!!:::::::::::::!!!!*
eeeeeeeeeeeeeeeeeoooooooooooooooo**********!!!!!!!!!!!!!!!!!!!!!*
eeeeeeeeeeeeeeeeeeooooooooooooooooo************!!!!!!!!!!!!****
eeeeeeeeeeeeeeeeeeoooooooooooooooooo**********************o
eeeeeeeeeeeeeeeeeeeooooooooooooooooooooo************ooo
eeeeeeeeeeeeeeeeeeeeooooooooooooooooooooooooooooooo
eeeeeeeeeeeeeeeeeeeeooooooooooooooooooooooooo
eeeeeeeeeeeeeeeeeeeeeoooooooooooooooooo
eeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
eeeeeeeeeeeeeeeee
</pre>
 
=={{header|Ada}}==
{{libheader|SDLAda}}{{trans|Go}}
 
<langsyntaxhighlight Adalang="ada">with Ada.Numerics.Elementary_Functions;
with Ada.Numerics.Generic_Real_Arrays;
 
Line 169 ⟶ 284:
Window.Finalize;
SDL.Finalise;
end Death_Star;</langsyntaxhighlight>
 
=={{header|ALGOL 68}}==
{{Trans|C}}{{Trans|11l}}
<syntaxhighlight lang="algol68">
BEGIN # draw a "Death Star" - translated from the C and 11l samples #
STRING shades = ".:!*oe&#%@";
 
PROC normalize = ( []REAL v )[]REAL:
BEGIN
REAL len = sqrt( v[ 1 ] * v[ 1 ] + v[ 2 ] * v[ 2 ] + v[ 3 ] * v[ 3 ] );
( v[ 1 ] / len, v[ 2 ] / len, v[ 3 ] / len )
END # normalize # ;
 
PROC dot = ( []REAL x, y )REAL:
BEGIN
REAL d = x[ 1 ] * y[ 1 ] + x[ 2 ] * y[ 2 ] + x[ 3 ] * y[ 3 ];
IF d < 0 THEN - d ELSE 0 FI
END # dot # ;
 
MODE SPHERE = STRUCT( REAL cx, cy, cz, r );
 
# positive shpere and negative sphere #
SPHERE 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 #
PROC hit_sphere = ( SPHERE sph, REAL x in, y in, REF REAL z1, z2 )BOOL:
IF REAL x = x in - cx OF sph;
REAL y = y in - cy OF sph;
REAL zsq := r OF sph * r OF sph - ( x * x + y * y );
zsq < 0
THEN FALSE
ELSE zsq := sqrt( zsq );
z1 := cz OF sph - zsq;
z2 := cz OF sph + zsq;
TRUE
FI # hit_sphere # ;
 
PROC draw_sphere = ( REAL k, ambient, []REAL light )VOID:
FOR i FROM ENTIER ( cy OF pos - r OF pos ) TO ENTIER ( cy OF pos + r OF pos ) + 1 DO
REAL y := i + 0.5;
FOR j FROM ENTIER ( cx OF pos - 2 * r OF pos ) TO ENTIER (cx OF pos + 2 * r OF pos ) + 1 DO
REAL x := ( j - cx OF pos ) / 2.0 + 0.5 + cx OF pos;
REAL zb1 := 0, zb2 := 0, zs1 := 0, zs2 := 0;
INT hit_result
= IF NOT hit_sphere( pos, x, y, zb1, zb2 ) THEN
0 # ray lands in blank space, draw bg #
ELIF NOT hit_sphere( neg, x, y, zs1, zs2 ) THEN
1 # ray hits pos sphere but not neg, draw pos sphere surface #
ELIF zs1 > zb1 THEN
1 # ray hits both, but pos front surface is closer #
ELIF zs2 > zb2 THEN
0 # pos sphere surface is inside neg sphere, show bg #
ELIF zs2 > zb1 THEN
2 # back surface on neg sphere is inside pos sphere, #
# the only place where neg sphere surface will be shown #
ELSE
1 # show the pos sphere #
FI;
IF hit_result = 0 THEN
print( ( " " ) )
ELSE
[]REAL vec =
normalize( IF hit_result = 1
THEN []REAL( x - cx OF pos
, y - cy OF pos
, zb1 - cz OF pos
)
ELSE []REAL( cx OF neg - x
, cy OF neg - y
, cz OF neg - zs2
)
FI
);
REAL b = ( dot( light, vec ) ^ k ) + ambient;
INT intensity := ENTIER ( ( 1 - b ) * ( ( UPB shades - LWB shades ) + 1 ) ) + 1;
IF intensity < LWB shades THEN intensity := LWB shades
ELIF intensity > UPB shades THEN intensity := UPB shades
FI;
print( ( shades[ intensity ] ) )
FI
OD;
print( ( newline ) )
OD # draw_sphere # ;
 
BEGIN
[]REAL light = ( -50, 30, 50 );
draw_sphere( 2, 0.5, normalize( light ) )
END
END
</syntaxhighlight>
{{out}}
Same as 11l
 
=={{header|AutoHotkey}}==
{{libheader|GDIP}}
<langsyntaxhighlight lang="ahk">#NoEnv
SetBatchLines, -1
#SingleInstance, Force
Line 252 ⟶ 460:
; gdi+ may now be shutdown on exiting the program
Gdip_Shutdown(pToken)
ExitApp</langsyntaxhighlight>
 
=={{header|Brlcad}}==
<langsyntaxhighlight lang="brlcad"># We need a database to hold the objects
opendb deathstar.g y
 
Line 280 ⟶ 488:
 
# We now trigger the raytracer to see our finished product
rt</langsyntaxhighlight>
 
=={{header|C}}==
Primitive ray tracing.
<langsyntaxhighlight lang="c">#include <stdio.h>
#include <math.h>
#include <unistd.h>
Line 395 ⟶ 603:
}
return 0;
}</langsyntaxhighlight>
 
=={{header|D}}==
{{trans|C}}
<langsyntaxhighlight lang="d">import std.stdio, std.math, std.numeric, std.algorithm;
 
struct V3 {
Line 507 ⟶ 715:
immutable light = [-50, 30, 50].V3.normalize;
drawSphere(2, 0.5, light);
}</langsyntaxhighlight>
 
The output is the same of the C version.
Line 518 ⟶ 726:
{{Trans|C}}
Translate of [[#C]] and [[#Go]], with copy of some parts of [[#DWScript]].
<syntaxhighlight lang="delphi">
<lang Delphi>
program Death_Star;
 
Line 672 ⟶ 880:
Free;
end;
end.</langsyntaxhighlight>
=={{header|DWScript}}==
{{trans|C}}
<langsyntaxhighlight lang="delphi">const cShades = '.:!*oe&#%@';
 
type TVector = array [0..2] of Float;
Line 768 ⟶ 976:
Normalize(light);
DrawSphere(2, 0.3);</langsyntaxhighlight>
 
=={{header|Frink}}==
This program not only draws a Death Star and renders it onscreen projected on the x,y, and z axes but also outputs a .stl file for 3-D printing. Frink has [https://frinklang.org/3d/frink/graphics/package-summary.html built-in routines for 3-D modeling].
<syntaxhighlight lang="frink">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."]
</syntaxhighlight>
 
=={{header|Go}}==
[[file:GoDstar.png|right|thumb|Output png]]
{{trans|C}}
<langsyntaxhighlight lang="go">package main
 
import (
Line 875 ⟶ 1,104:
fmt.Println(err)
}
}</langsyntaxhighlight>
 
=={{header|Haskell}}==
 
=== ASCII art ===
 
<syntaxhighlight lang="haskell">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)</syntaxhighlight>
 
<pre>λ> putStrLn $ deathStar 10 4 0.1
eeeeoo*&&&&&&&
eeeeeoooo**!&&&&&&&&&&&&
eeooooooo***!!&&&&&&&&&&&&&&&&
eooooo*****!!!::&&&&&&&&&&&&&&&&&&
eooo****!!!!:::.&&&&&&&&&&&&&&&&&&&&
eeeoo***!!!::::.&&&&&&##############&&&&
eeeoo***!!:::...&&&########%%%%%%%%#####&&
eeoo**!!!::...&&######%%%%%%%eeeeee%%%%###
eooo**!!::..&&&#####%%%%%eeeeeooooooeeee%%#&
oo**!!:&&&&&&&####%%%%eeeoooo********oooee%#
&&&&&&&&&&&&#####%%%eeeoo****!!!!!!!!***oe%#
&&&&&&&&&&&####%%%eeeoo***!!!::::::::!!**oe#
&&&&&&&&&&###%%%eeooo**!!:::.......::!!*oe
&&&&&&&&&####%%eeeoo**!!::..........::!*o%
&&&&&&&&####%%eeoo**!!::...........:!*o%
&&&&&&####%%eeoo**!!::..........:!*o
&&&&&&###%%%eeoo**!!::......::!*oe
&&&&&###%%%eeoo**!!!!:::!!!*o%
&&&&###%%%eeoooo****ooe%
&&####%%%%%%%#
</pre>
 
=={{header|J}}==
{{Trans|Python}}
 
<syntaxhighlight lang="j">
<lang J>
load'graphics/viewmat'
mag =: +/&.:*:"1
Line 920 ⟶ 1,203:
env=.(2; 0.5; (norm _50 30 50))
sph=. 20 20 0; 20; 1 1 _6; 20
'rgb' viewmat togray env draw_sphere sph</langsyntaxhighlight>
 
=={{header|Java}}==
{{libheader|JavaFX}}
<langsyntaxhighlight Javalang="java">import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.geometry.Point3D;
Line 1,138 ⟶ 1,421:
 
}
</syntaxhighlight>
</lang>
===Using Java 11===
Alternatively, without using JavaFX, which has been removed from the JavaJDK since version 11.
<syntaxhighlight lang="java">
 
import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.List;
 
import javax.imageio.ImageIO;
 
public final class DeathStar {
 
public static void main(String[] aArgs) throws IOException {
Vector direction = new Vector(20.0, -40.0, -10.0);
direction.normalise();
Sphere positive = new Sphere(0, 0, 0, 120);
Sphere negative = new Sphere(-90, -90, -30, 100);
 
BufferedImage image = deathStar(positive, negative, direction, 1.5, 0.5);
ImageIO.write(image, "png", new File("DeathStarJava.png"));
}
private static BufferedImage deathStar(
Sphere aPositive, Sphere aNegative, Vector aDirection, double aShadow, double aBrightness) {
final int width = aPositive.radius * 4;
final int height = aPositive.radius * 3;
BufferedImage result = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics graphics = result.getGraphics();
graphics.setColor(Color.CYAN);
graphics.fillRect(0, 0, width, height);
Vector ray = new Vector(0.0, 0.0, 0.0);
final int deltaX = aPositive.x - width / 2;
final int deltaY = aPositive.y - height / 2;
 
double xMax = aPositive.x + aPositive.radius;
double yMax = aPositive.y + aPositive.radius;
for ( int y = aPositive.y - aPositive.radius; y < yMax; y++ ) {
for ( int x = aPositive.x - aPositive.radius; x < xMax; x++ ) {
List<Object> contacts = aPositive.contact(x, y);
final double zb1 = (double) contacts.get(0);
final int zb2 = (int) contacts.get(1);
final boolean positiveHit = (boolean) contacts.get(2);
if ( ! positiveHit ) {
continue;
}
contacts = aNegative.contact(x, y);
final double zs1 = (double) contacts.get(0);
final int zs2 = (int) contacts.get(1);
boolean negativeHit = (boolean) contacts.get(2);
if ( negativeHit ) {
if ( zs1 > zb1 ) {
negativeHit = false;
} else if ( zs2 > zb2 ) {
continue;
}
}
if ( negativeHit ) {
ray.x = aNegative.x - x;
ray.y = aNegative.y - y;
ray.z = aNegative.z - zs2;
} else {
ray.x = x - aPositive.x;
ray.y = y - aPositive.y;
ray.z = zb1 - aPositive.z;
}
ray.normalise();
double rayComponent = ray.scalarProduct(aDirection);
if ( rayComponent < 0 ) {
rayComponent = 0;
}
int color = (int) ( 255 * ( Math.pow(rayComponent, aShadow) + aBrightness) / ( 1 + aBrightness ) );
if ( color < 0 ) {
color = 0;
} else if ( color > 255 ) {
color = 255;
}
result.setRGB(x - deltaX, y - deltaY, color);
}
}
return result;
}
private static class Vector {
public Vector(double aX, double aY, double aZ) {
x = aX; y = aY; z = aZ;
}
public double scalarProduct(Vector aOther) {
return x * aOther.x + y * aOther.y + z * aOther.z;
}
public Vector normalise() {
final double magnitude = Math.sqrt(this.scalarProduct(this));
return new Vector(x /= magnitude, y /= magnitude, z /= magnitude);
}
private double x, y, z;
}
private static class Sphere {
public Sphere(int aX, int aY, int aZ, int aRadius) {
x = aX; y = aY; z = aZ; radius = aRadius;
}
public List<Object> contact(int aX, int aY) {
final int xx = aX - x;
final int yy = aY - y;
final int zSquared = radius * radius - ( xx * xx + yy * yy );
if ( zSquared >= 0 ) {
final double zz = Math.sqrt(zSquared);
return List.of(z - zz, z, true);
}
return List.of( 0.0, 0, false );
}
private int x, y, z, radius;
}
 
}
</syntaxhighlight>
{{ out }}
[[Media:DeathStarJava.png]]
 
=={{header|JavaScript}}==
Layer circles and gradients to achieve result similar to that of the Wikipedia page for the [http://en.wikipedia.org/wiki/Death_Star Death Star].
<syntaxhighlight lang="javascript">
<lang JavaScript>
<!DOCTYPE html>
<html>
Line 1,185 ⟶ 1,600:
</html>
 
</syntaxhighlight>
</lang>
 
=={{header|Julia}}==
<langsyntaxhighlight lang="julia"># run in REPL
using MakieGLMakie
 
function deathstar()
Line 1,202 ⟶ 1,617:
scene = Scene(backgroundcolor=:black)
surface!(scene, x, y, z, color = rand(RGBAf0, 124, 124), show_axis=false)
return scene
end
 
scene = deathstar()
</syntaxhighlight>
</lang>
 
=={{header|LSL}}==
Rez a box on the ground, raise it up a few meters, add the following as a New Script.
<langsyntaxhighlight LSLlang="lsl">default {
state_entry() {
llSetPrimitiveParams([PRIM_NAME, "RosettaCode DeathStar"]);
Line 1,222 ⟶ 1,638:
llSetPrimitiveParams([PRIM_OMEGA, <0.0, 0.0, 1.0>, 1.0, 1.0]);
}
}</langsyntaxhighlight>
Output:
[[File:Death_Star_LSL.jpg|200px|Death Star]]
 
=={{header|Lua}}==
{{trans|C}}
<syntaxhighlight lang="lua">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)</syntaxhighlight>
{{out}}
<pre style="font-size:50%"> @@@%%%%%%%%%#########%
@@@@@%%%%%%#######&&&&&&&&&&&&&&&&&&##
@@@@@@%%%%%%######&&&&&&&eeeeeeeeeeeeeeeeeeeee&&
@@@@@@@@@@@@@@@@@@@&&&&&&eeeeeeeoooooooooooooooooooooeee&
@@@@@&####%%%%@@@@@@@@@@@@%eeeeoooooooo*******************oooee
@@@@eeee&&&&####%%%@@@@@@@@@@@@%oooooo********!!!!!!!!!!!!!!*****oooe
@@@**ooooeeee&&&####%%%@@@@@@@@@@@%oo*******!!!!!!!!!!!!!!!!!!!!!!!****oo&
@@@!!!****ooooeee&&&###%%%%@@@@@@@@@@%*****!!!!!!!!:::::::::::::::::!!!!!**ooe
@@@:::!!!!!****oooeee&&###%%%%@@@@@@@@@%***!!!!!!!::::::::::::::::::::::::!!!***oe
@@@@::::::::!!!***oooeee&&&##%%%%@@@@@@@@@**!!!!!!!:::::::::............::::::!!!**oo
@@@.......::::!!!!***ooeee&&###%%%@@@@@@@@@*!!!!!!::::::::..................:::::!!!**oe
%@@@@.........::::!!!**oooee&&&##%%%@@@@@@@@*!!!!!!::::::::......................::::!!!*oe
%@@@@...........:::!!!***ooeee&&###%%%@@@@@@**!!!!!!:::::::........................::::!!!*oo
%@@@@@...........:::!!!***ooeee&&###%%@@@@@@***!!!!!!:::::::.........................::::!!!*oe
@@@@@@..........::::!!!**oooee&&&##%%%@@@@@****!!!!!!:::::::..........................::::!!**oe
%@@@@@@::::...:::::!!!!***ooeee&&###%%@@@@o*****!!!!!!:::::::..........................::::!!!**o
@@@@@@@@!!!:::::!!!!!***oooee&&&##%%%@@oooo******!!!!!!:::::::.........................:::::!!**oe
%@@@@@@@@@o****!******ooooeee&&###%%%eeeooooo*****!!!!!!!:::::::........................::::!!!**oe
%@@@@@@@@@@@eeoooooooeeeee&&&##%%%&eeeeeeooooo*****!!!!!!!::::::::.....................:::::!!!**oo&
%@@@@@@@@@@@@@@@@##&&&#####%###&&&&&eeeeeoooooo******!!!!!!:::::::::..................:::::!!!!**oe&
%@@@@@@@@@@@@@@@@@@@%%%%%%######&&&&&eeeeeoooooo******!!!!!!!:::::::::::...........:::::::!!!!***oe&
%%@@@@@@@@@@@@@@@@@@@%%%%%%######&&&&&eeeeeeooooo*******!!!!!!!::::::::::::::::::::::::::!!!!***ooe&
#%@@@@@@@@@@@@@@@@@@@%%%%%%%######&&&&&eeeeeeoooooo*******!!!!!!!!::::::::::::::::::::!!!!!!***ooee
%%@@@@@@@@@@@@@@@@@@@%%%%%%%######&&&&&&eeeeeeoooooo*******!!!!!!!!!!!!::::::::::!!!!!!!!****ooee&
#%@@@@@@@@@@@@@@@@@@@@%%%%%%%######&&&&&&eeeeeeooooooo*********!!!!!!!!!!!!!!!!!!!!!!!!****oooee&
%%@@@@@@@@@@@@@@@@@@@@@%%%%%%%######&&&&&&eeeeeeeooooooo**********!!!!!!!!!!!!!!!*******ooooee&#
&%%@@@@@@@@@@@@@@@@@@@@@%%%%%%%#######&&&&&&eeeeeeeooooooooo*************************oooooeee&#
#%%@@@@@@@@@@@@@@@@@@@@@@%%%%%%%#######&&&&&&&eeeeeeeooooooooooo****************ooooooeeee&&#
&%%@@@@@@@@@@@@@@@@@@@@@@%%%%%%%%#######&&&&&&&&eeeeeeeeeoooooooooooooooooooooooooeeeee&&##
#%%@@@@@@@@@@@@@@@@@@@@@@%%%%%%%%########&&&&&&&&eeeeeeeeeeeeoooooooooooooeeeeeeee&&&##%
#%%@@@@@@@@@@@@@@@@@@@@@@@%%%%%%%%%########&&&&&&&&&&eeeeeeeeeeeeeeeeeeeeeeee&&&&&##%
#%%@@@@@@@@@@@@@@@@@@@@@@@@%%%%%%%%%#########&&&&&&&&&&&&&&&&eeeee&&&&&&&&&&####%%
#%%@@@@@@@@@@@@@@@@@@@@@@@@@%%%%%%%%%%###########&&&&&&&&&&&&&&&&&&&&######%%%
#%%@@@@@@@@@@@@@@@@@@@@@@@@@@%%%%%%%%%%%#############################%%%%@
#%%@@@@@@@@@@@@@@@@@@@@@@@@@@@@%%%%%%%%%%%%%%%###############%%%%%%%@
#%%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%%%%%%%%%%%%%%%%%%%%%%%%%%%@@@
#%%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%%%%%%%%@@@@@@@@@
%%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@</pre>
 
=={{header|Maple}}==
<langsyntaxhighlight Maplelang="maple">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)</langsyntaxhighlight>
 
=={{header|Mathematica}} / {{header|Wolfram Language}}==
<langsyntaxhighlight Mathematicalang="mathematica">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]</langsyntaxhighlight>
 
=={{header|Nim}}==
Line 1,245 ⟶ 1,747:
The result is written in a PNG file. For this purpose, we used the modules “bitmap” and “grayscale_image” created for the tasks “Bitmap” and “Grayscale image”. To write the PNG file, we use the third party library “nimPNG”.
 
<langsyntaxhighlight Nimlang="nim">import math
 
import bitmap, grayscale_image, nimPNG
Line 1,334 ⟶ 1,836:
for color in rgbImage.pixels:
data.add([color.r, color.g, color.b])
echo savePNG24("death_star.png", data, rgbImage.w, rgbImage.h)</langsyntaxhighlight>
 
=={{header|Openscad}}==
<langsyntaxhighlight lang="openscad">// We are performing geometric subtraction
 
difference() {
Line 1,355 ⟶ 1,857:
sphere(40);
}
}</langsyntaxhighlight>
 
=={{header|Perl}}==
[[file:death-star-perl.png|thumb]]
Writes a PGM to stdout.
<langsyntaxhighlight lang="perl">use strict;
 
sub sq {
Line 1,434 ⟶ 1,936:
}
 
draw(2, 0.2);</langsyntaxhighlight>
 
=={{header|Phix}}==
{{trans|Go}}
{{libheader|Phix/pGUI}}
{{libheader|Phix/online}}
<lang Phix>-- demo\rosetta\DeathStar.exw
You can run this online [http://phix.x10.mx/p2js/deathstar.htm here]. Note it is rather slow to redraw fullscreen.
include pGUI.e
<!--<syntaxhighlight lang="phix">(phixonline)-->
 
<span style="color: #000080;font-style:italic;">--
Ihandle dlg, canvas
-- demo\rosetta\DeathStar.exw
cdCanvas cddbuffer, cdcanvas
-- ==========================
 
--
function dot(sequence x, sequence y)
-- Translated from Go.
return sum(sq_mul(x,y))
--</span>
end function
<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>
function normalize(sequence v)
atom len = sqrt(dot(v, v))
if len=0 then return {0,0,0} end if
return sq_mul(v,1/len)
end function
 
enum X,Y,Z
 
function hit(sequence s, atom x, y, atom r)
x -= s[X]
y -= s[Y]
atom zsq := r*r - (x*x + y*y)
if zsq >= 0 then
atom zsqrt := sqrt(zsq)
return {s[Z] - zsqrt, s[Z] + zsqrt, true}
end if
return {0, 0, false}
end function
<span style="color: #008080;">constant</span> <span style="color: #000000;">title</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"Death Star"</span>
procedure deathStar(integer width, height, atom k, atom amb, sequence direction)
<span style="color: #004080;">Ihandle</span> <span style="color: #000000;">dlg</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">canvas</span>
integer lum
<span style="color: #004080;">cdCanvas</span> <span style="color: #000000;">cddbuffer</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">cdcanvas</span>
sequence vec
integer r = floor((min(width,height)-40)/2)
integer cx = floor(width/2)
integer cy = floor(height/2)
sequence pos = {0,0,0},
neg = {r*-3/4,r*-3/4,r*-1/4}
 
for y = pos[Y]-r to pos[Y]+r do
for x = pos[X]-r to pos[X]+r do
atom {zb1, zb2, hit1} := hit(pos, x, y, r)
if hit1 then
atom {zs1, zs2, hit2} := hit(neg, x, y, r/2)
if not hit2 or zs2<=zb2 then
if hit2 and zs1<=zb1 then
vec = {neg[X] - x, neg[Y] - y, neg[Z] - zs2}
else
vec = {x - pos[X], y - pos[Y], zb1 - pos[Z]}
-- vec = {x, y, zb1}
end if
atom s = dot(direction, normalize(vec))
lum = and_bits(#FF,255*(iff(s<0?0:power(s,k))+amb)/(1+amb))
lum += lum*#100+lum*#10000
cdCanvasPixel(cddbuffer, cx+x, cy-y, lum)
end if
end if
end for
end for
end procedure
<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>
function redraw_cb(Ihandle /*ih*/, integer /*posx*/, integer /*posy*/)
<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>
integer {width, height} = IupGetIntInt(canvas, "DRAWSIZE")
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
cdCanvasActivate(cddbuffer)
cdCanvasClear(cddbuffer)
<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>
deathStar(width, height, 1.5, 0.2, normalize({20, -40, -10}))
<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>
cdCanvasFlush(cddbuffer)
<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>
return IUP_DEFAULT
<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>
end function
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
 
function map_cb(Ihandle ih)
<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>
cdcanvas = cdCreateCanvas(CD_IUP, ih)
cddbuffer = cdCreateCanvas(CD_DBUFFER, cdcanvas)
<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>
cdCanvasSetBackground(cddbuffer, CD_BLACK)
<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>
return IUP_DEFAULT
<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>
end function
<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>
procedure main()
<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>
IupOpen()
<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>
canvas = IupCanvas(NULL)
<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>
IupSetAttribute(canvas, "RASTERSIZE", "340x340") -- initial size
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
IupSetCallback(canvas, "MAP_CB", Icallback("map_cb"))
 
<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>
dlg = IupDialog(canvas)
IupSetAttribute(dlg, "TITLE", "Draw a sphere")
<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>
IupSetCallback(canvas, "ACTION", Icallback("redraw_cb"))
<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>
IupMap(dlg)
<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>
IupSetAttribute(canvas, "RASTERSIZE", NULL) -- release the minimum limitation
<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>
IupShowXY(dlg,IUP_CENTER,IUP_CENTER)
<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>
IupMainLoop()
<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>
IupClose()
end procedure
<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>
main()</lang>
<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 &lt; 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>
<!--</syntaxhighlight>-->
 
=={{header|POV-Ray}}==
<langsyntaxhighlight POV-Raylang="pov">camera { perspective location <0.0 , .8 ,-3.0> look_at 0
aperture .1 blur_samples 20 variance 1/100000 focal_point 0}
Line 1,552 ⟶ 2,084:
finish { phong 1 reflection {0.10 metallic 0.5} }
}
} </langsyntaxhighlight>
[[image:PovRay-deathstar.jpg]]
 
=={{header|Python}}==
{{trans|C}}
<langsyntaxhighlight lang="python">import sys, math, collections
 
Sphere = collections.namedtuple("Sphere", "cx cy cz r")
Line 1,623 ⟶ 2,155:
 
light = normalize(V3(-50, 30, 50))
draw_sphere(2, 0.5, light)</langsyntaxhighlight>
 
=={{header|Q}}==
write an image in BMP format:
<syntaxhighlight lang="q">
<lang Q>
/ https://en.wikipedia.org/wiki/BMP_file_format
/ BITMAPINFOHEADER / RGB24
Line 1,670 ⟶ 2,202:
/ fn:`:demo.bmp;
/ writebmp[w;h;fcn;fn];
</syntaxhighlight>
</lang>
 
Create the death star image:
 
<syntaxhighlight lang="q">
<lang Q>
w:400; h:300; r:150; l:-0.5 0.7 0.5
sqrt0:{$[x>0;sqrt x;0]};
Line 1,714 ⟶ 2,246:
writebmp[w;h;fcn;fn];
 
</langsyntaxhighlight>(converted to JPG ...)
 
[[image:qdstar.jpg]]
 
=={{header|Racket}}==
<langsyntaxhighlight lang="racket">
#lang racket
(require plot)
Line 1,729 ⟶ 2,261:
#:y-min -1/2 #:y-max 1/2
#:z-min 0 #:z-max 1)
</syntaxhighlight>
</lang>
[[File:death-star.png]]
 
Line 1,737 ⟶ 2,269:
{{works with|Rakudo|2018.10}}
[[File:Deathstar-perl6.png|thumb]]
<syntaxhighlight lang="raku" perl6line>class sphere {
has $.cx; # center x coordinate
has $.cy; # center y coordinate
Line 1,823 ⟶ 2,355:
$z = $sphere.cz - $z2 .. $sphere.cz + $z2;
True;
}</langsyntaxhighlight>
 
=={{header|REXX}}==
Line 1,829 ⟶ 2,361:
 
(Apologies for the comments making the lines so wide, but it was easier to read and compare to the original &nbsp; '''D''' &nbsp; source.)
<langsyntaxhighlight lang="rexx">/*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. */
Line 1,882 ⟶ 2,414:
if @\='' then say strip(@, 'T') /*strip trailing blanks from line. */
end /*i*/ /* [↑] show all lines for sphere. */
return</langsyntaxhighlight>
{{out|output|text=&nbsp; when using the internal default input:}}
(Shown at &nbsp; <big>'''<sup>1</sup>/<sub>2</sub>'''</big> &nbsp; size.)
Line 1,929 ⟶ 2,461:
 
=={{header|Set lang}}==
<langsyntaxhighlight lang="set_lang">set ! 32
set ! 32
set ! 46
Line 1,988 ⟶ 2,520:
set ! 46
set ! 45
set ! 126</langsyntaxhighlight>
Outputs:
<pre> .-~""~-.
Line 2,000 ⟶ 2,532:
{{trans|Perl}}
Writes a PGM to stdout.
<langsyntaxhighlight lang="ruby">func hitf(sph, x, y) {
x -= sph[0]
y -= sph[1]
Line 2,061 ⟶ 2,593:
}
 
draw(2, 0.2)</langsyntaxhighlight>
Output image: [https://github.com/trizen/rc/blob/master/img/death_star_sidef.png here].
 
Line 2,067 ⟶ 2,599:
{{trans|C}}
Note that this code has a significant amount of refactoring relative to the C version, including the addition of specular reflections and the separation of the scene code from the raytracing from the rendering.
<langsyntaxhighlight lang="tcl">package require Tcl 8.5
 
proc normalize vec {
Line 2,181 ⟶ 2,713:
}
}
textDeathStar 3 10 0.7 0.3</langsyntaxhighlight>
Output:
<pre>
Line 2,228 ⟶ 2,760:
{{libheader|Tk}}
[[File:Deathstar-tcl.gif|200px|thumb|Rendering of the Death Star by the Tcl solution.]]
<langsyntaxhighlight lang="tcl"># Render as a picture (with many hard-coded settings)
package require Tk
proc guiDeathStar {photo diff spec lightBrightness ambient} {
Line 2,245 ⟶ 2,777:
}
pack [label .l -image [image create photo ds]]
guiDeathStar ds 3 10 0.7 0.3</langsyntaxhighlight>
 
=={{header|VBScript}}==
ASCII graphics. Should be invoked with cscript. Modified from LUA
<syntaxhighlight lang="vb">
'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
</syntaxhighlight>
{{out}}
<pre>
####&&&&&&&&&&&&
%%######&&&&eeeeeeeeooooooooee&&
%%%%####&&&&eeeeeeoooooo************ooee
%%%%####%%%%%%eeoooooo******!!!!!!!!!!!!**oo
%%%%ee&&&&####%%%%%%##oo****!!!!!!!!::::::::!!!!**oo
%%%%ooooeeee&&####%%%%%%##**!!!!!!::::::::::::::::!!!!oo
%%%%!!****ooee&&&&##%%%%%%##!!!!::::::::............::::!!**
%%%%::::!!****ooee&&####%%%%%%&&!!::::....................::!!oo
%%....::::!!**ooooee&&##%%%%%%##::::........................::!!
%%........::::!!**ooee&&####%%%%##::::..........................::!!
##%%..........::!!**ooee&&&&##%%%%##::..............................::oo
%%%%..........::!!!!**ooee&&##%%%%::::..............................::!!
##%%..............::!!**ooee&&##%%%%::::................................::oo
##%%..............::!!**ooee&&##%%%%::::................................::**
%%%%............::::!!**oo&&&&##%%!!::::................................::!!
%%%%............::!!**ooee&&##%%!!!!::::..................................!!
##%%%%%%........::::!!**ooee&&##**!!!!::::..................................::**
##%%%%%%!!::::::!!!!**ooee&&##****!!!!::::..................................::**
##%%%%%%%%**********ooee&&##oo****!!!!!!::::................................::**
##%%%%%%%%%%##eeeeee&&eeeeeeoooo****!!!!::::..............................::!!**
##%%%%%%%%%%######&&&&&&eeeeoooo****!!!!::::::............................::!!**
##%%%%%%%%%%%%######&&&&eeeeoooo******!!!!::::::..........................::!!oo
&&##%%%%%%%%%%######&&&&eeeeeeoooo****!!!!!!::::::......................::::!!oo
&&##%%%%%%%%%%######&&&&&&eeeeoooooo****!!!!!!::::::..................::::!!**ee
##%%%%%%%%%%%%######&&&&eeeeeeoooo******!!!!!!::::::::..........::::::!!!!**
##%%%%%%%%%%%%######&&&&&&eeeeeeoooo******!!!!!!::::::::::::::::::::!!!!**oo
&&##%%%%%%%%%%%%######&&&&&&eeeeoooooo******!!!!!!!!::::::::::::!!!!!!**ooee
ee##%%%%%%%%%%%%########&&&&eeeeeeoooooo********!!!!!!!!!!!!!!!!!!!!****oo&&
&&##%%%%%%%%%%%%######&&&&&&eeeeeeoooooo**********!!!!!!!!!!!!******ooee
ee##%%%%%%%%%%%%%%######&&&&&&eeeeeeoooooooo********************ooooee&&
&&##%%%%%%%%%%%%########&&&&&&&&eeeeeeoooooooooo********ooooooooee&&
####%%%%%%%%%%%%########&&&&&&&&eeeeeeeeooooooooooooooooooeeee&&
ee##%%%%%%%%%%%%%%##########&&&&&&&&eeeeeeeeeeeeeeeeeeeeeeee&&##
&&##%%%%%%%%%%%%%%%%########&&&&&&&&&&eeeeeeeeeeeeee&&&&&&##
&&##%%%%%%%%%%%%%%%%##########&&&&&&&&&&&&&&&&&&&&&&####
&&##%%%%%%%%%%%%%%%%%%##############&&&&&&&&######%%
####%%%%%%%%%%%%%%%%%%######################
&&##%%%%%%%%%%%%%%%%%%%%%%%%######%%%%%%
&&##%%%%%%%%%%%%%%%%%%%%%%%%%%%%
##%%%%%%%%%%%%%%
</pre>
 
=={{header|Wren}}==
{{trans|Go}}
{{libheader|DOME}}
<langsyntaxhighlight ecmascriptlang="wren">import "dome" for Window
import "graphics" for Canvas, Color, ImageData
import "math" for Vector
Line 2,353 ⟶ 3,014:
}
 
var Game = DeathStar.new(400, 400)</langsyntaxhighlight>
 
=={{header|Yabasic}}==
<langsyntaxhighlight Yabasiclang="yabasic">open window 100,100
window origin "cc"
backcolor 0,0,0
Line 2,511 ⟶ 3,172:
draw_sphere(2, .3)
wend
</syntaxhighlight>
</lang>
=={{header|Zig}}==
{{trans|C}}
Primitive ray tracing. Writes a PGM to stdout.
<syntaxhighlight lang="zig">
const std = @import("std");
const Allocator = std.mem.Allocator;
</syntaxhighlight>
<syntaxhighlight lang="zig">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();
}</syntaxhighlight>
<syntaxhighlight lang="zig">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;
}
};
}</syntaxhighlight>
<syntaxhighlight lang="zig">
fn SphereHit(comptime T: type) type {
return struct { z1: T, z2: T };
}</syntaxhighlight>
<syntaxhighlight lang="zig">
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;
const zsq = self.r * self.r - x * x - y * y;
if (zsq >= 0) {
const zsqrt = std.math.sqrt(zsq);
return .{ .z1 = self.cz - zsqrt, .z2 = self.cz + zsqrt };
}
return null;
}
};
}</syntaxhighlight>
<syntaxhighlight lang="zig">
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;
 
const w: usize = @intFromFloat(pos.r * 4);
const 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;
}
}
};
}</syntaxhighlight>
<syntaxhighlight lang="zig">
const Gray = struct {
w: u8,
const black = Gray{ .w = 0 };
};</syntaxhighlight>
<syntaxhighlight lang="zig">
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 });
}
}
};
}</syntaxhighlight>
12

edits