mirror of
				https://github.com/bspeice/speice.io
				synced 2025-10-31 01:20:31 -04:00 
			
		
		
		
	Refactor to use a step function
This commit is contained in:
		| @ -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) { | ||||
|  | ||||
| @ -10,7 +10,7 @@ function plot(x: number, y: number, image: ImageData) { | ||||
|   //  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. | ||||
|   // from the paper. We'll negate 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 | ||||
|  | ||||
| @ -17,7 +17,7 @@ function r(x: number, y: number) { | ||||
| } | ||||
|  | ||||
| function theta(x: number, y: number) { | ||||
|   return Math.atan2(x, y); | ||||
|   return Math.atan2(y, x); | ||||
| } | ||||
|  | ||||
| function omega(): number { | ||||
| @ -93,6 +93,18 @@ export function weightedChoice<T>(choices: [number, T][]) { | ||||
|   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) { | ||||
|   const pixelX = Math.floor(((x + 2) * image.width) / 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; | ||||
| } | ||||
|  | ||||
| export class Flame { | ||||
|   constructor(public readonly transforms: [number, Transform][]) {} | ||||
|  | ||||
|   render(quality: number, image: ImageData) { | ||||
|     var x = Math.random() * 2 - 1; | ||||
|     var y = Math.random() * 2 - 1; | ||||
|  | ||||
|     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); | ||||
| export function render(flame: Flame, quality: number, image: ImageData) { | ||||
|   const iterations = quality * image.width * image.height; | ||||
|  | ||||
|   for (var i = 0; i < iterations; i++) { | ||||
|     flame.step(); | ||||
|     if (i > 20) { | ||||
|         plot(x, y, image); | ||||
|       } | ||||
|       plot(flame.x, flame.y, image); | ||||
|     } | ||||
|   } | ||||
| } | ||||
| @ -185,5 +187,5 @@ export function renderBaseline(image: ImageData) { | ||||
|     [transform3Weight, transform3], | ||||
|   ]); | ||||
|  | ||||
|   flame.render(1, image); | ||||
|   render(flame, 1, image); | ||||
| } | ||||
|  | ||||
| @ -7,6 +7,7 @@ import { | ||||
|   julia, | ||||
|   popcorn, | ||||
|   pdj, | ||||
|   render, | ||||
|   transform1Coefs, | ||||
|   transform1Weight, | ||||
|   transform2Coefs, | ||||
| @ -75,5 +76,6 @@ export function renderPost(image: ImageData) { | ||||
|     [transform2Weight, transform2], | ||||
|     [transform3Weight, transform3], | ||||
|   ]); | ||||
|   flame.render(1, image); | ||||
|  | ||||
|   render(flame, 1, image); | ||||
| } | ||||
|  | ||||
| @ -13,8 +13,7 @@ import { | ||||
|   transform3Coefs, | ||||
|   transform3Pdj, | ||||
|   transform3Weight, | ||||
|   weightedChoice, | ||||
|   plot, | ||||
|   render, | ||||
| } from "./2a-variations"; | ||||
| import { TransformPost, transform2Post } from "./2b-post"; | ||||
|  | ||||
| @ -26,22 +25,9 @@ export class FlameFinal extends Flame { | ||||
|     super(transforms); | ||||
|   } | ||||
|  | ||||
|   render(quality: number, image: ImageData) { | ||||
|     var x = Math.random() * 2 - 1; | ||||
|     var y = Math.random() * 2 - 1; | ||||
|  | ||||
|     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); | ||||
|       } | ||||
|     } | ||||
|   step() { | ||||
|     super.step(); | ||||
|     [this.x, this.y] = this.final.apply(this.x, this.y); | ||||
|   } | ||||
| } | ||||
|  | ||||
| @ -82,5 +68,5 @@ export function renderFinal(image: ImageData) { | ||||
|     transformFinal | ||||
|   ); | ||||
|  | ||||
|   flame.render(1, image); | ||||
|   render(flame, 1, image); | ||||
| } | ||||
|  | ||||
| @ -14,10 +14,14 @@ export default function () { | ||||
|   }); | ||||
|   return ( | ||||
|     <Layout> | ||||
|       <div> | ||||
|         <Canvas f={gasket} /> | ||||
|         <Canvas f={renderBaseline} /> | ||||
|       </div> | ||||
|       <div> | ||||
|         <Canvas f={renderPost} /> | ||||
|         <Canvas f={renderFinal} /> | ||||
|       </div> | ||||
|     </Layout> | ||||
|   ); | ||||
| } | ||||
|  | ||||
		Reference in New Issue
	
	Block a user