Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Randomness Not Reproducible #155

Closed
nysky1 opened this issue May 16, 2022 · 3 comments
Closed

Randomness Not Reproducible #155

nysky1 opened this issue May 16, 2022 · 3 comments

Comments

@nysky1
Copy link

nysky1 commented May 16, 2022

Matt and community, I've tried for a few days now to ensure that I can regen an image based on a seed. Tell me why this scenario does NOT work:

I'm running this example from the /examples folder.
I CMD-R to refresh the images.
I see an image I like - I press CMD+S.
The browser saves the image with the seed as a suffix.
I go back, comment out line 5 and uncomment line 6, then adding the seed to line 6 below (see <----- comment)
I rerun with the hard-coded seed and get a different image than expected.

Have a misread the docs or am I doing something wrong? Thank you!


const canvasSketch = require('canvas-sketch');
const Random = require('canvas-sketch-util/random');
const { lerp } = require('canvas-sketch-util/math');

// We can force a random seed or a specific string/number
Random.setSeed(Random.getRandomSeed());
//Random.setSeed(340593); <--------

const settings = {
pixelsPerInch: 300,
// When exporting, use the seed as the suffix
// This way we can reproduce it more easily later
suffix: Random.getSeed(),
// Standard A4 paper size
dimensions: 'A4',
// We'll work in inches for the rendering
units: 'in'
};

const sketch = ({ width, height }) => {
const margin = 0;

const sliceCount = 50000;
const slices = Array.from(new Array(sliceCount)).map((_, i, list) => {
const t = list.lenth <= 1 ? 0 : i / (list.length - 1);

const noiseAngle = t * Math.PI * 2;
const nx = Math.cos(noiseAngle);
const ny = Math.sin(noiseAngle);
const nf = 0.05 + Random.range(0, 0.5);
const amplitude = 2;
const noise = Random.noise2D(nx * nf, ny * nf);
const noise01 = noise * 0.5 + 0.5;

const tOffset = Random.gaussian(0, 0.01);

const cx = width / 2;
const x = cx + noise * amplitude;
return {
  alpha: Random.range(0.75, 1) * (1 - noise01),
  color: 'white',
  lineWidth: Random.range(0.005, 0.02) * 0.1,
  length: Random.gaussian() * noise01 * 0.5,
  angle: Random.gaussian(0, 1),
  x,
  y: lerp(margin, height - margin, t + tOffset)
};

});

return ({ context }) => {
context.globalCompositeOperation = 'source-over';
context.fillStyle = 'black';
context.fillRect(0, 0, width, height);
context.globalCompositeOperation = 'lighter';

slices.forEach(slice => {
  context.save();
  context.beginPath();
  context.translate(slice.x, slice.y);
  context.rotate(slice.angle);
  context.lineTo(slice.length / 2, 0);
  context.lineTo(-slice.length / 2, 0);
  context.lineWidth = slice.lineWidth;
  context.strokeStyle = slice.color;
  context.globalAlpha = slice.alpha;
  context.stroke();
  context.restore();
});

};
};

canvasSketch(sketch, settings);

@L-A
Copy link

L-A commented May 16, 2022

FWIW, this is about canvas-sketch-util, not really canvas-sketch, but it's probably useful to others:

You're getting this behaviour because when you save an image, the PRNG has already stepped forward every time you called random.something, and it will be in a different state the start of the next drawing call.

To get a consistent state and output in this situation, you have to store the value of getRandomSeed() at the top, then re-apply it to setSeed at the beginning of your sketch function:

// Seeding at the top

const Seed = random.getRandomSeed();
random.setSeed(Seed);
// Then setting a constant state when starting to draw

  const sketch = () => {
  return ({ context, width, height }) => {
    random.setSeed(Seed); // <- Re-apply your seed before you call your first random
    [...]

You could also generate a separate getRandomSeed() value specifically for your drawing routine, so long as you consistently apply it at the beginning of your sketch function.

@nysky1
Copy link
Author

nysky1 commented May 16, 2022 via email

@nysky1 nysky1 closed this as completed May 16, 2022
@nysky1
Copy link
Author

nysky1 commented May 18, 2022 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants