mirror of
https://github.com/bspeice/speice.io
synced 2024-12-22 16:48:10 -05:00
Refactor to use a step function
This commit is contained in:
parent
4bcc321c4b
commit
79394519c7
@ -28,7 +28,7 @@ export const Canvas: React.FC<{ f: renderFn }> = ({ f }) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return <canvas ref={canvasRef} width={600} height={600} />;
|
return <canvas ref={canvasRef} width={400} height={400} />;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function randomInteger(min: number, max: number) {
|
export function randomInteger(min: number, max: number) {
|
||||||
|
@ -10,7 +10,7 @@ function plot(x: number, y: number, image: ImageData) {
|
|||||||
// pixelY = Math.floor((y + 1) * image.height / 2)
|
// pixelY = Math.floor((y + 1) * image.height / 2)
|
||||||
//
|
//
|
||||||
// However, that produces a mirror image (across both X and Y)
|
// However, that produces a mirror image (across both X and Y)
|
||||||
// from the paper. We'll invert X and Y to compensate.
|
// from the paper. We'll negate X and Y to compensate.
|
||||||
// Second, because the gasket solution only contains points in
|
// Second, because the gasket solution only contains points in
|
||||||
// the range [0, 1), the naive plot above would waste 75% of
|
// the range [0, 1), the naive plot above would waste 75% of
|
||||||
// the pixels available. We'll keep the shift by 1 (to compensate
|
// the pixels available. We'll keep the shift by 1 (to compensate
|
||||||
|
@ -17,7 +17,7 @@ function r(x: number, y: number) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function theta(x: number, y: number) {
|
function theta(x: number, y: number) {
|
||||||
return Math.atan2(x, y);
|
return Math.atan2(y, x);
|
||||||
}
|
}
|
||||||
|
|
||||||
function omega(): number {
|
function omega(): number {
|
||||||
@ -93,6 +93,18 @@ export function weightedChoice<T>(choices: [number, T][]) {
|
|||||||
throw "unreachable";
|
throw "unreachable";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class Flame {
|
||||||
|
x: number = Math.random() * 2 - 1;
|
||||||
|
y: number = Math.random() * 2 - 1;
|
||||||
|
|
||||||
|
constructor(public readonly transforms: [number, Transform][]) {}
|
||||||
|
|
||||||
|
step() {
|
||||||
|
const transform = weightedChoice(this.transforms);
|
||||||
|
[this.x, this.y] = transform.apply(this.x, this.y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function plot(x: number, y: number, image: ImageData) {
|
export function plot(x: number, y: number, image: ImageData) {
|
||||||
const pixelX = Math.floor(((x + 2) * image.width) / 4);
|
const pixelX = Math.floor(((x + 2) * image.width) / 4);
|
||||||
const pixelY = Math.floor(((y + 2) * image.height) / 4);
|
const pixelY = Math.floor(((y + 2) * image.height) / 4);
|
||||||
@ -114,23 +126,13 @@ export function plot(x: number, y: number, image: ImageData) {
|
|||||||
image.data[index + 3] = 0xff;
|
image.data[index + 3] = 0xff;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Flame {
|
export function render(flame: Flame, quality: number, image: ImageData) {
|
||||||
constructor(public readonly transforms: [number, Transform][]) {}
|
const iterations = quality * image.width * image.height;
|
||||||
|
|
||||||
render(quality: number, image: ImageData) {
|
for (var i = 0; i < iterations; i++) {
|
||||||
var x = Math.random() * 2 - 1;
|
flame.step();
|
||||||
var y = Math.random() * 2 - 1;
|
if (i > 20) {
|
||||||
|
plot(flame.x, flame.y, image);
|
||||||
const iter = quality * (image.width * image.height);
|
|
||||||
for (var i = 0; i < iter; i++) {
|
|
||||||
const transform = weightedChoice(this.transforms);
|
|
||||||
|
|
||||||
// Play the chaos game
|
|
||||||
[x, y] = transform.apply(x, y);
|
|
||||||
|
|
||||||
if (i > 20) {
|
|
||||||
plot(x, y, image);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -185,5 +187,5 @@ export function renderBaseline(image: ImageData) {
|
|||||||
[transform3Weight, transform3],
|
[transform3Weight, transform3],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
flame.render(1, image);
|
render(flame, 1, image);
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ import {
|
|||||||
julia,
|
julia,
|
||||||
popcorn,
|
popcorn,
|
||||||
pdj,
|
pdj,
|
||||||
|
render,
|
||||||
transform1Coefs,
|
transform1Coefs,
|
||||||
transform1Weight,
|
transform1Weight,
|
||||||
transform2Coefs,
|
transform2Coefs,
|
||||||
@ -75,5 +76,6 @@ export function renderPost(image: ImageData) {
|
|||||||
[transform2Weight, transform2],
|
[transform2Weight, transform2],
|
||||||
[transform3Weight, transform3],
|
[transform3Weight, transform3],
|
||||||
]);
|
]);
|
||||||
flame.render(1, image);
|
|
||||||
|
render(flame, 1, image);
|
||||||
}
|
}
|
||||||
|
@ -13,8 +13,7 @@ import {
|
|||||||
transform3Coefs,
|
transform3Coefs,
|
||||||
transform3Pdj,
|
transform3Pdj,
|
||||||
transform3Weight,
|
transform3Weight,
|
||||||
weightedChoice,
|
render,
|
||||||
plot,
|
|
||||||
} from "./2a-variations";
|
} from "./2a-variations";
|
||||||
import { TransformPost, transform2Post } from "./2b-post";
|
import { TransformPost, transform2Post } from "./2b-post";
|
||||||
|
|
||||||
@ -26,22 +25,9 @@ export class FlameFinal extends Flame {
|
|||||||
super(transforms);
|
super(transforms);
|
||||||
}
|
}
|
||||||
|
|
||||||
render(quality: number, image: ImageData) {
|
step() {
|
||||||
var x = Math.random() * 2 - 1;
|
super.step();
|
||||||
var y = Math.random() * 2 - 1;
|
[this.x, this.y] = this.final.apply(this.x, this.y);
|
||||||
|
|
||||||
const iter = quality * (image.width * image.height);
|
|
||||||
for (var i = 0; i < iter; i++) {
|
|
||||||
const transform = weightedChoice(this.transforms);
|
|
||||||
[x, y] = transform.apply(x, y);
|
|
||||||
|
|
||||||
// This line is the only thing that changes:
|
|
||||||
[x, y] = this.final.apply(x, y);
|
|
||||||
|
|
||||||
if (i > 20) {
|
|
||||||
plot(x, y, image);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,5 +68,5 @@ export function renderFinal(image: ImageData) {
|
|||||||
transformFinal
|
transformFinal
|
||||||
);
|
);
|
||||||
|
|
||||||
flame.render(1, image);
|
render(flame, 1, image);
|
||||||
}
|
}
|
||||||
|
@ -14,10 +14,14 @@ export default function () {
|
|||||||
});
|
});
|
||||||
return (
|
return (
|
||||||
<Layout>
|
<Layout>
|
||||||
<Canvas f={gasket} />
|
<div>
|
||||||
<Canvas f={renderBaseline} />
|
<Canvas f={gasket} />
|
||||||
<Canvas f={renderPost} />
|
<Canvas f={renderBaseline} />
|
||||||
<Canvas f={renderFinal} />
|
</div>
|
||||||
|
<div>
|
||||||
|
<Canvas f={renderPost} />
|
||||||
|
<Canvas f={renderFinal} />
|
||||||
|
</div>
|
||||||
</Layout>
|
</Layout>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user