import { RAD } from './enums'; import Random from './random'; const Arc = { create: function(bounds, grids) { let arc = { centerX: Random.num(0, bounds.width), centerY: Random.num(0, bounds.height), clockwise: Random.bool(), endX: 0, endY: 0, length: Random.num(RAD.t90, RAD.t360), radius: Random.num(100, 200), theta: Random.num(RAD.t90, RAD.t360) }; arc.endX = arc.centerX + arc.radius * Math.cos(arc.theta); arc.endY = arc.centerY - arc.radius * Math.sin(arc.theta); arc = Arc.overflow(arc, bounds); const x = arc.endX - arc.endX % 5; const y = arc.endY - arc.endY % 5; // If starting in a hazard, recurse. // if (grids.global[x] !== undefined && grids.global[x][y] !== undefined) { // arc = createArc(bounds, grids); // } return arc; }, step: function(arc, { bounds, speed }) { // Ensure constant velocity and theta between 0 and 2π. const delta = speed / arc.radius; arc.length -= delta; arc.theta += (arc.clockwise ? -delta : +delta); arc.theta = (arc.theta > 0 ? arc.theta % RAD.t360 : RAD.t360 + arc.theta); arc.endX = arc.centerX + arc.radius * Math.cos(arc.theta); // TODO perf here arc.endY = arc.centerY - arc.radius * Math.sin(arc.theta); // TODO perf here // Overflow. arc = Arc.overflow(arc, bounds); return arc; }, randomize: function(arc) { arc.length = Random.num(RAD.t90, RAD.t360); arc = Arc.changeRadius(arc, Random.num(100, 200)); if (Random.bool(0.8)) { arc = Arc.reverse(arc); } return arc; }, overflow: function(arc, bounds) { if (arc.endX < 0) { arc.endX += bounds.width; arc.centerX += bounds.width } else if (arc.endX > bounds.width) { arc.endX -= bounds.width; arc.centerX -= bounds.width } if (arc.endY < 0) { arc.endY += bounds.height; arc.centerY += bounds.height } else if (arc.endY > bounds.height) { arc.endY -= bounds.height; arc.centerY -= bounds.height } return arc; }, changeRadius: function(arc, newRadius) { const r0 = arc.radius; const r1 = newRadius; // Moves arc center to new radius while keeping theta constant. arc.centerX -= (r1 - r0) * Math.cos(arc.theta); // TODO perf here arc.centerY += (r1 - r0) * Math.sin(arc.theta); // TODO perf here arc.radius = r1; return arc; }, reverse: function(arc) { arc.clockwise = !arc.clockwise; arc.theta = (arc.theta + RAD.t180) % RAD.t360; arc.centerX -= (2 * arc.radius) * Math.cos(arc.theta); // TODO perf here arc.centerY += (2 * arc.radius) * Math.sin(arc.theta); // TODO perf here return arc; }, follow: function(arc, arcToFollow) { if (arc.clockwise !== arcToFollow.clockwise) { arc = Arc.reverse(arc); } if (Math.abs(arc.theta - arcToFollow.theta) > 0.1) { arc = Arc.changeRadius(arc, 20); } else { arc = Arc.changeRadius(arc, arcToFollow.radius); } return arc; }, evade: function(arc, visionGrid) { // const danger = visionGrid.reduce((acc, v) => acc || v.touch, false); // // if (danger === false) { // return arc; // } // // const evasionArc = moveArc(arc, 20); // evasionArc.length = 1; // // return evasionArc; } } export default Arc;