Last active
June 2, 2024 23:10
-
-
Save Perlkonig/25a9ffd67bbf40faec649f5b174c94c5 to your computer and use it in GitHub Desktop.
A TypeScript implementation of Castux's code for generating conical projections of hexagonal rhombus boards (https://gist.github.com/Castux/ee792e2631716ec0041aa2732d142a4b)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
type Vertex = [number,number]; | |
type Hex = Vertex[]; | |
const narrow = true; // Change this to toggle between the base and narrow versions | |
const size = 14; // board height; width = height - 1 | |
const baseHex: Hex = []; | |
const s32 = Math.sqrt(3) / 2; | |
const rad = 1 / Math.sqrt(3); | |
for (let i = 0; i < 6; i++) { | |
const alpha = (i + 0.5) * 2 * Math.PI / 6; | |
baseHex.push([rad * Math.cos(alpha), rad * Math.sin(alpha)]) | |
} | |
const hexes: Hex[] = []; | |
for (let x = 1; x < size; x++) { | |
for (let y = 0; y < size; y++) { | |
const yshift = narrow ? 0.5 : -0.5; | |
const dx = x + yshift * y; | |
const dy = s32 * y; | |
const hex: Hex = []; | |
for (let i = 0; i < 6; i++) { | |
hex.push([baseHex[i][0] + dx, baseHex[i][1] + dy]); | |
} | |
hexes.push(hex); | |
} | |
} | |
const toSegments = (hex: Hex): Vertex[] => { | |
const coords: Vertex[] = []; | |
for (let i = 0; i < 6; i++) { | |
const a = hex[i]; | |
const b = hex[(i + 1) % 6]; | |
const steps = 15; | |
for (let j = 0; j <= steps; j++) { | |
const s = j / steps; | |
coords.push([(1 - s) * a[0] + s * b[0], (1 - s) * a[1] + s * b[1]]); | |
} | |
} | |
return coords; | |
} | |
const fold = (p: Vertex, factor: number): Vertex => { | |
const d = Math.sqrt(p[0]**2 + p[1]**2); | |
let a = Math.atan2(p[1], p[0]); | |
a = a * factor; | |
const x = d * Math.cos(a); | |
const y = d * Math.sin(a); | |
return [x,y]; | |
} | |
const truncate = (n: number): number => { | |
return Math.round(n * 100) / 100; | |
} | |
const svg: string[] = []; | |
const factor = narrow ? 6 : 3; | |
const scale = 20; | |
const allCoords: Vertex[] = []; | |
for (const hex of hexes) { | |
const coords: Vertex[] = []; | |
for (const pt of toSegments(hex)) { | |
const folded = fold(pt, factor); | |
coords.push([truncate(scale * folded[0]), truncate(scale * folded[1])]); | |
} | |
allCoords.push(...coords); | |
svg.push(`<polygon points="${coords.map(pt => pt.join(",")).join(" ")}" stroke="black" stroke-width="1" fill="none" />`) | |
} | |
svg.push(`</svg>`); | |
const minx = Math.min(...allCoords.map(pt => pt[0])); | |
const maxx = Math.max(...allCoords.map(pt => pt[0])); | |
const miny = Math.min(...allCoords.map(pt => pt[1])); | |
const maxy = Math.max(...allCoords.map(pt => pt[1])); | |
const width = maxx - minx; | |
const height = maxy - miny; | |
const buffer = 5; | |
svg.unshift(`<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" viewBox="${minx - buffer} ${miny - buffer} ${width + (buffer * 2)} ${height + (buffer * 2)}">`); | |
console.log(svg.join("\n")); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment