mirror of
https://github.com/bspeice/speice.io
synced 2025-09-08 15:45:01 -04:00
Log density visualization
This commit is contained in:
@ -1,17 +1,12 @@
|
||||
import {useContext, useEffect, useState} from "react";
|
||||
import {Transform} from "../src/transform";
|
||||
import {
|
||||
xform1Coefs,
|
||||
xform1Weight,
|
||||
xform2Coefs,
|
||||
xform2Weight,
|
||||
xform3Coefs,
|
||||
xform3Weight
|
||||
} from "../src/params";
|
||||
import * as params from "../src/params"
|
||||
import {PainterContext} from "../src/Canvas"
|
||||
import {buildBlend, buildTransform} from "./buildTransform"
|
||||
import {chaosGameFinal} from "./chaosGameFinal"
|
||||
import {VariationEditor, VariationProps} from "./VariationEditor"
|
||||
import {xform1Weight} from "../src/params";
|
||||
import {applyTransform} from "@site/blog/2024-11-15-playing-with-fire/src/applyTransform";
|
||||
import {buildBlend} from "@site/blog/2024-11-15-playing-with-fire/2-transforms/buildBlend";
|
||||
|
||||
export default function FlameBlend() {
|
||||
const {width, height, setPainter} = useContext(PainterContext);
|
||||
@ -47,11 +42,21 @@ export default function FlameBlend() {
|
||||
// and swap in identity components for each
|
||||
const identityXform: Transform = (x, y) => [x, y];
|
||||
|
||||
useEffect(() => setPainter(chaosGameFinal(width, height, [
|
||||
[xform1Weight, buildTransform(xform1Coefs, buildBlend(xform1Coefs, xform1Variations))],
|
||||
[xform2Weight, buildTransform(xform2Coefs, buildBlend(xform2Coefs, xform2Variations))],
|
||||
[xform3Weight, buildTransform(xform3Coefs, buildBlend(xform3Coefs, xform3Variations))]
|
||||
], identityXform)), [xform1Variations, xform2Variations, xform3Variations]);
|
||||
useEffect(() => {
|
||||
const transforms: [number, Transform][] = [
|
||||
[params.xform1Weight, applyTransform(params.xform1Coefs, buildBlend(params.xform1Coefs, xform1Variations))],
|
||||
[params.xform2Weight, applyTransform(params.xform2Coefs, buildBlend(params.xform2Coefs, xform2Variations))],
|
||||
[params.xform3Weight, applyTransform(params.xform3Coefs, buildBlend(params.xform3Coefs, xform3Variations))]
|
||||
]
|
||||
|
||||
const gameParams = {
|
||||
width,
|
||||
height,
|
||||
transforms,
|
||||
final: identityXform
|
||||
}
|
||||
setPainter(chaosGameFinal(gameParams));
|
||||
}, [xform1Variations, xform2Variations, xform3Variations]);
|
||||
|
||||
return (
|
||||
<>
|
||||
|
@ -1,40 +1,18 @@
|
||||
import {useContext, useEffect, useState} from "react";
|
||||
import {Coefs} from "../src/coefs"
|
||||
import {
|
||||
xform1Coefs,
|
||||
xform1Weight,
|
||||
xform1Variations,
|
||||
xform1CoefsPost,
|
||||
xform2Coefs,
|
||||
xform2Weight,
|
||||
xform2Variations,
|
||||
xform2CoefsPost,
|
||||
xform3Coefs,
|
||||
xform3Weight,
|
||||
xform3Variations,
|
||||
xform3CoefsPost,
|
||||
xformFinalCoefs as xformFinalCoefsDefault,
|
||||
xformFinalCoefsPost as xformFinalCoefsPostDefault,
|
||||
} from "../src/params";
|
||||
import * as params from "../src/params";
|
||||
import {PainterContext} from "../src/Canvas"
|
||||
import {buildBlend, buildTransform} from "./buildTransform";
|
||||
import {transformPost} from "./post";
|
||||
import {buildBlend} from "./buildBlend";
|
||||
import {chaosGameFinal} from "./chaosGameFinal"
|
||||
import {VariationEditor, VariationProps} from "./VariationEditor";
|
||||
import {CoefEditor} from "./CoefEditor";
|
||||
import {Transform} from "../src/transform";
|
||||
|
||||
export const transforms: [number, Transform][] = [
|
||||
[xform1Weight, transformPost(buildTransform(xform1Coefs, xform1Variations), xform1CoefsPost)],
|
||||
[xform2Weight, transformPost(buildTransform(xform2Coefs, xform2Variations), xform2CoefsPost)],
|
||||
[xform3Weight, transformPost(buildTransform(xform3Coefs, xform3Variations), xform3CoefsPost)]
|
||||
];
|
||||
import {applyPost, applyTransform} from "../src/applyTransform";
|
||||
|
||||
export default function FlameFinal() {
|
||||
const {width, height, setPainter} = useContext(PainterContext);
|
||||
|
||||
const [xformFinalCoefs, setXformFinalCoefs] = useState<Coefs>(xformFinalCoefsDefault);
|
||||
const resetXformFinalCoefs = () => setXformFinalCoefs(xformFinalCoefsDefault);
|
||||
const [xformFinalCoefs, setXformFinalCoefs] = useState<Coefs>(params.xformFinalCoefs);
|
||||
const resetXformFinalCoefs = () => setXformFinalCoefs(params.xformFinalCoefs);
|
||||
|
||||
const xformFinalVariationsDefault: VariationProps = {
|
||||
linear: 0,
|
||||
@ -45,15 +23,14 @@ export default function FlameFinal() {
|
||||
const [xformFinalVariations, setXformFinalVariations] = useState<VariationProps>(xformFinalVariationsDefault);
|
||||
const resetXformFinalVariations = () => setXformFinalVariations(xformFinalVariationsDefault);
|
||||
|
||||
const [xformFinalCoefsPost, setXformFinalCoefsPost] = useState<Coefs>(xformFinalCoefsPostDefault);
|
||||
const resetXformFinalCoefsPost = () => setXformFinalCoefsPost(xformFinalCoefsPostDefault);
|
||||
const [xformFinalCoefsPost, setXformFinalCoefsPost] = useState<Coefs>(params.xformFinalCoefsPost);
|
||||
const resetXformFinalCoefsPost = () => setXformFinalCoefsPost(params.xformFinalCoefsPost);
|
||||
|
||||
useEffect(() => {
|
||||
const finalBlend = buildBlend(xformFinalCoefs, xformFinalVariations);
|
||||
const finalTransform = buildTransform(xformFinalCoefs, finalBlend);
|
||||
const finalPost = transformPost(finalTransform, xformFinalCoefsPost);
|
||||
const finalXform = applyPost(xformFinalCoefsPost, applyTransform(xformFinalCoefs, finalBlend));
|
||||
|
||||
setPainter(chaosGameFinal(width, height, transforms, finalPost));
|
||||
setPainter(chaosGameFinal({width, height, transforms: params.xforms, final: finalXform}));
|
||||
}, [xformFinalCoefs, xformFinalVariations, xformFinalCoefsPost]);
|
||||
|
||||
return (
|
||||
|
@ -1,45 +1,37 @@
|
||||
import {useContext, useEffect, useState} from "react";
|
||||
import {Coefs} from "../src/coefs"
|
||||
import {Transform} from "../src/transform";
|
||||
import {
|
||||
xform1Coefs,
|
||||
xform1Weight,
|
||||
xform1Variations,
|
||||
xform1CoefsPost as xform1CoefsPostDefault,
|
||||
xform2Coefs,
|
||||
xform2Weight,
|
||||
xform2Variations,
|
||||
xform2CoefsPost as xform2CoefsPostDefault,
|
||||
xform3Coefs,
|
||||
xform3Weight,
|
||||
xform3Variations,
|
||||
xform3CoefsPost as xform3CoefsPostDefault
|
||||
} from "../src/params";
|
||||
import * as params from "../src/params";
|
||||
import {PainterContext} from "../src/Canvas"
|
||||
import {chaosGameFinal} from "./chaosGameFinal"
|
||||
import {chaosGameFinal, ChaosGameFinalProps} from "./chaosGameFinal"
|
||||
import {CoefEditor} from "./CoefEditor"
|
||||
import {transformPost} from "./post";
|
||||
import {buildTransform} from "./buildTransform";
|
||||
import {applyPost, applyTransform} from "@site/blog/2024-11-15-playing-with-fire/src/applyTransform";
|
||||
|
||||
export default function FlamePost() {
|
||||
const {width, height, setPainter} = useContext(PainterContext);
|
||||
|
||||
const [xform1CoefsPost, setXform1CoefsPost] = useState<Coefs>(xform1CoefsPostDefault);
|
||||
const resetXform1CoefsPost = () => setXform1CoefsPost(xform1CoefsPostDefault);
|
||||
const [xform1CoefsPost, setXform1CoefsPost] = useState<Coefs>(params.xform1CoefsPost);
|
||||
const resetXform1CoefsPost = () => setXform1CoefsPost(params.xform1CoefsPost);
|
||||
|
||||
const [xform2CoefsPost, setXform2CoefsPost] = useState<Coefs>(xform2CoefsPostDefault);
|
||||
const resetXform2CoefsPost = () => setXform2CoefsPost(xform2CoefsPostDefault);
|
||||
const [xform2CoefsPost, setXform2CoefsPost] = useState<Coefs>(params.xform2CoefsPost);
|
||||
const resetXform2CoefsPost = () => setXform2CoefsPost(params.xform2CoefsPost);
|
||||
|
||||
const [xform3CoefsPost, setXform3CoefsPost] = useState<Coefs>(xform3CoefsPostDefault);
|
||||
const resetXform3CoefsPost = () => setXform1CoefsPost(xform3CoefsPostDefault);
|
||||
const [xform3CoefsPost, setXform3CoefsPost] = useState<Coefs>(params.xform3CoefsPost);
|
||||
const resetXform3CoefsPost = () => setXform1CoefsPost(params.xform3CoefsPost);
|
||||
|
||||
const identityXform: Transform = (x, y) => [x, y];
|
||||
|
||||
useEffect(() => setPainter(chaosGameFinal(width, height, [
|
||||
[xform1Weight, transformPost(buildTransform(xform1Coefs, xform1Variations), xform1CoefsPost)],
|
||||
[xform2Weight, transformPost(buildTransform(xform2Coefs, xform2Variations), xform2CoefsPost)],
|
||||
[xform3Weight, transformPost(buildTransform(xform3Coefs, xform3Variations), xform3CoefsPost)]
|
||||
], identityXform)), [xform1CoefsPost, xform2CoefsPost, xform3CoefsPost]);
|
||||
const gameParams: ChaosGameFinalProps = {
|
||||
width,
|
||||
height,
|
||||
transforms: [
|
||||
[params.xform1Weight, applyPost(xform1CoefsPost, applyTransform(params.xform1Coefs, params.xform1Variations))],
|
||||
[params.xform2Weight, applyPost(xform2CoefsPost, applyTransform(params.xform2Coefs, params.xform2Variations))],
|
||||
[params.xform3Weight, applyPost(xform3CoefsPost, applyTransform(params.xform3Coefs, params.xform3Variations))],
|
||||
],
|
||||
final: identityXform
|
||||
}
|
||||
useEffect(() => setPainter(chaosGameFinal(gameParams)), [xform1CoefsPost, xform2CoefsPost, xform3CoefsPost]);
|
||||
|
||||
return (
|
||||
<>
|
||||
|
@ -1,17 +0,0 @@
|
||||
// hidden-start
|
||||
import {VariationBlend} from "../src/variationBlend";
|
||||
// hidden-end
|
||||
export function blend(
|
||||
x: number,
|
||||
y: number,
|
||||
variations: VariationBlend): [number, number] {
|
||||
let [finalX, finalY] = [0, 0];
|
||||
|
||||
for (const [weight, variation] of variations) {
|
||||
const [varX, varY] = variation(x, y);
|
||||
finalX += weight * varX;
|
||||
finalY += weight * varY;
|
||||
}
|
||||
|
||||
return [finalX, finalY];
|
||||
}
|
@ -1,13 +1,11 @@
|
||||
import {applyCoefs, Coefs} from "../src/coefs";
|
||||
import {Coefs} from "../src/coefs";
|
||||
import {VariationProps} from "./VariationEditor";
|
||||
import {Transform} from "../src/transform";
|
||||
import {linear} from "../src/linear";
|
||||
import {julia} from "../src/julia";
|
||||
import {popcorn} from "../src/popcorn";
|
||||
import {pdj} from "../src/pdj";
|
||||
import {pdjParams} from "../src/params";
|
||||
import {blend} from "./blend";
|
||||
import {VariationBlend} from "../src/variationBlend";
|
||||
import {VariationBlend} from "../src/blend";
|
||||
|
||||
export function buildBlend(coefs: Coefs, variations: VariationProps): VariationBlend {
|
||||
return [
|
||||
@ -16,11 +14,4 @@ export function buildBlend(coefs: Coefs, variations: VariationProps): VariationB
|
||||
[variations.popcorn, popcorn(coefs)],
|
||||
[variations.pdj, pdj(pdjParams)]
|
||||
]
|
||||
}
|
||||
|
||||
export function buildTransform(coefs: Coefs, variations: VariationBlend): Transform {
|
||||
return (x: number, y: number) => {
|
||||
[x, y] = applyCoefs(x, y, coefs);
|
||||
return blend(x, y, variations);
|
||||
}
|
||||
}
|
@ -3,13 +3,20 @@ import { randomBiUnit } from "../src/randomBiUnit";
|
||||
import { randomChoice } from "../src/randomChoice";
|
||||
import { plotBinary as plot } from "../src/plotBinary"
|
||||
import {Transform} from "../src/transform";
|
||||
const iterations = 500_000;
|
||||
const step = 1000;
|
||||
import {ChaosGameWeightedProps} from "../1-introduction/chaosGameWeighted";
|
||||
// hidden-end
|
||||
export function* chaosGameFinal(width: number, height: number, transforms: [number, Transform][], final: Transform) {
|
||||
export type ChaosGameFinalProps = ChaosGameWeightedProps & {
|
||||
final: Transform,
|
||||
quality?: number,
|
||||
step?: number,
|
||||
}
|
||||
export function* chaosGameFinal({width, height, transforms, final, quality, step}: ChaosGameFinalProps) {
|
||||
let image = new ImageData(width, height);
|
||||
let [x, y] = [randomBiUnit(), randomBiUnit()];
|
||||
|
||||
const iterations = (quality ?? 0.5) * width * height;
|
||||
step = step ?? 1000;
|
||||
|
||||
for (let i = 0; i < iterations; i++) {
|
||||
const [_, transform] = randomChoice(transforms);
|
||||
[x, y] = transform(x, y);
|
||||
|
@ -133,7 +133,7 @@ $$
|
||||
|
||||
The formula looks intimidating, but it's not hard to implement:
|
||||
|
||||
import blendSource from "!!raw-loader!./blend";
|
||||
import blendSource from "!!raw-loader!../src/blend";
|
||||
|
||||
<CodeBlock language={'typescript'}>{blendSource}</CodeBlock>
|
||||
|
||||
|
Reference in New Issue
Block a user