💡 Performance: only calculate points once
This commit is contained in:
parent
41c3ce8b17
commit
7019b4c40a
72
bundle.js
72
bundle.js
|
@ -491,18 +491,18 @@ function _typeof(obj) { return obj && typeof Symbol !== "undefined" && obj.const
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Apply the chaos game: starting from `start`, we plot
|
* Starting from the last point in `points`, add
|
||||||
* the next `n` points. To get to the next point, we apply
|
* `iterations` number of point generated by applying
|
||||||
* a random transformation among given ones
|
* transformations chosen at random among `transforms`
|
||||||
*
|
*
|
||||||
* @param {Array} start Starting point
|
* @param {Array} points Initial set of points
|
||||||
* @param {number} iterations Number of points to plot
|
* @param {number} iterations Number of points to plot
|
||||||
* @param {Array} transforms List of available transforms
|
* @param {Array} transforms List of available transforms
|
||||||
* @param {Array} weights Probability weights for each transform
|
* @param {Array} weights Probability weights for each transform
|
||||||
* @return {null}
|
* @return {null}
|
||||||
*/
|
*/
|
||||||
var applyChaos = exports.applyChaos = function applyChaos(start, iterations, transforms, weights, cb) {
|
var applyChaos = exports.applyChaos = function applyChaos(points, iterations, transforms, weights) {
|
||||||
var point = start;
|
var point = points[points.length - 1];
|
||||||
|
|
||||||
if (weights === undefined) {
|
if (weights === undefined) {
|
||||||
weights = Array.apply(null, Array(transforms.length)).map(function () {
|
weights = Array.apply(null, Array(transforms.length)).map(function () {
|
||||||
|
@ -513,8 +513,7 @@ function _typeof(obj) { return obj && typeof Symbol !== "undefined" && obj.const
|
||||||
while (iterations--) {
|
while (iterations--) {
|
||||||
var index = chooseIndex(weights);
|
var index = chooseIndex(weights);
|
||||||
point = transforms[index](point);
|
point = transforms[index](point);
|
||||||
|
points.push(point);
|
||||||
cb(point);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}, {}], 7: [function (require, module, exports) {
|
}, {}], 7: [function (require, module, exports) {
|
||||||
|
@ -571,6 +570,8 @@ function _typeof(obj) { return obj && typeof Symbol !== "undefined" && obj.const
|
||||||
var width = undefined,
|
var width = undefined,
|
||||||
height = undefined;
|
height = undefined;
|
||||||
|
|
||||||
|
var points = [[0, 0]];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Re-render the scene from scratch
|
* Re-render the scene from scratch
|
||||||
*
|
*
|
||||||
|
@ -587,24 +588,22 @@ function _typeof(obj) { return obj && typeof Symbol !== "undefined" && obj.const
|
||||||
|
|
||||||
// do the chaos game
|
// do the chaos game
|
||||||
var image = ctx.getImageData(0, 0, width, height);
|
var image = ctx.getImageData(0, 0, width, height);
|
||||||
|
var length = points.length;
|
||||||
var color = [0, 0, 0];
|
var color = [0, 0, 0];
|
||||||
var skip = 50;
|
|
||||||
|
|
||||||
_chaos.applyChaos.apply(undefined, [[0, 0], 200000].concat(_toConsumableArray(_ifs.barnsley), [function (point) {
|
for (var i = 50; i < length; i += 1) {
|
||||||
var x = Math.floor(point[0] * zoom + center[0]);
|
var x = Math.floor(points[i][0] * zoom + center[0]);
|
||||||
var y = height - Math.floor(point[1] * zoom + center[1]);
|
var y = height - Math.floor(points[i][1] * zoom + center[1]);
|
||||||
|
|
||||||
if (x >= 0 && x < width && y >= 0 && y < height && skip <= 0) {
|
if (x >= 0 && x < width && y >= 0 && y < height) {
|
||||||
var i = (y * width + x) * 4;
|
var index = (y * width + x) * 4;
|
||||||
|
|
||||||
image.data[i] = color[0];
|
image.data[index] = color[0];
|
||||||
image.data[i + 1] = color[1];
|
image.data[index + 1] = color[1];
|
||||||
image.data[i + 2] = color[2];
|
image.data[index + 2] = color[2];
|
||||||
image.data[i + 3] = 255;
|
image.data[index + 3] = 255;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
skip -= 1;
|
|
||||||
}]));
|
|
||||||
|
|
||||||
ctx.putImageData(image, 0, 0);
|
ctx.putImageData(image, 0, 0);
|
||||||
};
|
};
|
||||||
|
@ -627,7 +626,7 @@ function _typeof(obj) { return obj && typeof Symbol !== "undefined" && obj.const
|
||||||
*/
|
*/
|
||||||
content.on('wheel', function (event) {
|
content.on('wheel', function (event) {
|
||||||
var delta = event.deltaMode === 0 ? event.deltaY / 53 : event.deltaY;
|
var delta = event.deltaMode === 0 ? event.deltaY / 53 : event.deltaY;
|
||||||
var newZoom = zoom * (1 - delta * .035);
|
var newZoom = zoom * Math.max(0, 1 - delta * .035);
|
||||||
|
|
||||||
// which (unprojected) point does the mouse point on?
|
// which (unprojected) point does the mouse point on?
|
||||||
var mouse = [(event.offsetX - center[0]) / zoom, (height - event.offsetY - center[1]) / zoom];
|
var mouse = [(event.offsetX - center[0]) / zoom, (height - event.offsetY - center[1]) / zoom];
|
||||||
|
@ -638,9 +637,33 @@ function _typeof(obj) { return obj && typeof Symbol !== "undefined" && obj.const
|
||||||
// => newCenter = mouse * zoom - mouse * newZoom + center
|
// => newCenter = mouse * zoom - mouse * newZoom + center
|
||||||
center = [mouse[0] * zoom - mouse[0] * newZoom + center[0], mouse[1] * zoom - mouse[1] * newZoom + center[1]];
|
center = [mouse[0] * zoom - mouse[0] * newZoom + center[0], mouse[1] * zoom - mouse[1] * newZoom + center[1]];
|
||||||
|
|
||||||
zoom = newZoom;
|
if (newZoom > zoom) {
|
||||||
render();
|
_chaos.applyChaos.apply(undefined, [points, Math.floor((newZoom - zoom) * 1000)].concat(_toConsumableArray(_ifs.sierpinski)));
|
||||||
|
} else {
|
||||||
|
// points = points.slice(0, points.length + Math.floor((newZoom - zoom) * 1000));
|
||||||
|
}
|
||||||
|
|
||||||
|
zoom = newZoom;
|
||||||
|
|
||||||
|
// time for some GC
|
||||||
|
if (points.length > 1000000) {
|
||||||
|
var length = points.length;
|
||||||
|
var newPoints = [];
|
||||||
|
var i = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < length; i += 1) {
|
||||||
|
var x = Math.floor(points[i][0] * zoom + center[0]);
|
||||||
|
var y = height - Math.floor(points[i][1] * zoom + center[1]);
|
||||||
|
|
||||||
|
if (x >= 0 && x < width && y >= 0 && y < height) {
|
||||||
|
newPoints.push(points[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
points = newPoints;
|
||||||
|
}
|
||||||
|
|
||||||
|
render();
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -668,6 +691,7 @@ function _typeof(obj) { return obj && typeof Symbol !== "undefined" && obj.const
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
_chaos.applyChaos.apply(undefined, [points, 200000].concat(_toConsumableArray(_ifs.sierpinski)));
|
||||||
window.onresize = resize;
|
window.onresize = resize;
|
||||||
resize();
|
resize();
|
||||||
}, { "./chaos": 6, "./ifs": 7, "the-dom": 1 }] }, {}, [8]);
|
}, { "./chaos": 6, "./ifs": 7, "the-dom": 1 }] }, {}, [8]);
|
||||||
|
|
|
@ -20,18 +20,18 @@ const chooseIndex = weights => {
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Apply the chaos game: starting from `start`, we plot
|
* Starting from the last point in `points`, add
|
||||||
* the next `n` points. To get to the next point, we apply
|
* `iterations` number of point generated by applying
|
||||||
* a random transformation among given ones
|
* transformations chosen at random among `transforms`
|
||||||
*
|
*
|
||||||
* @param {Array} start Starting point
|
* @param {Array} points Initial set of points
|
||||||
* @param {number} iterations Number of points to plot
|
* @param {number} iterations Number of points to plot
|
||||||
* @param {Array} transforms List of available transforms
|
* @param {Array} transforms List of available transforms
|
||||||
* @param {Array} weights Probability weights for each transform
|
* @param {Array} weights Probability weights for each transform
|
||||||
* @return {null}
|
* @return {null}
|
||||||
*/
|
*/
|
||||||
export const applyChaos = (start, iterations, transforms, weights, cb) => {
|
export const applyChaos = (points, iterations, transforms, weights) => {
|
||||||
let point = start;
|
let point = points[points.length - 1];
|
||||||
|
|
||||||
if (weights === undefined) {
|
if (weights === undefined) {
|
||||||
weights = Array.apply(null, Array(transforms.length)).map(
|
weights = Array.apply(null, Array(transforms.length)).map(
|
||||||
|
@ -42,7 +42,6 @@ export const applyChaos = (start, iterations, transforms, weights, cb) => {
|
||||||
while (iterations--) {
|
while (iterations--) {
|
||||||
const index = chooseIndex(weights);
|
const index = chooseIndex(weights);
|
||||||
point = transforms[index](point);
|
point = transforms[index](point);
|
||||||
|
points.push(point);
|
||||||
cb(point);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -14,6 +14,8 @@ let dragging = false;
|
||||||
let center, zoom = 200;
|
let center, zoom = 200;
|
||||||
let width, height;
|
let width, height;
|
||||||
|
|
||||||
|
let points = [[0, 0]];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Re-render the scene from scratch
|
* Re-render the scene from scratch
|
||||||
*
|
*
|
||||||
|
@ -30,24 +32,22 @@ const render = () => {
|
||||||
|
|
||||||
// do the chaos game
|
// do the chaos game
|
||||||
const image = ctx.getImageData(0, 0, width, height);
|
const image = ctx.getImageData(0, 0, width, height);
|
||||||
|
const length = points.length;
|
||||||
const color = [0, 0, 0];
|
const color = [0, 0, 0];
|
||||||
let skip = 50;
|
|
||||||
|
|
||||||
applyChaos([0, 0], 200000, ...barnsley, point => {
|
for (let i = 50; i < length; i += 1) {
|
||||||
const x = Math.floor(point[0] * zoom + center[0]);
|
const x = Math.floor(points[i][0] * zoom + center[0]);
|
||||||
const y = height - Math.floor(point[1] * zoom + center[1]);
|
const y = height - Math.floor(points[i][1] * zoom + center[1]);
|
||||||
|
|
||||||
if (x >= 0 && x < width && y >= 0 && y < height && skip <= 0) {
|
if (x >= 0 && x < width && y >= 0 && y < height) {
|
||||||
const i = (y * width + x) * 4;
|
const index = (y * width + x) * 4;
|
||||||
|
|
||||||
image.data[i] = color[0];
|
image.data[index] = color[0];
|
||||||
image.data[i + 1] = color[1];
|
image.data[index + 1] = color[1];
|
||||||
image.data[i + 2] = color[2];
|
image.data[index + 2] = color[2];
|
||||||
image.data[i + 3] = 255;
|
image.data[index + 3] = 255;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
skip -= 1;
|
|
||||||
});
|
|
||||||
|
|
||||||
ctx.putImageData(image, 0, 0);
|
ctx.putImageData(image, 0, 0);
|
||||||
};
|
};
|
||||||
|
@ -70,7 +70,7 @@ const resize = () => {
|
||||||
*/
|
*/
|
||||||
content.on('wheel', event => {
|
content.on('wheel', event => {
|
||||||
const delta = event.deltaMode === 0 ? event.deltaY / 53 : event.deltaY;
|
const delta = event.deltaMode === 0 ? event.deltaY / 53 : event.deltaY;
|
||||||
const newZoom = zoom * (1 - delta * .035);
|
const newZoom = zoom * Math.max(0, 1 - delta * .035);
|
||||||
|
|
||||||
// which (unprojected) point does the mouse point on?
|
// which (unprojected) point does the mouse point on?
|
||||||
const mouse = [
|
const mouse = [
|
||||||
|
@ -113,5 +113,6 @@ content.on('mousemove', event => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
applyChaos(points, 200000, ...barnsley);
|
||||||
window.onresize = resize;
|
window.onresize = resize;
|
||||||
resize();
|
resize();
|
||||||
|
|
Loading…
Reference in New Issue