diff --git a/js/animation3.js b/js/animation3.js index 49c3c64..ea77234 100644 --- a/js/animation3.js +++ b/js/animation3.js @@ -7,6 +7,8 @@ // number of frames have emitted. A smoothstep cubic curve was considered, but maintaining consistent entry and exit angles will affect // performance for large particle counts. +// Another tricky part was the wall avoidance and vision grid. + // This algorithm travels a random period of time around a random arc. // If a wall is detected, a 180-degree turn is executed. @@ -42,16 +44,26 @@ function move(store) { arc.t += (clockwise ? -delta : +delta); arc.t = (arc.t > 0 ? arc.t % t360 : t360 - arc.t); - const wall = detectWall(store); + const intersections = detectWall(store); + + if (intersections.length > 0) { + const { xs, ys } = intersections.reduce( + ({ xs, ys }, {x, y}) => ({ xs: xs + x, ys: ys + y }), + { xs: 0, ys: 0 } + ); + + const avgX = xs / intersections.length; + const avgY = ys / intersections.length; + + const v = (t90 + Math.atan((particleY - avgY) / (particleX - avgX))) % t90; + const modifier = Math.max(Math.round(v * 180 / Math.PI), 20); - if (wall.x !== null) { - // console.warn(wall.x, wall.y, particleX, particleY) - const x = wall.x - particleX; - const y = wall.y - particleY; - const v = Math.atan((particleY - wall.y) / (particleX - wall.x)); - arc = modifyArc(arc, 40); + arc = modifyArc(arc, modifier); } else { - arc = modifyArc(arc, 400); + if (Math.random() < 0.005) { + console.warn('changing direction') + } + arc = modifyArc(arc, Math.random() * 100 + 100); } particleX = arc.x + arc.r * Math.cos(arc.t); @@ -97,33 +109,23 @@ function detectWall(store) { const gridX = particleX - particleX % 5; const gridY = particleY - particleY % 5; - return visionGridPoints.reduce((acc, { div, x, y, alpha }) => { - const xx = x + gridX; - const yy = gridY - y; + return visionGridPoints.reduce((acc, point) => { + const xx = gridX + point.x; + const yy = gridY - point.y; + const alpha = point.alpha; if (grid[xx] && grid[xx][yy] && grid[xx][yy].type === 'wall') { - if (alpha >= 0 && alpha <= r0) { - if (clockwise === false) { - DOM.addClass(div, 'touching'); - } - return (clockwise ? acc : { x: xx, y: yy }); - } else if (alpha >= arc.t && alpha <= r1) { - if (clockwise === false) { - DOM.addClass(div, 'touching'); - } - return (clockwise ? acc : { x: xx, y: yy }); - } else { - if (clockwise === true) { - DOM.addClass(div, 'touching'); - } - return (clockwise ? { x: xx, y: yy } : acc); + if (clockwise === false && alpha >= 0 && alpha <= r0) { + acc.push(point); + } else if (clockwise === false && alpha >= arc.t && alpha <= r1) { + acc.push(point); + } else if (clockwise === true) { + acc.push(point); } } - DOM.removeClass(div, 'touching'); - return acc; - }, { x: null, y: null }); + }, []); } function transformParticle(store) { @@ -259,7 +261,7 @@ function init() { } const stop$ = Rx.Observable.fromEvent(DOM.container, 'stop'); - const fps$ = Rx.Observable.interval(1000 / 256) + const fps$ = Rx.Observable.interval(1000 / 128) .map(_ => store) // .take(300) // .take(15) diff --git a/js/bundle.js b/js/bundle.js index 0d0afc6..31b9b92 100644 --- a/js/bundle.js +++ b/js/bundle.js @@ -6379,6 +6379,8 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de // number of frames have emitted. A smoothstep cubic curve was considered, but maintaining consistent entry and exit angles will affect // performance for large particle counts. +// Another tricky part was the wall avoidance and vision grid. + // This algorithm travels a random period of time around a random arc. // If a wall is detected, a 180-degree turn is executed. @@ -6408,16 +6410,31 @@ function move(store) { arc.t += clockwise ? -delta : +delta; arc.t = arc.t > 0 ? arc.t % t360 : t360 - arc.t; - var wall = detectWall(store); + var intersections = detectWall(store); + + if (intersections.length > 0) { + var _intersections$reduce = intersections.reduce(function (_ref, _ref2) { + var xs = _ref.xs, + ys = _ref.ys; + var x = _ref2.x, + y = _ref2.y; + return { xs: xs + x, ys: ys + y }; + }, { xs: 0, ys: 0 }), + xs = _intersections$reduce.xs, + ys = _intersections$reduce.ys; + + var avgX = xs / intersections.length; + var avgY = ys / intersections.length; - if (wall.x !== null) { - // console.warn(wall.x, wall.y, particleX, particleY) - var x = wall.x - particleX; - var y = wall.y - particleY; - var v = Math.atan((particleY - wall.y) / (particleX - wall.x)); - arc = modifyArc(arc, 40); + var v = (t90 + Math.atan((particleY - avgY) / (particleX - avgX))) % t90; + var modifier = Math.max(Math.round(v * 180 / Math.PI), 20); + + arc = modifyArc(arc, modifier); } else { - arc = modifyArc(arc, 400); + if (Math.random() < 0.005) { + console.warn('changing direction'); + } + arc = modifyArc(arc, Math.random() * 100 + 100); } particleX = arc.x + arc.r * Math.cos(arc.t); @@ -6467,38 +6484,23 @@ function detectWall(store) { var gridX = particleX - particleX % 5; var gridY = particleY - particleY % 5; - return visionGridPoints.reduce(function (acc, _ref) { - var div = _ref.div, - x = _ref.x, - y = _ref.y, - alpha = _ref.alpha; - - var xx = x + gridX; - var yy = gridY - y; + return visionGridPoints.reduce(function (acc, point) { + var xx = gridX + point.x; + var yy = gridY - point.y; + var alpha = point.alpha; if (grid[xx] && grid[xx][yy] && grid[xx][yy].type === 'wall') { - if (alpha >= 0 && alpha <= r0) { - if (clockwise === false) { - _dom2.default.addClass(div, 'touching'); - } - return clockwise ? acc : { x: xx, y: yy }; - } else if (alpha >= arc.t && alpha <= r1) { - if (clockwise === false) { - _dom2.default.addClass(div, 'touching'); - } - return clockwise ? acc : { x: xx, y: yy }; - } else { - if (clockwise === true) { - _dom2.default.addClass(div, 'touching'); - } - return clockwise ? { x: xx, y: yy } : acc; + if (clockwise === false && alpha >= 0 && alpha <= r0) { + acc.push(point); + } else if (clockwise === false && alpha >= arc.t && alpha <= r1) { + acc.push(point); + } else if (clockwise === true) { + acc.push(point); } } - _dom2.default.removeClass(div, 'touching'); - return acc; - }, { x: null, y: null }); + }, []); } function transformParticle(store) { @@ -6529,11 +6531,11 @@ function transformVisionGrid(store) { var gridX = particleX - particleX % 5; var gridY = particleY - particleY % 5; - visionGridPoints.forEach(function (_ref2, i) { - var x = _ref2.x, - y = _ref2.y, - alpha = _ref2.alpha, - div = _ref2.div; + visionGridPoints.forEach(function (_ref3, i) { + var x = _ref3.x, + y = _ref3.y, + alpha = _ref3.alpha, + div = _ref3.div; if (alpha >= 0 && alpha <= r0) { div.style.display = clockwise ? 'none' : 'block'; @@ -6643,7 +6645,7 @@ function init() { } var stop$ = _rxjs2.default.Observable.fromEvent(_dom2.default.container, 'stop'); - var fps$ = _rxjs2.default.Observable.interval(1000 / 256).map(function (_) { + var fps$ = _rxjs2.default.Observable.interval(1000 / 128).map(function (_) { return store; }) // .take(300)