Fix angle resolution
This commit is contained in:
parent
5b861cc341
commit
0101ef8d55
5 changed files with 44 additions and 22 deletions
|
@ -8,6 +8,8 @@
|
||||||
|
|
||||||
// For fixing floating point rounding errors.
|
// For fixing floating point rounding errors.
|
||||||
export const EPSILON = 1e-8;
|
export const EPSILON = 1e-8;
|
||||||
|
// Don't change these.
|
||||||
|
export const TAU = Math.PI * 2;
|
||||||
// Unit length of sector. Only for internal representation.
|
// Unit length of sector. Only for internal representation.
|
||||||
export const SECTOR_SIZE = 512;
|
export const SECTOR_SIZE = 512;
|
||||||
// G, G-boy, The big G, Mr. G, g's big brother, G-dog
|
// G, G-boy, The big G, Mr. G, g's big brother, G-dog
|
||||||
|
|
|
@ -8,15 +8,17 @@ import * as edit from './edit.mjs';
|
||||||
|
|
||||||
export let shipLanded = false;
|
export let shipLanded = false;
|
||||||
|
|
||||||
let notification;
|
let notification = null;
|
||||||
let notLife = 0;
|
let notLife = 0;
|
||||||
|
|
||||||
function notify(message) {
|
function notify(message) {
|
||||||
|
if (notification === null) return;
|
||||||
notification.text = message;
|
notification.text = message;
|
||||||
notLife = 60;
|
notLife = 60;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function tick() {
|
export function tick() {
|
||||||
|
if (notification === null) return;
|
||||||
if (notLife-- <= 0)
|
if (notLife-- <= 0)
|
||||||
notification.text = '';
|
notification.text = '';
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,8 @@ import {render as renderBackground} from './background.mjs';
|
||||||
import * as world from '../world/index.mjs';
|
import * as world from '../world/index.mjs';
|
||||||
import * as consts from '../consts.mjs';
|
import * as consts from '../consts.mjs';
|
||||||
|
|
||||||
|
const TAU = consts.TAU;
|
||||||
|
|
||||||
export let canvas, context, tempCanvas, tempContext;
|
export let canvas, context, tempCanvas, tempContext;
|
||||||
export let perspective;
|
export let perspective;
|
||||||
export let trace = false;
|
export let trace = false;
|
||||||
|
@ -30,6 +32,10 @@ export function render() {
|
||||||
context.fillStyle = '#000';
|
context.fillStyle = '#000';
|
||||||
context.fillRect(0, 0, canvas.width, canvas.height);
|
context.fillRect(0, 0, canvas.width, canvas.height);
|
||||||
|
|
||||||
|
context.beginPath();
|
||||||
|
context.rect(0, 0, canvas.width, canvas.height);
|
||||||
|
context.clip();
|
||||||
|
|
||||||
context.save();
|
context.save();
|
||||||
perspective.tick();
|
perspective.tick();
|
||||||
perspective.transformRotate();
|
perspective.transformRotate();
|
||||||
|
@ -118,7 +124,7 @@ class Perspective {
|
||||||
}
|
}
|
||||||
|
|
||||||
get currentRotation() {
|
get currentRotation() {
|
||||||
return this.interpolate(this.targetRotation, this.oldTarget);
|
return this.interpolateAngles(this.targetRotation, this.oldTarget);
|
||||||
}
|
}
|
||||||
|
|
||||||
get currentZoom() {
|
get currentZoom() {
|
||||||
|
@ -131,15 +137,11 @@ class Perspective {
|
||||||
}
|
}
|
||||||
|
|
||||||
interpolateAngles(cur, old, x = this.transition) {
|
interpolateAngles(cur, old, x = this.transition) {
|
||||||
let a = cur % (Math.PI * 2);
|
return old + this.angleDifference(old, cur) * (1 - x);
|
||||||
let b = old % (Math.PI * 2);
|
}
|
||||||
|
|
||||||
let sum = a + b;
|
angleDifference(a, b) {
|
||||||
|
return Math.atan2(Math.sin(b - a), Math.cos(b - a));
|
||||||
if (sum > (Math.PI * 2) && sum < (Math.PI * 3))
|
|
||||||
sum %= Math.PI;
|
|
||||||
|
|
||||||
return sum / 2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tick() {
|
tick() {
|
||||||
|
@ -195,7 +197,7 @@ class Perspective {
|
||||||
normalize() {
|
normalize() {
|
||||||
this.targetZoom = Math.max(consts.MIN_ZOOM,
|
this.targetZoom = Math.max(consts.MIN_ZOOM,
|
||||||
Math.min(consts.MAX_ZOOM, this.targetZoom));
|
Math.min(consts.MAX_ZOOM, this.targetZoom));
|
||||||
this.targetRotation %= (Math.PI * 2);
|
this.targetRotation %= TAU;
|
||||||
}
|
}
|
||||||
|
|
||||||
transformRotate() {
|
transformRotate() {
|
||||||
|
@ -218,4 +220,8 @@ class Perspective {
|
||||||
context.translate(tx + bw / 2, ty + bh / 2);
|
context.translate(tx + bw / 2, ty + bh / 2);
|
||||||
context.scale(this.zoom, this.zoom);
|
context.scale(this.zoom, this.zoom);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
normalizeAngle(a = this.r) {
|
||||||
|
return ((a % TAU) + TAU) % TAU;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import {GRAVITATIONAL_CONSTANT as G} from '../consts.mjs';
|
import {GRAVITATIONAL_CONSTANT as G, TAU} from '../consts.mjs';
|
||||||
|
|
||||||
export default class Body {
|
export default class Body {
|
||||||
constructor(x, y, mass) {
|
constructor(x, y, mass) {
|
||||||
|
@ -24,6 +24,14 @@ export default class Body {
|
||||||
return Math.sqrt(this.xvel ** 2 + this.yvel ** 2);
|
return Math.sqrt(this.xvel ** 2 + this.yvel ** 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
angleDifference(a, b) {
|
||||||
|
return Math.atan2(Math.sin(a - b), Math.cos(a - b));
|
||||||
|
}
|
||||||
|
|
||||||
|
normalizeAngle(a = this.r) {
|
||||||
|
return ((a % TAU) + TAU) % TAU;
|
||||||
|
}
|
||||||
|
|
||||||
getCelestialCollision(celestials) {
|
getCelestialCollision(celestials) {
|
||||||
let result = false;
|
let result = false;
|
||||||
celestials.forEach(c => {
|
celestials.forEach(c => {
|
||||||
|
@ -51,6 +59,7 @@ export default class Body {
|
||||||
(y * Math.cos(r) - x * Math.sin(r))];
|
(y * Math.cos(r) - x * Math.sin(r))];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Remove and replace uses with `rotateVector`.
|
||||||
relativeVector(x, y) {
|
relativeVector(x, y) {
|
||||||
return this.rotateVector(x, y, this.r);
|
return this.rotateVector(x, y, this.r);
|
||||||
}
|
}
|
||||||
|
|
|
@ -112,24 +112,27 @@ export default class Ship extends Body {
|
||||||
}
|
}
|
||||||
|
|
||||||
resolveCelestialCollision(pos, cel) {
|
resolveCelestialCollision(pos, cel) {
|
||||||
// I don't even know why this works, don't touch it.
|
let celToCom = this.angleTo(...this.com, ...cel.com);
|
||||||
let theta = this.angleTo(...this.com, ...cel.com);
|
let celToPoc = this.angleTo(...pos, ...cel.com);
|
||||||
let angleToCom = this.angleTo(...this.com, ...pos);
|
let pocToCom = this.angleTo(...this.com, ...pos);
|
||||||
let turnAngle = angleToCom - theta;
|
|
||||||
let checkAngle = theta - this.r - Math.PI / 2;
|
let turnAngle = this.angleDifference(celToPoc, pocToCom);
|
||||||
|
let checkAngle = this.angleDifference(celToPoc, this.r + Math.PI / 2);
|
||||||
|
|
||||||
let [force] = this.rotateVector(0, 1, turnAngle);
|
let [force] = this.rotateVector(0, 1, turnAngle);
|
||||||
if (Math.abs(checkAngle) < consts.TIP_ANGLE) {
|
|
||||||
force *= -1;
|
if (Math.abs(checkAngle) < consts.TIP_ANGLE) force *= -1;
|
||||||
}
|
|
||||||
let canLand = Math.abs(checkAngle) < 0.03
|
let canLand = Math.abs(checkAngle) < 0.03
|
||||||
&& Math.abs(this.rvel) < 0.001;
|
&& Math.abs(this.rvel) < 0.001;
|
||||||
|
|
||||||
if (canLand) {
|
if (canLand) {
|
||||||
this.landed = true;
|
this.landed = true;
|
||||||
this.rvel = 0;
|
this.rvel = 0;
|
||||||
this.r = theta - Math.PI / 2;
|
this.r = celToCom - Math.PI / 2;
|
||||||
}
|
}
|
||||||
this.rvel -= force * consts.TIP_SPEED;
|
|
||||||
|
this.rvel += force * consts.TIP_SPEED;
|
||||||
}
|
}
|
||||||
|
|
||||||
checkModuleCollision(module, body) {
|
checkModuleCollision(module, body) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue