Skip to content

Commit

Permalink
feat: add option to chose hexagon orientation
Browse files Browse the repository at this point in the history
  • Loading branch information
JanMalch committed Nov 17, 2020
1 parent eb5261e commit 1265eca
Show file tree
Hide file tree
Showing 5 changed files with 156 additions and 24 deletions.
12 changes: 12 additions & 0 deletions src/App.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
let drawCuttingLines = false;
let drawFoldingLines = false;
let pointyBottom = true;
async function onFilesChange({ detail: fileList }: { detail: File[] }) {
imageElements = []; // make canvas not ready while images are loading
Expand Down Expand Up @@ -85,10 +86,20 @@
</section>

<section>
<label>
<input type="checkbox" bind:checked="{pointyBottom}" />
Y-Symmetric
</label>&nbsp;&nbsp;
<small>(looks better, but has a pointy bottom and thus cannot stand upright)</small>

<br />
<br />

<label>
<input type="checkbox" bind:checked="{drawCuttingLines}" />
Draw cutting lines
</label>
&nbsp;&nbsp;
<label>
<input type="checkbox" bind:checked="{drawFoldingLines}" />
Draw folding lines
Expand Down Expand Up @@ -116,6 +127,7 @@
drawables="{imageElements}"
drawCuttingLines="{drawCuttingLines}"
drawFoldingLines="{drawFoldingLines}"
pointyBottom="{pointyBottom}"
size="{size}"
on:finish="{onFinish}" />
</section>
Expand Down
29 changes: 21 additions & 8 deletions src/components/Canvas.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,24 @@
import {
extractRotatedTriangle,
triangleSelectors,
triangleSelectorsFlatSides,
} from '../drawing/processing';
import { magicAngle } from '../formulas/content';
import { degreeToRadian } from '../formulas/math';
import { downwardTriangle, upwardTriangle } from '../shapes';
import {
downwardTriangle,
leftwardTriangle,
rightwardTriangle,
upwardTriangle,
} from '../shapes';
import type { Point } from '../types';
export let drawables: HTMLImageElement[] = [];
export let size: number;
export let drawCuttingLines: boolean;
export let drawFoldingLines: boolean;
export let pointyBottom: boolean;
export let canvas: HTMLCanvasElement | null = null;
export let drawCuttingLines = false;
export let drawFoldingLines = false;
const dispatch = createEventDispatcher();
Expand All @@ -33,29 +40,35 @@
drawables.every((d) => d instanceof HTMLImageElement);
if (imagesAvailable) {
const usedSelectors = pointyBottom
? triangleSelectorsFlatSides
: triangleSelectors;
const triangles = pointyBottom
? [leftwardTriangle, rightwardTriangle]
: [downwardTriangle, upwardTriangle];
const allTriangleSetups = drawables.map((drawable) =>
Array(6)
.fill(0)
.map((_, i) => {
return {
image: drawable,
clippingTriangle:
i % 2 === 0 ? downwardTriangle : upwardTriangle,
...triangleSelectors[i],
clippingTriangle: triangles[i % 2],
...usedSelectors[i],
};
})
);
for (let line = 0; line < allTriangleSetups.length; line++) {
const triangleSetups = allTriangleSetups[line];
for (let i = 0; i < triangleSelectors.length; i++) {
for (let i = 0; i < 6; i++) {
const setup = triangleSetups[i];
const result = extractRotatedTriangle(
size,
setup.image,
setup.clippingTriangle,
setup.relativeRectangle,
setup.rotation
setup.rotation,
pointyBottom
);
onProcessingFinish(result, line, i);
}
Expand Down
124 changes: 110 additions & 14 deletions src/drawing/processing.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { magicHeight } from '../formulas/content';
import { magicSize } from '../formulas/content';
import { degreeToRadian } from '../formulas/math';
import type { NaturalImage, ProcessingOptions, Rectangle, RectangleDef, TriangleDef } from '../types';
import { drawImage, inClip } from './utils';

/**
* Options to find and rotate the individual triangles in the hexagon from the image.
* The hexagon is rotated so that the flat sides face up- or downwards.
*/
export const triangleSelectors: ProcessingOptions[] = [
{
Expand All @@ -13,7 +14,7 @@ export const triangleSelectors: ProcessingOptions[] = [
x: 0,
y: 0.5,
width: 0.5,
height: magicHeight,
height: magicSize,
},
rotation: (canvas, prev) => {
const ctx = canvas.getContext('2d')!;
Expand All @@ -26,9 +27,9 @@ export const triangleSelectors: ProcessingOptions[] = [
// A1
relativeRectangle: {
x: 0,
y: 0.5 - magicHeight,
y: 0.5 - magicSize,
width: 0.5,
height: magicHeight,
height: magicSize,
},
rotation: (canvas, prev) => {
const ctx = canvas.getContext('2d')!;
Expand All @@ -47,9 +48,9 @@ export const triangleSelectors: ProcessingOptions[] = [
},
relativeRectangle: {
x: 0.25,
y: 0.5 - magicHeight,
y: 0.5 - magicSize,
width: 0.5,
height: magicHeight,
height: magicSize,
},
},
{
Expand All @@ -61,9 +62,9 @@ export const triangleSelectors: ProcessingOptions[] = [
},
relativeRectangle: {
x: 0.5,
y: 0.5 - magicHeight,
y: 0.5 - magicSize,
width: 0.5,
height: magicHeight,
height: magicSize,
},
},
{
Expand All @@ -78,7 +79,7 @@ export const triangleSelectors: ProcessingOptions[] = [
x: 0.5,
y: 0.5,
width: 0.5,
height: magicHeight,
height: magicSize,
},
},
{
Expand All @@ -93,11 +94,104 @@ export const triangleSelectors: ProcessingOptions[] = [
x: 0.25,
y: 0.5,
width: 0.5,
height: magicHeight,
height: magicSize,
},
},
];

/**
* Options to find and rotate the individual triangles in the hexagon from the image.
* The hexagon is rotated so that the flat sides face to the left or right.
*/
export const triangleSelectorsFlatSides: ProcessingOptions[] = [
{
// A0
relativeRectangle: {
x: 0.5 - magicSize,
y: 0,
width: magicSize,
height: 0.5,
},
rotation: (canvas, prev) => {
const ctx = canvas.getContext('2d')!;
ctx.drawImage(prev, 0, 0);
},
},
{
// A1
relativeRectangle: {
x: 0.5,
y: 0,
width: magicSize,
height: 0.5,
},
rotation: (canvas, prev) => {
const ctx = canvas.getContext('2d')!;
ctx.drawImage(prev, 0, 0);
},
},
{
// A2
rotation: (canvas, prev) => {
const ctx = canvas.getContext('2d')!;
ctx.translate(0, canvas.height / 2);
ctx.rotate(degreeToRadian(-120));
ctx.drawImage(prev, canvas.width * -1, 0);
},
relativeRectangle: {
x: 0.5,
y: 0.25,
width: magicSize,
height: 0.5,
},
},
{
// A3
rotation: (canvas, prev) => {
const ctx = canvas.getContext('2d')!;
ctx.translate(canvas.width, canvas.height / 2);
ctx.rotate(degreeToRadian(-120));
ctx.drawImage(prev, 0, canvas.height * -1);
},
relativeRectangle: {
x: 0.5,
y: 0.5,
width: magicSize,
height: 0.5,
},
},
{
// A4
rotation: (canvas, prev) => {
const ctx = canvas.getContext('2d')!;
ctx.translate(canvas.width, 0);
ctx.rotate(degreeToRadian(120));
ctx.drawImage(prev, 0, canvas.height / -2);
},
relativeRectangle: {
x: 0.5 - magicSize,
y: 0.5,
width: magicSize,
height: 0.5,
},
},
{
// A5
rotation: (canvas, prev) => {
const ctx = canvas.getContext('2d')!;
ctx.rotate(degreeToRadian(120));
ctx.drawImage(prev, 0, canvas.height * -1);
},
relativeRectangle: {
x: 0.5 - magicSize,
y: 0.25,
width: magicSize,
height: 0.5,
},
},
];


function loadIntoTriangleCanvas(
toTriangleCanvas: HTMLCanvasElement,
image: NaturalImage & CanvasImageSource,
Expand Down Expand Up @@ -185,14 +279,16 @@ export function extractRotatedTriangle(size: number,
image: NaturalImage & CanvasImageSource,
clippingTriangle: TriangleDef,
relativeRectangle: Rectangle,
rotation: ProcessingOptions["rotation"]) {
rotation: ProcessingOptions["rotation"],
pointyBottom: boolean) {
const smallerSize = size * (magicSize * 2);
const toTriangleCanvas = createCanvas({
width: size,
height: size * (magicHeight * 2),
width: pointyBottom ? smallerSize : size,
height: pointyBottom ? size : smallerSize,
});
const rotatedTriangleCanvas = createCanvas({
height: size,
width: size * (magicHeight * 2),
width: smallerSize,
});
const scaledRotatedTriangleCanvas = createCanvas({
width: size,
Expand Down
3 changes: 1 addition & 2 deletions src/formulas/content.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,4 @@
* The interior angle at the hypotenuse of an isosceles triangle whose height and width are the same.
*/
export const magicAngle = 63.435;
export const magicHeight = Math.sqrt(3) / 4;
export const magicScale = 2 / Math.sqrt(3);
export const magicSize = Math.sqrt(3) / 4;
12 changes: 12 additions & 0 deletions src/shapes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,15 @@ export const downwardTriangle: TriangleDef = [
{ x: 1, y: 0 },
{ x: 0.5, y: 1 },
];

export const leftwardTriangle: TriangleDef = [
{ x: 0, y: 0.5 },
{ x: 1, y: 1 },
{ x: 1, y: 0 },
];

export const rightwardTriangle: TriangleDef = [
{ x: 0, y: 0 },
{ x: 1, y: 0.5 },
{ x: 0, y: 1 },
];

0 comments on commit 1265eca

Please sign in to comment.