2021-07-26 03:17:55 +00:00
|
|
|
const { writeFileSync } = require('fs');
|
|
|
|
|
2021-07-26 14:58:16 +00:00
|
|
|
function generateRandomIntegerInRange(min, max) {
|
|
|
|
return Math.floor(Math.random() * (max - min + 1)) + min;
|
|
|
|
}
|
|
|
|
|
2021-07-26 03:17:55 +00:00
|
|
|
const xMax = 1080.0;
|
|
|
|
const yMax = 1920.0;
|
|
|
|
|
2021-07-26 14:58:16 +00:00
|
|
|
const framesMin = 30 * 5;
|
|
|
|
const framesMax = 30 * 60 * 3;
|
2021-07-26 03:17:55 +00:00
|
|
|
|
|
|
|
const distanceMax = 30.0;
|
|
|
|
|
|
|
|
const buffer = 50;
|
|
|
|
|
2021-07-26 14:58:16 +00:00
|
|
|
const xRandStart = generateRandomIntegerInRange(buffer, xMax - buffer);
|
|
|
|
const yRandStart = generateRandomIntegerInRange(buffer, yMax - buffer);
|
|
|
|
|
2021-07-26 03:17:55 +00:00
|
|
|
let xStart = 0;
|
|
|
|
let yStart = 0;
|
|
|
|
let frames = framesMin;
|
|
|
|
let distance = 15.0;
|
|
|
|
let angle = 45;
|
|
|
|
|
|
|
|
let angles = [ 45, 45 + 90, 45 + 180, 45 + 270];
|
|
|
|
|
2021-07-26 14:58:16 +00:00
|
|
|
let searchHit = 100;
|
|
|
|
let iterator = 10;
|
|
|
|
|
|
|
|
function addCommas (num) {
|
|
|
|
let nums = (num + '').split('');
|
|
|
|
let output = '';
|
|
|
|
nums.reverse();
|
|
|
|
output += nums[0];
|
|
|
|
for (let i = 1; i < nums.length; i++) {
|
|
|
|
if (i % 3 === 0) output += ',';
|
|
|
|
output += nums[i];
|
|
|
|
}
|
|
|
|
return output.split('').reverse().join('');
|
|
|
|
}
|
|
|
|
|
|
|
|
function millisecondsToStr (milliseconds) {
|
|
|
|
// TIP: to find current time in milliseconds, use:
|
|
|
|
// var current_time_milliseconds = new Date().getTime();
|
|
|
|
|
|
|
|
function numberEnding (number) {
|
|
|
|
return (number > 1) ? 's' : '';
|
|
|
|
}
|
|
|
|
|
|
|
|
var temp = Math.floor(milliseconds / 1000);
|
|
|
|
var years = Math.floor(temp / 31536000);
|
|
|
|
if (years) {
|
|
|
|
return years + ' year' + numberEnding(years);
|
|
|
|
}
|
|
|
|
//TODO: Months! Maybe weeks?
|
|
|
|
var days = Math.floor((temp %= 31536000) / 86400);
|
|
|
|
if (days) {
|
|
|
|
return days + ' day' + numberEnding(days);
|
|
|
|
}
|
|
|
|
var hours = Math.floor((temp %= 86400) / 3600);
|
|
|
|
if (hours) {
|
|
|
|
return hours + ' hour' + numberEnding(hours);
|
|
|
|
}
|
|
|
|
var minutes = Math.floor((temp %= 3600) / 60);
|
|
|
|
if (minutes) {
|
|
|
|
return minutes + ' minute' + numberEnding(minutes);
|
|
|
|
}
|
|
|
|
var seconds = temp % 60;
|
|
|
|
if (seconds) {
|
|
|
|
return seconds + ' second' + numberEnding(seconds);
|
|
|
|
}
|
|
|
|
return 'less than a second'; //'just now' //or other string you like;
|
|
|
|
}
|
|
|
|
|
|
|
|
let currentDisplay = '';
|
|
|
|
let currentUpdate = 0;
|
|
|
|
function displayTimeLeft (msLeft, percent) {
|
|
|
|
const timeStr = `Time Left: ~${millisecondsToStr(msLeft)}`;
|
|
|
|
const now = +new Date();
|
|
|
|
const rateLimit = msLeft < 60 * 1000 ? (now - currentUpdate > 1000) : (now - currentUpdate > 60 * 1000) ;
|
|
|
|
if (timeStr != currentDisplay && !rateLimit) {
|
|
|
|
currentDisplay = timeStr;
|
|
|
|
currentUpdate = now;
|
|
|
|
console.log(timeStr + ` @ ${Math.round(percent * 10) / 10}%`);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2021-07-26 03:17:55 +00:00
|
|
|
|
|
|
|
function simulate (x, y, frames, angle, distance) {
|
|
|
|
for (let i = 0; i < frames; i++) {
|
|
|
|
x = x + distance * Math.cos(angle * Math.PI / 180.0);
|
|
|
|
y = y + distance * Math.sin(angle * Math.PI / 180.0);
|
2021-07-26 14:58:16 +00:00
|
|
|
|
2021-07-26 03:17:55 +00:00
|
|
|
if (x >= 1080.0 || x <= 0.0) {
|
|
|
|
angle = 180 - angle;
|
|
|
|
}
|
|
|
|
if (x >= 1080.0) x = 1080.0;
|
2021-07-26 14:58:16 +00:00
|
|
|
if (x < 0.0) x = 0.0;
|
2021-07-26 03:17:55 +00:00
|
|
|
if (y >= 1920.0 || y <= 0.0) {
|
|
|
|
angle = 360 - angle;
|
|
|
|
}
|
|
|
|
if (y >= 1920.0) y = 1920.0;
|
2021-07-26 14:58:16 +00:00
|
|
|
if (y < 0.0) y = 0.0;
|
2021-07-26 03:17:55 +00:00
|
|
|
}
|
|
|
|
return { x, y, angle }
|
|
|
|
}
|
|
|
|
|
2021-07-26 14:58:16 +00:00
|
|
|
function simulateAll (xStart, yStart, xLimit, yLimit) {
|
2021-07-26 03:17:55 +00:00
|
|
|
let res;
|
|
|
|
let attempts = 0;
|
|
|
|
let startTime;
|
|
|
|
let duration;
|
|
|
|
let secondsLeft;
|
2021-07-26 14:58:16 +00:00
|
|
|
let pointsTotal = Math.ceil((xLimit - xStart) / iterator) * Math.ceil((yLimit - yStart) / iterator);
|
|
|
|
let searchesTotal = (pointsTotal * angles.length * 10 * Math.ceil( (framesMax - framesMin) / iterator) );
|
|
|
|
let pointsCounter = 0;
|
|
|
|
let rollingAvgDuration = null;
|
|
|
|
console.log(`Simulating ${addCommas(searchesTotal)} possible candidates...`);
|
|
|
|
console.log(``)
|
|
|
|
for (let x = xStart; x < xLimit; x+=iterator ) {
|
|
|
|
for (let y = yStart; y < yLimit; y+=iterator) {
|
2021-07-26 03:17:55 +00:00
|
|
|
startTime = +new Date();
|
2021-07-26 14:58:16 +00:00
|
|
|
//console.time(`${x},${y}`)
|
|
|
|
for (let a = 0; a < angles.length; a++) {
|
2021-07-26 03:17:55 +00:00
|
|
|
for (let d = 0; d < 10; d++) {
|
2021-07-26 14:58:16 +00:00
|
|
|
for (let frames = framesMin; frames < framesMax + 1; frames+=iterator) {
|
2021-07-26 03:17:55 +00:00
|
|
|
angle = angles[a];
|
|
|
|
res = simulate(x, y, frames, angle, distance + d);
|
|
|
|
attempts++;
|
2021-07-26 14:58:16 +00:00
|
|
|
if (Math.abs(res.x - x) < searchHit && Math.abs(res.y - y) < searchHit && ((res.angle == angle) ) ) {
|
2021-07-26 03:17:55 +00:00
|
|
|
console.log(`#${attempts}`);
|
|
|
|
console.log(`startx = ${x} endx = ${res.x}`);
|
|
|
|
console.log(`starty = ${y} endy = ${res.y}`);
|
|
|
|
console.log(`startangle = ${angle}`);
|
|
|
|
console.log(`frames = ${frames}`);
|
|
|
|
console.log(`distance = ${distance + d}`);
|
|
|
|
console.log(`searchHit = ${searchHit}`);
|
|
|
|
console.log("++++++++++++++++++++++++++++++++++++++++");
|
2021-07-26 14:58:16 +00:00
|
|
|
writeFileSync('candidate.json', JSON.stringify({
|
|
|
|
startx : x,
|
|
|
|
starty : y,
|
|
|
|
startangle : angle,
|
|
|
|
startframes : frames,
|
|
|
|
distance : distance + d
|
|
|
|
}) , 'utf-8')
|
2021-07-26 03:17:55 +00:00
|
|
|
return res;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-07-26 14:58:16 +00:00
|
|
|
//console.timeEnd(`${x},${y}`)
|
2021-07-26 03:17:55 +00:00
|
|
|
duration = ((+new Date()) - startTime);
|
2021-07-26 14:58:16 +00:00
|
|
|
if (rollingAvgDuration === null) {
|
|
|
|
rollingAvgDuration = duration;
|
|
|
|
} else {
|
|
|
|
rollingAvgDuration = (rollingAvgDuration + duration) / 2;
|
|
|
|
}
|
|
|
|
msLeft = duration * (pointsTotal - pointsCounter);
|
|
|
|
displayTimeLeft(msLeft, attempts / searchesTotal);
|
|
|
|
pointsCounter++;
|
2021-07-26 03:17:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function main () {
|
|
|
|
let res;
|
2021-07-26 14:58:16 +00:00
|
|
|
let xLimit = xMax - buffer;
|
|
|
|
let yLimit = yMax - buffer;
|
|
|
|
xStart = xRandStart;
|
|
|
|
yStart = yRandStart;
|
2021-07-26 03:17:55 +00:00
|
|
|
for (let i = 0; i < 7; i++) {
|
2021-07-26 14:58:16 +00:00
|
|
|
res = simulateAll(xStart, yStart, xLimit, yLimit);
|
|
|
|
xStart = res.x - searchHit;
|
|
|
|
yStart = res.y - searchHit;
|
|
|
|
xLimit = res.x + searchHit;
|
|
|
|
yLimit = res.y + searchHit;
|
2021-07-26 03:17:55 +00:00
|
|
|
searchHit = Math.floor(searchHit / 2.0);
|
2021-07-26 14:58:16 +00:00
|
|
|
iterator = Math.floor(iterator / 2.0);
|
|
|
|
if (iterator === 0) iterator = 1;
|
2021-07-26 03:17:55 +00:00
|
|
|
if (searchHit === 0) process.exit()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
main();
|