mirror of
https://github.com/bspeice/speice.io
synced 2025-07-01 13:56:11 -04:00
Checkpoint for histogram
It takes a lot of render time to get a usable result, and it's not that interesting. Committing so I can save the work if I want to revisit it, but abandoning the idea for now.
This commit is contained in:
@ -1,5 +1,30 @@
|
||||
import {VictoryArea} from "victory";
|
||||
import {VictoryChart, VictoryLine, VictoryScatter, VictoryTheme} from "victory";
|
||||
import {useContext, useEffect, useState} from "react";
|
||||
import {PainterContext} from "../src/Canvas";
|
||||
import {chaosGameHistogram} from "./chaosGameHistogram";
|
||||
import {PlotData, plotHistogram} from "./plotHistogram";
|
||||
|
||||
function F() {
|
||||
return <VictoryArea data={}
|
||||
function* plotChaosGame(width: number, height: number, setPdf: (data: PlotData) => void, setCdf: (data: PlotData) => void) {
|
||||
const emptyImage = new ImageData(width, height);
|
||||
for (let histogram of chaosGameHistogram(width, height)) {
|
||||
const plotData = plotHistogram(histogram);
|
||||
setPdf(plotData);
|
||||
yield emptyImage;
|
||||
}
|
||||
}
|
||||
|
||||
export default function FlameHistogram() {
|
||||
const {width, height, setPainter} = useContext(PainterContext);
|
||||
const [pdfData, setPdfData] = useState<{ x: number, y: number }[]>(null);
|
||||
|
||||
useEffect(() => setPainter(plotChaosGame(width, height, setPdfData, null)), []);
|
||||
|
||||
return (
|
||||
<VictoryChart theme={VictoryTheme.clean}>
|
||||
<VictoryLine
|
||||
data={pdfData}
|
||||
interpolation='natural'
|
||||
/>
|
||||
</VictoryChart>
|
||||
)
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
// hidden-start
|
||||
import {VictoryChart} from "victory";
|
||||
import {camera, histIndex} from "../src/camera";
|
||||
// hidden-end
|
||||
export class PlotHistogram {
|
||||
public readonly pixels: Uint32Array;
|
||||
|
||||
public constructor(private readonly width: number, height: number) {
|
||||
this.pixels = new Uint32Array(width * height);
|
||||
}
|
||||
|
||||
public plot(x: number, y: number) {
|
||||
const [pixelX, pixelY] = camera(x, y, this.width);
|
||||
const pixelIndex = histIndex(pixelX, pixelY, this.width, 1);
|
||||
this.pixels[pixelIndex] += 1;
|
||||
}
|
||||
|
||||
public getHistogram() {
|
||||
const data = new Map<number, number>();
|
||||
this.pixels.forEach(value => {
|
||||
const bucket = 32 - Math.clz32(value);
|
||||
|
||||
if (bucket in data) {
|
||||
data[bucket] += 1;
|
||||
} else {
|
||||
data[bucket] = 1;
|
||||
}
|
||||
})
|
||||
|
||||
const output: {x: number, y: number}[] = [];
|
||||
data.forEach((bucket, value) =>
|
||||
output.push({x: Math.pow(bucket, 2), y: value}));
|
||||
return output;
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
import {plot} from "./plotHistogram";
|
||||
import {randomBiUnit} from "../src/randomBiUnit";
|
||||
import {randomChoice} from "../src/randomChoice";
|
||||
import {buildTransform} from "../2-transforms/buildTransform";
|
||||
import {transformPost} from "../2-transforms/post";
|
||||
import {transforms} from "../2-transforms/FlameFinal";
|
||||
import * as params from "../src/params";
|
||||
|
||||
const finalTransform = buildTransform(params.xformFinalCoefs, params.xformFinalVariations);
|
||||
const finalTransformPost = transformPost(finalTransform, params.xformFinalCoefsPost);
|
||||
|
||||
const step = 1000;
|
||||
const quality = 1;
|
||||
|
||||
export function* chaosGameHistogram(width: number, height: number) {
|
||||
let iterations = quality * width * height;
|
||||
let histogram = new Uint32Array(width * height);
|
||||
|
||||
let [x, y] = [randomBiUnit(), randomBiUnit()];
|
||||
|
||||
for (let i = 0; i < iterations; i++) {
|
||||
const [_, transform] = randomChoice(transforms);
|
||||
[x, y] = transform(x, y);
|
||||
[x, y] = finalTransformPost(x, y);
|
||||
|
||||
if (i > 20)
|
||||
plot(x, y, width, histogram);
|
||||
|
||||
if (i % step === 0)
|
||||
yield histogram;
|
||||
}
|
||||
|
||||
yield histogram;
|
||||
}
|
@ -23,6 +23,13 @@ We'll render the reference image again, but this time, counting the times
|
||||
we tried to turn on a pixel.
|
||||
|
||||
import CodeBlock from "@theme/CodeBlock";
|
||||
import plotHistogramSource from "!!raw-loader!./PlotHistogram";
|
||||
import plotHistogramSource from "!!raw-loader!./plotHistogram";
|
||||
|
||||
<CodeBlock language="typescript">{plotHistogramSource}</CodeBlock>
|
||||
|
||||
import Canvas from "../src/Canvas";
|
||||
import FlameHistogram from "./FlameHistogram";
|
||||
|
||||
<Canvas width={400} height={400} hidden={true}>
|
||||
<FlameHistogram/>
|
||||
</Canvas>
|
@ -0,0 +1,23 @@
|
||||
// hidden-start
|
||||
import {camera, histIndex} from "../src/camera";
|
||||
// hidden-end
|
||||
export function plot(x: number, y: number, width: number, hitCount: Uint32Array) {
|
||||
const [pixelX, pixelY] = camera(x, y, width);
|
||||
const pixelIndex = histIndex(pixelX, pixelY, width, 1);
|
||||
hitCount[pixelIndex] += 1;
|
||||
}
|
||||
|
||||
export type PlotData = {x: number, y: number}[];
|
||||
export function plotHistogram(hitCount: Uint32Array) {
|
||||
const data = new Map<number, number>();
|
||||
hitCount.forEach(value => {
|
||||
const bucket = 32 - Math.clz32(value);
|
||||
const currentCount = data.get(bucket) ?? 0;
|
||||
data.set(bucket, currentCount + 1);
|
||||
})
|
||||
|
||||
const output: PlotData = [];
|
||||
data.forEach((value, bucket) =>
|
||||
output.push({x: Math.pow(2, bucket), y: value}));
|
||||
return output;
|
||||
}
|
Reference in New Issue
Block a user