The Death Star is a type of fictional mobile space station and galactic superweapon featured in the Star Wars space opera franchise. The first Death Star is stated to be more than 100 km to 160 km in diameter, depending on source. It is crewed by an estimated 1.7 million military personnel and 400,000 droids
Every row of the sphere is a chord found with the Pythagorean theorem, cut at random into dashes.
javascript·death-star.js
const canvas = document.getElementById('c');
const ctx = canvas.getContext('2d');
const size = window.innerWidth;
const dpr = window.devicePixelRatio;
const s = size * dpr;
canvas.width = s;
canvas.height = s;
ctx.scale(dpr, dpr);
ctx.lineWidth = 8;
ctx.lineCap = 'round';
const center = s / 4;
const radius = s / 4;
const gap = 20;
const step = radius / gap;
const start = center - radius - (step / 2);
const end = center + radius + (step / 2);
const blockGap = s / 30;
/* Pythagorean theorem */
const pyT = y => Math.sqrt(Math.pow(radius, 2) - Math.pow(y, 2))
let y, half;
const points = [];
for (let index = start; index <= end; index = index + step) {
y = index;
half = pyT(center - y);
if (Number.isNaN(half)) {
continue;
}
points.push({
from: center - half + 10,
to: center + half - 10,
y
})
}
const getRandomArbitrary = (max, min = 0) => Math.floor(Math.random() * (max - min + 1)) + min;
const splitToNums = (from, to) => {
let n = to - from;
const a = [];
let s;
while (n > 0) {
s = getRandomArbitrary(n)
a.push(s);
n -= s;
}
return a;
}
const shuffle = a => {
for (let i = a.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[a[i], a[j]] = [a[j], a[i]];
}
return a;
}
const limit = (v = []) => {
const c = [];
for (let index = 0; index < v.length; index++) {
if (v[index] < blockGap) {
if (index === 0) {
c.push(v[index]);
} else {
c[0] = c[0] + v[index];
}
} else {
c[c.length] = v[index]
}
}
return c;
}
const splitToBlocks = p => {
const {
from,
to,
y
} = p;
const blox = shuffle(limit(splitToNums(from, to)));
return {
froms: [from, ...blox.map(v => Math.round(v + from))],
tos: [...blox.map(v => {
const s = Math.round(v + from - blockGap);
return s < from ? from : s;
}), to],
y
}
}
let blocks;
points.forEach((p, index) => {
const {
froms,
tos,
y
} = splitToBlocks(p);
for (let i = 0; i < froms.length; i++) {
ctx.moveTo(froms[i], y);
ctx.lineTo(tos[i], y);
ctx.stroke();
}
});