import { DEG_180, DEG_270, DEG_360, DEG_90 } from './conts' import { NemiCurve, getBoundsOfNemiCurves, scaleNemiCurve, translateNemiCurve } from './nemiCurve' export type NemiShape = { inner: { elements: NemiCurve[] } outer: { elements: NemiCurve[] } } const range = (n: number) => { return Array.from({ length: n }, (_, i) => i) } export const specialNemiShape2: NemiShape = { inner: { elements: [ { type: 'line', startPoint: { x: -20, y: 0 }, endPoint: { x: -50, y: -20 }, }, ], }, outer: { elements: [ { type: 'line', startPoint: { x: -24, y: 0 }, endPoint: { x: -54, y: -20 }, }, ], }, } export const specialNemiShape: NemiShape = { inner: { elements: [ { type: "line", startPoint: { x: -182.5, y: -217.5, }, endPoint: { x: 182.5, y: -217.5, }, }, { type: "bezier", startPoint: { x: 182.5, y: -217.5, }, controlPoint1: { x: 302.62199999999996, y: -217.5, }, controlPoint2: { x: 400, y: -120.1219, }, endPoint: { x: 400, y: 0, }, }, { type: "bezier", startPoint: { x: 400, y: 0, }, controlPoint1: { x: 400, y: 120.12200000000001, }, controlPoint2: { x: 302.62199999999996, y: 217.5, }, endPoint: { x: 182.5, y: 217.5, }, }, { type: "line", startPoint: { x: 182.5, y: 217.5, }, endPoint: { x: -182.5, y: 217.5, }, }, { type: "bezier", startPoint: { x: -182.5, y: 217.5, }, controlPoint1: { x: -302.6219, y: 217.5, }, controlPoint2: { x: -400, y: 120.12200000000001, }, endPoint: { x: -400, y: 0, }, }, { type: "bezier", startPoint: { x: -400, y: 0, }, controlPoint1: { x: -400, y: -120.1219, }, controlPoint2: { x: -302.6219, y: -217.5, }, endPoint: { x: -182.5, y: -217.5, }, }, ], }, outer: { elements: [ { type: "line", startPoint: { x: -182.5, y: -276.5, }, endPoint: { x: 182.5, y: -276.5, }, }, { type: "bezier", startPoint: { x: 182.5, y: -276.5, }, controlPoint1: { x: 335.207, y: -276.5, }, controlPoint2: { x: 459, y: -152.707, }, endPoint: { x: 459, y: 0, }, }, { type: "bezier", startPoint: { x: 459, y: 0, }, controlPoint1: { x: 459, y: 152.707, }, controlPoint2: { x: 335.207, y: 276.5, }, endPoint: { x: 182.5, y: 276.5, }, }, { type: "line", startPoint: { x: 182.5, y: 276.5, }, endPoint: { x: -182.5, y: 276.5, }, }, { type: "bezier", startPoint: { x: -182.5, y: 276.5, }, controlPoint1: { x: -335.207, y: 276.5, }, controlPoint2: { x: -459, y: 152.707, }, endPoint: { x: -459, y: 0, }, }, { type: "bezier", startPoint: { x: -459, y: 0, }, controlPoint1: { x: -459, y: -152.707, }, controlPoint2: { x: -335.207, y: -276.5, }, endPoint: { x: -182.5, y: -276.5, }, }, ], }, } export const specialNemiShape_2: NemiShape = { inner: { elements: [ { type: 'arc', centerPoint: { x: 0, y: 0 }, startAngle: -DEG_90, radians: DEG_270, radius: 20, }, { type: 'line', startPoint: { x: -20, y: 0 }, endPoint: { x: -20, y: -20 }, }, { type: 'bezier', startPoint: { x: -20, y: -20 }, controlPoint1: { x: -15, y: -30 }, controlPoint2: { x: -5, y: -35 }, endPoint: { x: 10, y: -30 }, }, ], }, outer: { elements: [ { type: 'arc', centerPoint: { x: 0, y: 0 }, startAngle: -DEG_90, radians: DEG_270, radius: 24, }, { type: 'line', startPoint: { x: -24, y: 0 }, endPoint: { x: -24, y: -20 }, }, { type: 'bezier', startPoint: { x: -24, y: -20 }, controlPoint1: { x: -20, y: -35 }, controlPoint2: { x: -5, y: -40 }, endPoint: { x: 10, y: -34 }, }, ], }, } export const centerNemiCurves = (nemiCurves: NemiCurve[]): NemiCurve[] => { const bounds = getBoundsOfNemiCurves(nemiCurves) console.log('bounds: ', bounds); return nemiCurves.map((curve) => translateNemiCurve(curve, { dx: -bounds.xCenter, dy: -bounds.yCenter, }), ) } // const second = centerNemiCurves( // fromDPath( // 'M0.5 277C0.5 124.293 124.293 0.5 277 0.5H642C794.707 0.5 918.5 124.293 918.5 277C918.5 429.707 794.707 553.5 642 553.5H277C124.293 553.5 0.5 429.707 0.5 277Z', // ), // ) // export const specialNemiShape: NemiShape = { // inner: { // elements: centerNemiCurves( // fromDPath( // 'M218 0.5H583C703.122 0.5 800.5 97.8781 800.5 218C800.5 338.122 703.122 435.5 583 435.5H218C97.8781 435.5 0.5 338.122 0.5 218C0.5 97.8781 97.8781 0.5 218 0.5Z', // ), // ), // }, // outer: { // elements: [...second.slice(1), second[0]], // }, // } export const getCircularNemiShape = ({ withWideLanes }: { withWideLanes: boolean }): NemiShape => { const innerRadius = withWideLanes ? 50 : 61 return { inner: { elements: [ { type: 'arc', centerPoint: { x: 0, y: 0 }, startAngle: -DEG_90, radians: DEG_360, radius: innerRadius, }, ], }, outer: { elements: [ { type: 'arc', centerPoint: { x: 0, y: 0 }, startAngle: -DEG_90, radians: DEG_360, radius: 100, }, ], }, } } export const getLineNemiShape = ({ width, numberOfLanes }: { width: number; numberOfLanes: number }): NemiShape => { const minHeightForEachLane = 200 const maxHeight = 600 const height = Math.min(numberOfLanes * minHeightForEachLane, maxHeight) return { inner: { elements: [ { type: 'line', startPoint: { x: 0, y: 0 }, endPoint: { x: width, y: 0 }, }, ], }, outer: { elements: [ { type: 'line', startPoint: { x: 0, y: -height }, endPoint: { x: width, y: -height }, }, ], }, } } export const getVerticalLineNemiShape = ({ height, numberOfLanes, }: { height: number numberOfLanes: number }): NemiShape => { const minWidthForEachLane = 200 const maxWidth = 600 const widthToUse = Math.min(numberOfLanes * minWidthForEachLane, maxWidth) return { inner: { elements: [ { type: 'line', startPoint: { x: -widthToUse / 2, y: 0 }, endPoint: { x: -widthToUse / 2, y: height }, }, ], }, outer: { elements: [ { type: 'line', startPoint: { x: widthToUse / 2, y: 0 }, endPoint: { x: widthToUse / 2, y: height }, }, ], }, } } export const getWideNemiShape = ({ width, height, withWideLanes, }: { width: number height: number withWideLanes: boolean }): NemiShape => { if (height > width) { return getCircularNemiShape({ withWideLanes }) } const extraSpace = width - height const sideWidth = height / 2 const outerRadius = sideWidth const laneWidth = (withWideLanes ? 0.6 : 0.4) * outerRadius const innerRadius = outerRadius - laneWidth const innerElements = [ { type: 'arc', centerPoint: { x: extraSpace + sideWidth, y: 0 }, startAngle: -DEG_90, radians: DEG_180, radius: innerRadius, }, { type: 'line', startPoint: { x: extraSpace + sideWidth, y: innerRadius }, endPoint: { x: sideWidth, y: innerRadius }, }, { type: 'arc', centerPoint: { x: sideWidth, y: 0 }, startAngle: DEG_90, radians: DEG_180, radius: innerRadius, }, { type: 'line', startPoint: { x: sideWidth, y: -innerRadius }, endPoint: { x: extraSpace + sideWidth, y: -innerRadius }, }, ] as const const outerElements: NemiCurve[] = [ { ...innerElements[0], radius: outerRadius, }, { ...innerElements[1], startPoint: { ...innerElements[1].startPoint, y: outerRadius, }, endPoint: { ...innerElements[1].endPoint, y: outerRadius, }, }, { ...innerElements[2], radius: outerRadius, }, { ...innerElements[3], startPoint: { ...innerElements[3].startPoint, y: -outerRadius, }, endPoint: { ...innerElements[3].endPoint, y: -outerRadius, }, }, ] return { inner: { elements: innerElements as unknown as NemiCurve[], }, outer: { elements: outerElements, }, } } export function scaleNemiShape(nemiShape: NemiShape, scale: number): NemiShape { return { inner: { elements: nemiShape.inner.elements.map((element) => scaleNemiCurve(element, scale)), }, outer: { elements: nemiShape.outer.elements.map((element) => scaleNemiCurve(element, scale)), }, } } export const getEx1NemiShape = ({ width, height }: { width: number; height: number }): NemiShape => { const columns = 4 const rows = 4 const widthEach = (width / columns) * 0.9 const heightEach = (height / rows) * 0.6 return { inner: { elements: range(columns).flatMap((columnI) => range(rows).map((rowI) => { const x = (columnI / columns) * width const y = (rowI / rows) * height return { type: 'line', startPoint: { x, y: y + heightEach }, endPoint: { x: x + widthEach, y: y + heightEach }, } }), ), }, outer: { elements: range(columns).flatMap((columnI) => range(rows).map((rowI) => { const x = (columnI / columns) * width const y = (rowI / rows) * height return { type: 'line', startPoint: { x, y }, endPoint: { x: x + widthEach, y: y }, } }), ), }, } } export const getSpecial2Shape = ({ width }: { width: number; height: number }): NemiShape => { // the special2 shape is simple, it consists of 1 bezier element that is like the top of a circle const cpDistance = width / 6 const controlPoint1 = { x: cpDistance, y: -200 } const controlPoint2 = { x: width - cpDistance, y: -200 } const endPoint = { x: width, y: 0 } const curve: NemiCurve = { type: 'bezier', startPoint: { x: 0, y: 0 }, controlPoint1, controlPoint2, endPoint, } return { inner: { elements: [curve], }, outer: { elements: [translateNemiCurve(curve, { dx: 0, dy: -100 })], }, } }