diff --git a/posts/2023/06/flam3/0-utility.tsx b/posts/2023/06/flam3/0-utility.tsx new file mode 100644 index 0000000..556f4cb --- /dev/null +++ b/posts/2023/06/flam3/0-utility.tsx @@ -0,0 +1,36 @@ +import React, { useEffect, useRef } from "react"; + +export type renderFn = (image: ImageData) => void; + +export const Canvas: React.FC<{ f: renderFn }> = ({ f }) => { + const canvasRef = useRef(null); + let image: ImageData | null = null; + useEffect(() => { + if (canvasRef.current) { + const canvas = canvasRef.current; + const ctx = canvas.getContext("2d"); + + if (!ctx) { + return; + } + + if ( + !image || + image.width !== canvas.width || + image.height !== canvas.height + ) { + image = ctx.createImageData(canvas.width, canvas.height); + } + + f(image); + + ctx.putImageData(image, 0, 0); + } + }); + + return ; +}; + +export function randomInteger(min: number, max: number) { + return Math.floor(Math.random() * (max - min)) + min; +} diff --git a/posts/2023/06/flam3/1-gasket.ts b/posts/2023/06/flam3/1-gasket.ts new file mode 100644 index 0000000..6da9bac --- /dev/null +++ b/posts/2023/06/flam3/1-gasket.ts @@ -0,0 +1,61 @@ +import { randomInteger, renderFn } from "./0-utility"; + +const ITER = 100_000; + +function plot(x: number, y: number, image: ImageData) { + // A trivial `plot` implementation would take the range [-1, 1], + // shift it to [0, 2], then scale by the width or height + // as appropriate: + // pixelX = Math.floor((x + 1) * image.width / 2) + // pixelY = Math.floor((y + 1) * image.height / 2) + // + // However, that produces a mirror image (across both X and Y) + // from the paper. We'll invert X and Y to compensate. + // Second, because the gasket solution only contains points in + // the range [0, 1), the naive plot above would waste 75% of + // the pixels available. We'll keep the shift by 1 (to compensate + // for mirroring X and Y), but scale by the full image width or + // height so we'll plot the specific quadrant we care about. + var pixelX = Math.floor((-x + 1) * image.width); + var pixelY = Math.floor((-y + 1) * image.height); + + // Now translate the (x, y) pixel coordinates to a buffer index + // and paint it black: + const index = pixelY * (image.width * 4) + pixelX * 4; + + image.data[index + 0] = 0; + image.data[index + 1] = 0; + image.data[index + 2] = 0; + image.data[index + 3] = 0xff; +} + +type Xform = (x: number, y: number) => [number, number]; + +export const gasket: renderFn = (image) => { + const F: Xform[] = [ + (x, y) => { + return [x / 2, y / 2]; + }, + (x, y) => { + return [(x + 1) / 2, y / 2]; + }, + (x, y) => { + return [x / 2, (y + 1) / 2]; + }, + ]; + + let x = Math.random() * 2 - 1; + let y = Math.random() * 2 - 1; + + // Heuristic for iteration count + const iter = image.height * image.width; + + for (var i = 0; i < iter; i++) { + const Fi = randomInteger(0, F.length); + [x, y] = F[Fi](x, y); + + if (i >= 20) { + plot(x, y, image); + } + } +}; diff --git a/posts/2023/06/flam3/2-variations.ts b/posts/2023/06/flam3/2-variations.ts new file mode 100644 index 0000000..685c8fd --- /dev/null +++ b/posts/2023/06/flam3/2-variations.ts @@ -0,0 +1,142 @@ +import { randomInteger } from "./0-utility"; + +type Variation = (x: number, y: number) => [number, number]; + +const r = (x: number, y: number) => { + return Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)); +}; +const theta = (x: number, y: number) => { + return Math.atan2(x, y); +}; + +const linear: Variation = (x, y) => { + return [x, y]; +}; + +const swirl: Variation = (x, y) => { + const r2 = Math.pow(r(x, y), 2); + const sinR2 = Math.sin(r2); + const cosR2 = Math.cos(r2); + + return [x * sinR2 - y * cosR2, x * cosR2 + y * sinR2]; +}; + +const polar: Variation = (x, y) => { + return [theta(x, y) / Math.PI, r(x, y) - 1]; +}; + +const disc: Variation = (x, y) => { + const thetaOverPi = theta(x, y) / Math.PI; + const piR = Math.PI * r(x, y); + return [thetaOverPi * Math.sin(piR), thetaOverPi * Math.cos(piR)]; +}; + +const variations = [linear, swirl, polar, disc]; + +class Coefs { + constructor( + public readonly a: number, + public readonly b: number, + public readonly c: number, + public readonly d: number, + public readonly e: number, + public readonly f: number + ) {} +} + +class Transform { + constructor( + public readonly weight: number, + public readonly coefs: Coefs, + // Assumes that we have a blend for each variation + public readonly blend: number[] + ) {} + + apply(x: number, y: number) { + const variationX = this.coefs.a * x + this.coefs.b * y + this.coefs.c; + const variationY = this.coefs.d * x + this.coefs.e * y + this.coefs.f; + + var transformX = 0; + var transformY = 0; + this.blend.forEach((blend, i) => { + const [perVarX, perVarY] = variations[i](variationX, variationY); + transformX += blend * perVarX; + transformY += blend * perVarY; + }); + + return [transformX, transformY]; + } +} + +function plot(x: number, y: number, image: ImageData) { + const pixelX = Math.floor(((x + 2) * image.width) / 4); + const pixelY = Math.floor(((y + 2) * image.height) / 4); + + if ( + pixelX < 0 || + pixelX > image.width || + pixelY < 0 || + pixelY > image.height + ) { + return; + } + + const index = pixelY * (image.width * 4) + pixelX * 4; + + image.data[index + 0] = 0; + image.data[index + 1] = 0; + image.data[index + 2] = 0; + image.data[index + 3] = 0xff; +} + +function render(transforms: Transform[], image: ImageData) { + const weightSum = transforms.reduce((val, xform) => val + xform.weight, 0); + + var x = Math.random() * 2 - 1; + var y = Math.random() * 2 - 1; + + const iter = 100_000; + for (var i = 0; i < iter; i++) { + // Find the tranform we're operating on + + /* + var f = Math.random() * weightSum; + + var transform = transforms[0]; + transforms.forEach((xform, j) => { + if (f > 0 && f < xform.weight) { + console.log(`xform=${j}`); + transform = xform; + f -= xform.weight; + } + }); + */ + // HACK: Currently assuming weights are equal + const transform = transforms[randomInteger(0, transforms.length)]; + + // Play the chaos game + [x, y] = transform.apply(x, y); + + if (i > 20) { + plot(x, y, image); + } + } +} + +export function renderBaseline(image: ImageData) { + return render( + [ + new Transform( + 0.5, + new Coefs(0.982996, 0, -0.219512, 0, 0.982996, -0.1875), + [1, 0, 0, -0.934] + ), + new Transform( + 0.5, + new Coefs(0.966511, -0.256624, 0.050305, 0.256624, 0.966511, -0.235518), + [0, 0.156, 0.778, 0] + ), + ], + image + ); +} diff --git a/posts/2023/06/flam3/baseline.bak b/posts/2023/06/flam3/baseline.bak new file mode 100644 index 0000000..3fe5737 --- /dev/null +++ b/posts/2023/06/flam3/baseline.bak @@ -0,0 +1,230 @@ + + + + + + 7886955967864652763240672432611E2D5D192757172255 + 11224F0D1D410F1A39101E350F202C0F1F23101B1E0C161C + 08151A060E14040A12040D13050D12060C11050D12050D11 + 050B0F05080F05080D04080C04080E050912040A18030C25 + 0410350616450A1E560F2362122768172B63192B5D162959 + 13234F1020420B1E3C0B1B380D19300E1A280D18200C191E + 0D1C200F1C1E0D1A1D0A171E0B171C0B1119070A15040611 + 03050E01050C00060C01060C03090D061213081516071012 + 0813160B1420081022060C24050926040728020528010429 + 00042F060B3B0C124717255A22396D3B4E815564955D6F9B + 667AA28593AC7A8799707B875F6A784F59694751643F4A60 + 2633602534622536651D3162162D60162B5D16295B15275E + 182B6324386D3F517F5A6B927686A992A1C1A5B1CAB8C2D4 + E4EAF3EEF3F8F9FCFDFBFCFDFEFCFDFEFCFDFEFDFDFCFDFF + F5F7FBE1E6EED2D6E2C3C7D6B9BFD5AFB8D5B2B8D3B6B9D2 + CCD1E6DADEEAE8EBEEE3EAEFDFEAF1D8E3EBD1DDE6BACAD8 + 9DB0D28199BF7790B56E87AC6C84A66B82A05C72934A5B7B + 2935531F2D451626381525351524321625341727371A2B44 + 2536563B4D8955689E6F84B37A90BF869DCCA3B6D7B9C6DF + CAD6E7C5CDDDC0C4D3BCC1CDB9BFC7B1B6C0ACB3BFB2BBC1 + BCC2C6D8DEE1E2E7EBECF0F5EDF1F6EFF3F8E9EFF7DDE3EF + BAC0D8ABB1D19CA3CA98A1CA949FCB8E9BD097A2D5A9B3E2 + BBC6EADFE4F4E3EAF7E8F1FBE8F3FADEE9EECAD8E4B3C3D9 + 8D9AAB808DA474809E737D9A737B977178925F6D9A4E5E95 + 4552841B2D611524540F1C47091236080F2A080D22070C20 + 11162D151E3A1A26482332532C3E5E42567557688B71839F + 8C9AB0BDC6C9BEC7C9C0C9CAC9C9C6C7CAC4B4BFB9A9AEA9 + 9499A09198A08E97A1929C9D939FA08F9CA5899397767F82 + 586873343A51272F491B2542141B360E142C0A0F250B0D20 + 0B12270E152E1119351721461D2A5622316127387126397C + 22367C253581222F7E1D2C7722317E333B824A5289636FA2 + ACB3D0BAC1DAC8D0E4D5E1E7D8E3E2D0DBDBB7C8C69AA8AC + + + + + + + 7886955967864652763240672432611E2D5D192757172255 + 11224F0D1D410F1A39101E350F202C0F1F23101B1E0C161C + 08151A060E14040A12040D13050D12060C11050D12050D11 + 050B0F05080F05080D04080C04080E050912040A18030C25 + 0410350616450A1E560F2362122768172B63192B5D162959 + 13234F1020420B1E3C0B1B380D19300E1A280D18200C191E + 0D1C200F1C1E0D1A1D0A171E0B171C0B1119070A15040611 + 03050E01050C00060C01060C03090D061213081516071012 + 0813160B1420081022060C24050926040728020528010429 + 00042F060B3B0C124717255A22396D3B4E815564955D6F9B + 667AA28593AC7A8799707B875F6A784F59694751643F4A60 + 2633602534622536651D3162162D60162B5D16295B15275E + 182B6324386D3F517F5A6B927686A992A1C1A5B1CAB8C2D4 + E4EAF3EEF3F8F9FCFDFBFCFDFEFCFDFEFCFDFEFDFDFCFDFF + F5F7FBE1E6EED2D6E2C3C7D6B9BFD5AFB8D5B2B8D3B6B9D2 + CCD1E6DADEEAE8EBEEE3EAEFDFEAF1D8E3EBD1DDE6BACAD8 + 9DB0D28199BF7790B56E87AC6C84A66B82A05C72934A5B7B + 2935531F2D451626381525351524321625341727371A2B44 + 2536563B4D8955689E6F84B37A90BF869DCCA3B6D7B9C6DF + CAD6E7C5CDDDC0C4D3BCC1CDB9BFC7B1B6C0ACB3BFB2BBC1 + BCC2C6D8DEE1E2E7EBECF0F5EDF1F6EFF3F8E9EFF7DDE3EF + BAC0D8ABB1D19CA3CA98A1CA949FCB8E9BD097A2D5A9B3E2 + BBC6EADFE4F4E3EAF7E8F1FBE8F3FADEE9EECAD8E4B3C3D9 + 8D9AAB808DA474809E737D9A737B977178925F6D9A4E5E95 + 4552841B2D611524540F1C47091236080F2A080D22070C20 + 11162D151E3A1A26482332532C3E5E42567557688B71839F + 8C9AB0BDC6C9BEC7C9C0C9CAC9C9C6C7CAC4B4BFB9A9AEA9 + 9499A09198A08E97A1929C9D939FA08F9CA5899397767F82 + 586873343A51272F491B2542141B360E142C0A0F250B0D20 + 0B12270E152E1119351721461D2A5622316127387126397C + 22367C253581222F7E1D2C7722317E333B824A5289636FA2 + ACB3D0BAC1DAC8D0E4D5E1E7D8E3E2D0DBDBB7C8C69AA8AC + + + + + + + 7886955967864652763240672432611E2D5D192757172255 + 11224F0D1D410F1A39101E350F202C0F1F23101B1E0C161C + 08151A060E14040A12040D13050D12060C11050D12050D11 + 050B0F05080F05080D04080C04080E050912040A18030C25 + 0410350616450A1E560F2362122768172B63192B5D162959 + 13234F1020420B1E3C0B1B380D19300E1A280D18200C191E + 0D1C200F1C1E0D1A1D0A171E0B171C0B1119070A15040611 + 03050E01050C00060C01060C03090D061213081516071012 + 0813160B1420081022060C24050926040728020528010429 + 00042F060B3B0C124717255A22396D3B4E815564955D6F9B + 667AA28593AC7A8799707B875F6A784F59694751643F4A60 + 2633602534622536651D3162162D60162B5D16295B15275E + 182B6324386D3F517F5A6B927686A992A1C1A5B1CAB8C2D4 + E4EAF3EEF3F8F9FCFDFBFCFDFEFCFDFEFCFDFEFDFDFCFDFF + F5F7FBE1E6EED2D6E2C3C7D6B9BFD5AFB8D5B2B8D3B6B9D2 + CCD1E6DADEEAE8EBEEE3EAEFDFEAF1D8E3EBD1DDE6BACAD8 + 9DB0D28199BF7790B56E87AC6C84A66B82A05C72934A5B7B + 2935531F2D451626381525351524321625341727371A2B44 + 2536563B4D8955689E6F84B37A90BF869DCCA3B6D7B9C6DF + CAD6E7C5CDDDC0C4D3BCC1CDB9BFC7B1B6C0ACB3BFB2BBC1 + BCC2C6D8DEE1E2E7EBECF0F5EDF1F6EFF3F8E9EFF7DDE3EF + BAC0D8ABB1D19CA3CA98A1CA949FCB8E9BD097A2D5A9B3E2 + BBC6EADFE4F4E3EAF7E8F1FBE8F3FADEE9EECAD8E4B3C3D9 + 8D9AAB808DA474809E737D9A737B977178925F6D9A4E5E95 + 4552841B2D611524540F1C47091236080F2A080D22070C20 + 11162D151E3A1A26482332532C3E5E42567557688B71839F + 8C9AB0BDC6C9BEC7C9C0C9CAC9C9C6C7CAC4B4BFB9A9AEA9 + 9499A09198A08E97A1929C9D939FA08F9CA5899397767F82 + 586873343A51272F491B2542141B360E142C0A0F250B0D20 + 0B12270E152E1119351721461D2A5622316127387126397C + 22367C253581222F7E1D2C7722317E333B824A5289636FA2 + ACB3D0BAC1DAC8D0E4D5E1E7D8E3E2D0DBDBB7C8C69AA8AC + + + + + + + 7886955967864652763240672432611E2D5D192757172255 + 11224F0D1D410F1A39101E350F202C0F1F23101B1E0C161C + 08151A060E14040A12040D13050D12060C11050D12050D11 + 050B0F05080F05080D04080C04080E050912040A18030C25 + 0410350616450A1E560F2362122768172B63192B5D162959 + 13234F1020420B1E3C0B1B380D19300E1A280D18200C191E + 0D1C200F1C1E0D1A1D0A171E0B171C0B1119070A15040611 + 03050E01050C00060C01060C03090D061213081516071012 + 0813160B1420081022060C24050926040728020528010429 + 00042F060B3B0C124717255A22396D3B4E815564955D6F9B + 667AA28593AC7A8799707B875F6A784F59694751643F4A60 + 2633602534622536651D3162162D60162B5D16295B15275E + 182B6324386D3F517F5A6B927686A992A1C1A5B1CAB8C2D4 + E4EAF3EEF3F8F9FCFDFBFCFDFEFCFDFEFCFDFEFDFDFCFDFF + F5F7FBE1E6EED2D6E2C3C7D6B9BFD5AFB8D5B2B8D3B6B9D2 + CCD1E6DADEEAE8EBEEE3EAEFDFEAF1D8E3EBD1DDE6BACAD8 + 9DB0D28199BF7790B56E87AC6C84A66B82A05C72934A5B7B + 2935531F2D451626381525351524321625341727371A2B44 + 2536563B4D8955689E6F84B37A90BF869DCCA3B6D7B9C6DF + CAD6E7C5CDDDC0C4D3BCC1CDB9BFC7B1B6C0ACB3BFB2BBC1 + BCC2C6D8DEE1E2E7EBECF0F5EDF1F6EFF3F8E9EFF7DDE3EF + BAC0D8ABB1D19CA3CA98A1CA949FCB8E9BD097A2D5A9B3E2 + BBC6EADFE4F4E3EAF7E8F1FBE8F3FADEE9EECAD8E4B3C3D9 + 8D9AAB808DA474809E737D9A737B977178925F6D9A4E5E95 + 4552841B2D611524540F1C47091236080F2A080D22070C20 + 11162D151E3A1A26482332532C3E5E42567557688B71839F + 8C9AB0BDC6C9BEC7C9C0C9CAC9C9C6C7CAC4B4BFB9A9AEA9 + 9499A09198A08E97A1929C9D939FA08F9CA5899397767F82 + 586873343A51272F491B2542141B360E142C0A0F250B0D20 + 0B12270E152E1119351721461D2A5622316127387126397C + 22367C253581222F7E1D2C7722317E333B824A5289636FA2 + ACB3D0BAC1DAC8D0E4D5E1E7D8E3E2D0DBDBB7C8C69AA8AC + + + + + + + 7886955967864652763240672432611E2D5D192757172255 + 11224F0D1D410F1A39101E350F202C0F1F23101B1E0C161C + 08151A060E14040A12040D13050D12060C11050D12050D11 + 050B0F05080F05080D04080C04080E050912040A18030C25 + 0410350616450A1E560F2362122768172B63192B5D162959 + 13234F1020420B1E3C0B1B380D19300E1A280D18200C191E + 0D1C200F1C1E0D1A1D0A171E0B171C0B1119070A15040611 + 03050E01050C00060C01060C03090D061213081516071012 + 0813160B1420081022060C24050926040728020528010429 + 00042F060B3B0C124717255A22396D3B4E815564955D6F9B + 667AA28593AC7A8799707B875F6A784F59694751643F4A60 + 2633602534622536651D3162162D60162B5D16295B15275E + 182B6324386D3F517F5A6B927686A992A1C1A5B1CAB8C2D4 + E4EAF3EEF3F8F9FCFDFBFCFDFEFCFDFEFCFDFEFDFDFCFDFF + F5F7FBE1E6EED2D6E2C3C7D6B9BFD5AFB8D5B2B8D3B6B9D2 + CCD1E6DADEEAE8EBEEE3EAEFDFEAF1D8E3EBD1DDE6BACAD8 + 9DB0D28199BF7790B56E87AC6C84A66B82A05C72934A5B7B + 2935531F2D451626381525351524321625341727371A2B44 + 2536563B4D8955689E6F84B37A90BF869DCCA3B6D7B9C6DF + CAD6E7C5CDDDC0C4D3BCC1CDB9BFC7B1B6C0ACB3BFB2BBC1 + BCC2C6D8DEE1E2E7EBECF0F5EDF1F6EFF3F8E9EFF7DDE3EF + BAC0D8ABB1D19CA3CA98A1CA949FCB8E9BD097A2D5A9B3E2 + BBC6EADFE4F4E3EAF7E8F1FBE8F3FADEE9EECAD8E4B3C3D9 + 8D9AAB808DA474809E737D9A737B977178925F6D9A4E5E95 + 4552841B2D611524540F1C47091236080F2A080D22070C20 + 11162D151E3A1A26482332532C3E5E42567557688B71839F + 8C9AB0BDC6C9BEC7C9C0C9CAC9C9C6C7CAC4B4BFB9A9AEA9 + 9499A09198A08E97A1929C9D939FA08F9CA5899397767F82 + 586873343A51272F491B2542141B360E142C0A0F250B0D20 + 0B12270E152E1119351721461D2A5622316127387126397C + 22367C253581222F7E1D2C7722317E333B824A5289636FA2 + ACB3D0BAC1DAC8D0E4D5E1E7D8E3E2D0DBDBB7C8C69AA8AC + + + + + + + 7886955967864652763240672432611E2D5D192757172255 + 11224F0D1D410F1A39101E350F202C0F1F23101B1E0C161C + 08151A060E14040A12040D13050D12060C11050D12050D11 + 050B0F05080F05080D04080C04080E050912040A18030C25 + 0410350616450A1E560F2362122768172B63192B5D162959 + 13234F1020420B1E3C0B1B380D19300E1A280D18200C191E + 0D1C200F1C1E0D1A1D0A171E0B171C0B1119070A15040611 + 03050E01050C00060C01060C03090D061213081516071012 + 0813160B1420081022060C24050926040728020528010429 + 00042F060B3B0C124717255A22396D3B4E815564955D6F9B + 667AA28593AC7A8799707B875F6A784F59694751643F4A60 + 2633602534622536651D3162162D60162B5D16295B15275E + 182B6324386D3F517F5A6B927686A992A1C1A5B1CAB8C2D4 + E4EAF3EEF3F8F9FCFDFBFCFDFEFCFDFEFCFDFEFDFDFCFDFF + F5F7FBE1E6EED2D6E2C3C7D6B9BFD5AFB8D5B2B8D3B6B9D2 + CCD1E6DADEEAE8EBEEE3EAEFDFEAF1D8E3EBD1DDE6BACAD8 + 9DB0D28199BF7790B56E87AC6C84A66B82A05C72934A5B7B + 2935531F2D451626381525351524321625341727371A2B44 + 2536563B4D8955689E6F84B37A90BF869DCCA3B6D7B9C6DF + CAD6E7C5CDDDC0C4D3BCC1CDB9BFC7B1B6C0ACB3BFB2BBC1 + BCC2C6D8DEE1E2E7EBECF0F5EDF1F6EFF3F8E9EFF7DDE3EF + BAC0D8ABB1D19CA3CA98A1CA949FCB8E9BD097A2D5A9B3E2 + BBC6EADFE4F4E3EAF7E8F1FBE8F3FADEE9EECAD8E4B3C3D9 + 8D9AAB808DA474809E737D9A737B977178925F6D9A4E5E95 + 4552841B2D611524540F1C47091236080F2A080D22070C20 + 11162D151E3A1A26482332532C3E5E42567557688B71839F + 8C9AB0BDC6C9BEC7C9C0C9CAC9C9C6C7CAC4B4BFB9A9AEA9 + 9499A09198A08E97A1929C9D939FA08F9CA5899397767F82 + 586873343A51272F491B2542141B360E142C0A0F250B0D20 + 0B12270E152E1119351721461D2A5622316127387126397C + 22367C253581222F7E1D2C7722317E333B824A5289636FA2 + ACB3D0BAC1DAC8D0E4D5E1E7D8E3E2D0DBDBB7C8C69AA8AC + + + diff --git a/posts/2023/06/flam3/baseline.flame b/posts/2023/06/flam3/baseline.flame new file mode 100644 index 0000000..bac3d5c --- /dev/null +++ b/posts/2023/06/flam3/baseline.flame @@ -0,0 +1,230 @@ + + + + + + 7886955967864652763240672432611E2D5D192757172255 + 11224F0D1D410F1A39101E350F202C0F1F23101B1E0C161C + 08151A060E14040A12040D13050D12060C11050D12050D11 + 050B0F05080F05080D04080C04080E050912040A18030C25 + 0410350616450A1E560F2362122768172B63192B5D162959 + 13234F1020420B1E3C0B1B380D19300E1A280D18200C191E + 0D1C200F1C1E0D1A1D0A171E0B171C0B1119070A15040611 + 03050E01050C00060C01060C03090D061213081516071012 + 0813160B1420081022060C24050926040728020528010429 + 00042F060B3B0C124717255A22396D3B4E815564955D6F9B + 667AA28593AC7A8799707B875F6A784F59694751643F4A60 + 2633602534622536651D3162162D60162B5D16295B15275E + 182B6324386D3F517F5A6B927686A992A1C1A5B1CAB8C2D4 + E4EAF3EEF3F8F9FCFDFBFCFDFEFCFDFEFCFDFEFDFDFCFDFF + F5F7FBE1E6EED2D6E2C3C7D6B9BFD5AFB8D5B2B8D3B6B9D2 + CCD1E6DADEEAE8EBEEE3EAEFDFEAF1D8E3EBD1DDE6BACAD8 + 9DB0D28199BF7790B56E87AC6C84A66B82A05C72934A5B7B + 2935531F2D451626381525351524321625341727371A2B44 + 2536563B4D8955689E6F84B37A90BF869DCCA3B6D7B9C6DF + CAD6E7C5CDDDC0C4D3BCC1CDB9BFC7B1B6C0ACB3BFB2BBC1 + BCC2C6D8DEE1E2E7EBECF0F5EDF1F6EFF3F8E9EFF7DDE3EF + BAC0D8ABB1D19CA3CA98A1CA949FCB8E9BD097A2D5A9B3E2 + BBC6EADFE4F4E3EAF7E8F1FBE8F3FADEE9EECAD8E4B3C3D9 + 8D9AAB808DA474809E737D9A737B977178925F6D9A4E5E95 + 4552841B2D611524540F1C47091236080F2A080D22070C20 + 11162D151E3A1A26482332532C3E5E42567557688B71839F + 8C9AB0BDC6C9BEC7C9C0C9CAC9C9C6C7CAC4B4BFB9A9AEA9 + 9499A09198A08E97A1929C9D939FA08F9CA5899397767F82 + 586873343A51272F491B2542141B360E142C0A0F250B0D20 + 0B12270E152E1119351721461D2A5622316127387126397C + 22367C253581222F7E1D2C7722317E333B824A5289636FA2 + ACB3D0BAC1DAC8D0E4D5E1E7D8E3E2D0DBDBB7C8C69AA8AC + + + + + + + 7886955967864652763240672432611E2D5D192757172255 + 11224F0D1D410F1A39101E350F202C0F1F23101B1E0C161C + 08151A060E14040A12040D13050D12060C11050D12050D11 + 050B0F05080F05080D04080C04080E050912040A18030C25 + 0410350616450A1E560F2362122768172B63192B5D162959 + 13234F1020420B1E3C0B1B380D19300E1A280D18200C191E + 0D1C200F1C1E0D1A1D0A171E0B171C0B1119070A15040611 + 03050E01050C00060C01060C03090D061213081516071012 + 0813160B1420081022060C24050926040728020528010429 + 00042F060B3B0C124717255A22396D3B4E815564955D6F9B + 667AA28593AC7A8799707B875F6A784F59694751643F4A60 + 2633602534622536651D3162162D60162B5D16295B15275E + 182B6324386D3F517F5A6B927686A992A1C1A5B1CAB8C2D4 + E4EAF3EEF3F8F9FCFDFBFCFDFEFCFDFEFCFDFEFDFDFCFDFF + F5F7FBE1E6EED2D6E2C3C7D6B9BFD5AFB8D5B2B8D3B6B9D2 + CCD1E6DADEEAE8EBEEE3EAEFDFEAF1D8E3EBD1DDE6BACAD8 + 9DB0D28199BF7790B56E87AC6C84A66B82A05C72934A5B7B + 2935531F2D451626381525351524321625341727371A2B44 + 2536563B4D8955689E6F84B37A90BF869DCCA3B6D7B9C6DF + CAD6E7C5CDDDC0C4D3BCC1CDB9BFC7B1B6C0ACB3BFB2BBC1 + BCC2C6D8DEE1E2E7EBECF0F5EDF1F6EFF3F8E9EFF7DDE3EF + BAC0D8ABB1D19CA3CA98A1CA949FCB8E9BD097A2D5A9B3E2 + BBC6EADFE4F4E3EAF7E8F1FBE8F3FADEE9EECAD8E4B3C3D9 + 8D9AAB808DA474809E737D9A737B977178925F6D9A4E5E95 + 4552841B2D611524540F1C47091236080F2A080D22070C20 + 11162D151E3A1A26482332532C3E5E42567557688B71839F + 8C9AB0BDC6C9BEC7C9C0C9CAC9C9C6C7CAC4B4BFB9A9AEA9 + 9499A09198A08E97A1929C9D939FA08F9CA5899397767F82 + 586873343A51272F491B2542141B360E142C0A0F250B0D20 + 0B12270E152E1119351721461D2A5622316127387126397C + 22367C253581222F7E1D2C7722317E333B824A5289636FA2 + ACB3D0BAC1DAC8D0E4D5E1E7D8E3E2D0DBDBB7C8C69AA8AC + + + + + + + 7886955967864652763240672432611E2D5D192757172255 + 11224F0D1D410F1A39101E350F202C0F1F23101B1E0C161C + 08151A060E14040A12040D13050D12060C11050D12050D11 + 050B0F05080F05080D04080C04080E050912040A18030C25 + 0410350616450A1E560F2362122768172B63192B5D162959 + 13234F1020420B1E3C0B1B380D19300E1A280D18200C191E + 0D1C200F1C1E0D1A1D0A171E0B171C0B1119070A15040611 + 03050E01050C00060C01060C03090D061213081516071012 + 0813160B1420081022060C24050926040728020528010429 + 00042F060B3B0C124717255A22396D3B4E815564955D6F9B + 667AA28593AC7A8799707B875F6A784F59694751643F4A60 + 2633602534622536651D3162162D60162B5D16295B15275E + 182B6324386D3F517F5A6B927686A992A1C1A5B1CAB8C2D4 + E4EAF3EEF3F8F9FCFDFBFCFDFEFCFDFEFCFDFEFDFDFCFDFF + F5F7FBE1E6EED2D6E2C3C7D6B9BFD5AFB8D5B2B8D3B6B9D2 + CCD1E6DADEEAE8EBEEE3EAEFDFEAF1D8E3EBD1DDE6BACAD8 + 9DB0D28199BF7790B56E87AC6C84A66B82A05C72934A5B7B + 2935531F2D451626381525351524321625341727371A2B44 + 2536563B4D8955689E6F84B37A90BF869DCCA3B6D7B9C6DF + CAD6E7C5CDDDC0C4D3BCC1CDB9BFC7B1B6C0ACB3BFB2BBC1 + BCC2C6D8DEE1E2E7EBECF0F5EDF1F6EFF3F8E9EFF7DDE3EF + BAC0D8ABB1D19CA3CA98A1CA949FCB8E9BD097A2D5A9B3E2 + BBC6EADFE4F4E3EAF7E8F1FBE8F3FADEE9EECAD8E4B3C3D9 + 8D9AAB808DA474809E737D9A737B977178925F6D9A4E5E95 + 4552841B2D611524540F1C47091236080F2A080D22070C20 + 11162D151E3A1A26482332532C3E5E42567557688B71839F + 8C9AB0BDC6C9BEC7C9C0C9CAC9C9C6C7CAC4B4BFB9A9AEA9 + 9499A09198A08E97A1929C9D939FA08F9CA5899397767F82 + 586873343A51272F491B2542141B360E142C0A0F250B0D20 + 0B12270E152E1119351721461D2A5622316127387126397C + 22367C253581222F7E1D2C7722317E333B824A5289636FA2 + ACB3D0BAC1DAC8D0E4D5E1E7D8E3E2D0DBDBB7C8C69AA8AC + + + + + + + 7886955967864652763240672432611E2D5D192757172255 + 11224F0D1D410F1A39101E350F202C0F1F23101B1E0C161C + 08151A060E14040A12040D13050D12060C11050D12050D11 + 050B0F05080F05080D04080C04080E050912040A18030C25 + 0410350616450A1E560F2362122768172B63192B5D162959 + 13234F1020420B1E3C0B1B380D19300E1A280D18200C191E + 0D1C200F1C1E0D1A1D0A171E0B171C0B1119070A15040611 + 03050E01050C00060C01060C03090D061213081516071012 + 0813160B1420081022060C24050926040728020528010429 + 00042F060B3B0C124717255A22396D3B4E815564955D6F9B + 667AA28593AC7A8799707B875F6A784F59694751643F4A60 + 2633602534622536651D3162162D60162B5D16295B15275E + 182B6324386D3F517F5A6B927686A992A1C1A5B1CAB8C2D4 + E4EAF3EEF3F8F9FCFDFBFCFDFEFCFDFEFCFDFEFDFDFCFDFF + F5F7FBE1E6EED2D6E2C3C7D6B9BFD5AFB8D5B2B8D3B6B9D2 + CCD1E6DADEEAE8EBEEE3EAEFDFEAF1D8E3EBD1DDE6BACAD8 + 9DB0D28199BF7790B56E87AC6C84A66B82A05C72934A5B7B + 2935531F2D451626381525351524321625341727371A2B44 + 2536563B4D8955689E6F84B37A90BF869DCCA3B6D7B9C6DF + CAD6E7C5CDDDC0C4D3BCC1CDB9BFC7B1B6C0ACB3BFB2BBC1 + BCC2C6D8DEE1E2E7EBECF0F5EDF1F6EFF3F8E9EFF7DDE3EF + BAC0D8ABB1D19CA3CA98A1CA949FCB8E9BD097A2D5A9B3E2 + BBC6EADFE4F4E3EAF7E8F1FBE8F3FADEE9EECAD8E4B3C3D9 + 8D9AAB808DA474809E737D9A737B977178925F6D9A4E5E95 + 4552841B2D611524540F1C47091236080F2A080D22070C20 + 11162D151E3A1A26482332532C3E5E42567557688B71839F + 8C9AB0BDC6C9BEC7C9C0C9CAC9C9C6C7CAC4B4BFB9A9AEA9 + 9499A09198A08E97A1929C9D939FA08F9CA5899397767F82 + 586873343A51272F491B2542141B360E142C0A0F250B0D20 + 0B12270E152E1119351721461D2A5622316127387126397C + 22367C253581222F7E1D2C7722317E333B824A5289636FA2 + ACB3D0BAC1DAC8D0E4D5E1E7D8E3E2D0DBDBB7C8C69AA8AC + + + + + + + 7886955967864652763240672432611E2D5D192757172255 + 11224F0D1D410F1A39101E350F202C0F1F23101B1E0C161C + 08151A060E14040A12040D13050D12060C11050D12050D11 + 050B0F05080F05080D04080C04080E050912040A18030C25 + 0410350616450A1E560F2362122768172B63192B5D162959 + 13234F1020420B1E3C0B1B380D19300E1A280D18200C191E + 0D1C200F1C1E0D1A1D0A171E0B171C0B1119070A15040611 + 03050E01050C00060C01060C03090D061213081516071012 + 0813160B1420081022060C24050926040728020528010429 + 00042F060B3B0C124717255A22396D3B4E815564955D6F9B + 667AA28593AC7A8799707B875F6A784F59694751643F4A60 + 2633602534622536651D3162162D60162B5D16295B15275E + 182B6324386D3F517F5A6B927686A992A1C1A5B1CAB8C2D4 + E4EAF3EEF3F8F9FCFDFBFCFDFEFCFDFEFCFDFEFDFDFCFDFF + F5F7FBE1E6EED2D6E2C3C7D6B9BFD5AFB8D5B2B8D3B6B9D2 + CCD1E6DADEEAE8EBEEE3EAEFDFEAF1D8E3EBD1DDE6BACAD8 + 9DB0D28199BF7790B56E87AC6C84A66B82A05C72934A5B7B + 2935531F2D451626381525351524321625341727371A2B44 + 2536563B4D8955689E6F84B37A90BF869DCCA3B6D7B9C6DF + CAD6E7C5CDDDC0C4D3BCC1CDB9BFC7B1B6C0ACB3BFB2BBC1 + BCC2C6D8DEE1E2E7EBECF0F5EDF1F6EFF3F8E9EFF7DDE3EF + BAC0D8ABB1D19CA3CA98A1CA949FCB8E9BD097A2D5A9B3E2 + BBC6EADFE4F4E3EAF7E8F1FBE8F3FADEE9EECAD8E4B3C3D9 + 8D9AAB808DA474809E737D9A737B977178925F6D9A4E5E95 + 4552841B2D611524540F1C47091236080F2A080D22070C20 + 11162D151E3A1A26482332532C3E5E42567557688B71839F + 8C9AB0BDC6C9BEC7C9C0C9CAC9C9C6C7CAC4B4BFB9A9AEA9 + 9499A09198A08E97A1929C9D939FA08F9CA5899397767F82 + 586873343A51272F491B2542141B360E142C0A0F250B0D20 + 0B12270E152E1119351721461D2A5622316127387126397C + 22367C253581222F7E1D2C7722317E333B824A5289636FA2 + ACB3D0BAC1DAC8D0E4D5E1E7D8E3E2D0DBDBB7C8C69AA8AC + + + + + + + 7886955967864652763240672432611E2D5D192757172255 + 11224F0D1D410F1A39101E350F202C0F1F23101B1E0C161C + 08151A060E14040A12040D13050D12060C11050D12050D11 + 050B0F05080F05080D04080C04080E050912040A18030C25 + 0410350616450A1E560F2362122768172B63192B5D162959 + 13234F1020420B1E3C0B1B380D19300E1A280D18200C191E + 0D1C200F1C1E0D1A1D0A171E0B171C0B1119070A15040611 + 03050E01050C00060C01060C03090D061213081516071012 + 0813160B1420081022060C24050926040728020528010429 + 00042F060B3B0C124717255A22396D3B4E815564955D6F9B + 667AA28593AC7A8799707B875F6A784F59694751643F4A60 + 2633602534622536651D3162162D60162B5D16295B15275E + 182B6324386D3F517F5A6B927686A992A1C1A5B1CAB8C2D4 + E4EAF3EEF3F8F9FCFDFBFCFDFEFCFDFEFCFDFEFDFDFCFDFF + F5F7FBE1E6EED2D6E2C3C7D6B9BFD5AFB8D5B2B8D3B6B9D2 + CCD1E6DADEEAE8EBEEE3EAEFDFEAF1D8E3EBD1DDE6BACAD8 + 9DB0D28199BF7790B56E87AC6C84A66B82A05C72934A5B7B + 2935531F2D451626381525351524321625341727371A2B44 + 2536563B4D8955689E6F84B37A90BF869DCCA3B6D7B9C6DF + CAD6E7C5CDDDC0C4D3BCC1CDB9BFC7B1B6C0ACB3BFB2BBC1 + BCC2C6D8DEE1E2E7EBECF0F5EDF1F6EFF3F8E9EFF7DDE3EF + BAC0D8ABB1D19CA3CA98A1CA949FCB8E9BD097A2D5A9B3E2 + BBC6EADFE4F4E3EAF7E8F1FBE8F3FADEE9EECAD8E4B3C3D9 + 8D9AAB808DA474809E737D9A737B977178925F6D9A4E5E95 + 4552841B2D611524540F1C47091236080F2A080D22070C20 + 11162D151E3A1A26482332532C3E5E42567557688B71839F + 8C9AB0BDC6C9BEC7C9C0C9CAC9C9C6C7CAC4B4BFB9A9AEA9 + 9499A09198A08E97A1929C9D939FA08F9CA5899397767F82 + 586873343A51272F491B2542141B360E142C0A0F250B0D20 + 0B12270E152E1119351721461D2A5622316127387126397C + 22367C253581222F7E1D2C7722317E333B824A5289636FA2 + ACB3D0BAC1DAC8D0E4D5E1E7D8E3E2D0DBDBB7C8C69AA8AC + + + diff --git a/posts/2023/06/flam3/index.tsx b/posts/2023/06/flam3/index.tsx new file mode 100644 index 0000000..7651ac2 --- /dev/null +++ b/posts/2023/06/flam3/index.tsx @@ -0,0 +1,20 @@ +import React from "react"; +import Blog from "../../../LayoutBlog"; + +import { Canvas } from "./0-utility"; +import { gasket } from "./1-gasket"; +import { renderBaseline } from "./2-variations"; + +export default function () { + const Layout = Blog({ + title: "The fractal flame algorithm", + description: "Explaining the paper", + published: "2023-06-25", + }); + return ( + + + + + ); +} diff --git a/posts/2023/06/flam3/renders.flame b/posts/2023/06/flam3/renders.flame new file mode 100644 index 0000000..cc281a6 --- /dev/null +++ b/posts/2023/06/flam3/renders.flame @@ -0,0 +1,40 @@ + + + + + + 7886955967864652763240672432611E2D5D192757172255 + 11224F0D1D410F1A39101E350F202C0F1F23101B1E0C161C + 08151A060E14040A12040D13050D12060C11050D12050D11 + 050B0F05080F05080D04080C04080E050912040A18030C25 + 0410350616450A1E560F2362122768172B63192B5D162959 + 13234F1020420B1E3C0B1B380D19300E1A280D18200C191E + 0D1C200F1C1E0D1A1D0A171E0B171C0B1119070A15040611 + 03050E01050C00060C01060C03090D061213081516071012 + 0813160B1420081022060C24050926040728020528010429 + 00042F060B3B0C124717255A22396D3B4E815564955D6F9B + 667AA28593AC7A8799707B875F6A784F59694751643F4A60 + 2633602534622536651D3162162D60162B5D16295B15275E + 182B6324386D3F517F5A6B927686A992A1C1A5B1CAB8C2D4 + E4EAF3EEF3F8F9FCFDFBFCFDFEFCFDFEFCFDFEFDFDFCFDFF + F5F7FBE1E6EED2D6E2C3C7D6B9BFD5AFB8D5B2B8D3B6B9D2 + CCD1E6DADEEAE8EBEEE3EAEFDFEAF1D8E3EBD1DDE6BACAD8 + 9DB0D28199BF7790B56E87AC6C84A66B82A05C72934A5B7B + 2935531F2D451626381525351524321625341727371A2B44 + 2536563B4D8955689E6F84B37A90BF869DCCA3B6D7B9C6DF + CAD6E7C5CDDDC0C4D3BCC1CDB9BFC7B1B6C0ACB3BFB2BBC1 + BCC2C6D8DEE1E2E7EBECF0F5EDF1F6EFF3F8E9EFF7DDE3EF + BAC0D8ABB1D19CA3CA98A1CA949FCB8E9BD097A2D5A9B3E2 + BBC6EADFE4F4E3EAF7E8F1FBE8F3FADEE9EECAD8E4B3C3D9 + 8D9AAB808DA474809E737D9A737B977178925F6D9A4E5E95 + 4552841B2D611524540F1C47091236080F2A080D22070C20 + 11162D151E3A1A26482332532C3E5E42567557688B71839F + 8C9AB0BDC6C9BEC7C9C0C9CAC9C9C6C7CAC4B4BFB9A9AEA9 + 9499A09198A08E97A1929C9D939FA08F9CA5899397767F82 + 586873343A51272F491B2542141B360E142C0A0F250B0D20 + 0B12270E152E1119351721461D2A5622316127387126397C + 22367C253581222F7E1D2C7722317E333B824A5289636FA2 + ACB3D0BAC1DAC8D0E4D5E1E7D8E3E2D0DBDBB7C8C69AA8AC + + + diff --git a/vite.config.ts b/vite.config.ts index 7fcbed8..87aebe3 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -19,6 +19,7 @@ export default defineConfig({ "/": "/pages/index.tsx", "/about": "/pages/about.mdx", "/2019/02/the-whole-world": "/posts/2019/02/the-whole-world.mdx", + "/2023/06/flam3": "/posts/2023/06/flam3/index.tsx", }), mdx({ remarkPlugins: [remarkFrontmatter, remarkMath, remarkMdxFrontmatter],