---
title: "Death Star · generative art"
description: "Built with canvas and trigonometry. Generative art plate #1 by Theodore Vorillas, drawn live in your browser from its code."
url: "https://vorillaz.com/lab/2d-death-star"
---

![](https://vorillaz.com/_astro/2d-death-star.DQXU9nw6_Z3nXnX.svg)

fig. #01 · rendered live in your browser from the code below

# #01 death star

Built with canvas and trigonometry.

- date

  2019.02.01

- tags

  generative-art · javascript

- fork

  - [jsfiddle ↗](https://jsfiddle.net/z4bq2x0g/)
  - [codepen ↗](https://codepen.io/TheodoreVorillas/pen/VgbzGJ)

> 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

## The algorithm

Every row of the sphere is a chord found with the Pythagorean theorem, cut at random into dashes.

```javascript title="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();
  }
});
```
