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.
|
||||
export const EPSILON = 1e-8;
|
||||
// Don't change these.
|
||||
export const TAU = Math.PI * 2;
|
||||
// Unit length of sector. Only for internal representation.
|
||||
export const SECTOR_SIZE = 512;
|
||||
// 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;
|
||||
|
||||
let notification;
|
||||
let notification = null;
|
||||
let notLife = 0;
|
||||
|
||||
function notify(message) {
|
||||
if (notification === null) return;
|
||||
notification.text = message;
|
||||
notLife = 60;
|
||||
}
|
||||
|
||||
export function tick() {
|
||||
if (notification === null) return;
|
||||
if (notLife-- <= 0)
|
||||
notification.text = '';
|
||||
}
|
||||
|
|
|
@ -6,6 +6,8 @@ import {render as renderBackground} from './background.mjs';
|
|||
import * as world from '../world/index.mjs';
|
||||
import * as consts from '../consts.mjs';
|
||||
|
||||
const TAU = consts.TAU;
|
||||
|
||||
export let canvas, context, tempCanvas, tempContext;
|
||||
export let perspective;
|
||||
export let trace = false;
|
||||
|
@ -30,6 +32,10 @@ export function render() {
|
|||
context.fillStyle = '#000';
|
||||
context.fillRect(0, 0, canvas.width, canvas.height);
|
||||
|
||||
context.beginPath();
|
||||
context.rect(0, 0, canvas.width, canvas.height);
|
||||
context.clip();
|
||||
|
||||
context.save();
|
||||
perspective.tick();
|
||||
perspective.transformRotate();
|
||||
|
@ -118,7 +124,7 @@ class Perspective {
|
|||
}
|
||||
|
||||
get currentRotation() {
|
||||
return this.interpolate(this.targetRotation, this.oldTarget);
|
||||
return this.interpolateAngles(this.targetRotation, this.oldTarget);
|
||||
}
|
||||
|
||||
get currentZoom() {
|
||||
|
@ -131,15 +137,11 @@ class Perspective {
|
|||
}
|
||||
|
||||
interpolateAngles(cur, old, x = this.transition) {
|
||||
let a = cur % (Math.PI * 2);
|
||||
let b = old % (Math.PI * 2);
|
||||
return old + this.angleDifference(old, cur) * (1 - x);
|
||||
}
|
||||
|
||||
let sum = a + b;
|
||||
|
||||
if (sum > (Math.PI * 2) && sum < (Math.PI * 3))
|
||||
sum %= Math.PI;
|
||||
|
||||
return sum / 2;
|
||||
angleDifference(a, b) {
|
||||
return Math.atan2(Math.sin(b - a), Math.cos(b - a));
|
||||
}
|
||||
|
||||
tick() {
|
||||
|
@ -195,7 +197,7 @@ class Perspective {
|
|||
normalize() {
|
||||
this.targetZoom = Math.max(consts.MIN_ZOOM,
|
||||
Math.min(consts.MAX_ZOOM, this.targetZoom));
|
||||
this.targetRotation %= (Math.PI * 2);
|
||||
this.targetRotation %= TAU;
|
||||
}
|
||||
|
||||
transformRotate() {
|
||||
|
@ -218,4 +220,8 @@ class Perspective {
|
|||
context.translate(tx + bw / 2, ty + bh / 2);
|
||||
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 {
|
||||
constructor(x, y, mass) {
|
||||
|
@ -24,6 +24,14 @@ export default class Body {
|
|||
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) {
|
||||
let result = false;
|
||||
celestials.forEach(c => {
|
||||
|
@ -51,6 +59,7 @@ export default class Body {
|
|||
(y * Math.cos(r) - x * Math.sin(r))];
|
||||
}
|
||||
|
||||
// TODO: Remove and replace uses with `rotateVector`.
|
||||
relativeVector(x, y) {
|
||||
return this.rotateVector(x, y, this.r);
|
||||
}
|
||||
|
|
|
@ -112,24 +112,27 @@ export default class Ship extends Body {
|
|||
}
|
||||
|
||||
resolveCelestialCollision(pos, cel) {
|
||||
// I don't even know why this works, don't touch it.
|
||||
let theta = this.angleTo(...this.com, ...cel.com);
|
||||
let angleToCom = this.angleTo(...this.com, ...pos);
|
||||
let turnAngle = angleToCom - theta;
|
||||
let checkAngle = theta - this.r - Math.PI / 2;
|
||||
let celToCom = this.angleTo(...this.com, ...cel.com);
|
||||
let celToPoc = this.angleTo(...pos, ...cel.com);
|
||||
let pocToCom = this.angleTo(...this.com, ...pos);
|
||||
|
||||
let turnAngle = this.angleDifference(celToPoc, pocToCom);
|
||||
let checkAngle = this.angleDifference(celToPoc, this.r + Math.PI / 2);
|
||||
|
||||
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
|
||||
&& Math.abs(this.rvel) < 0.001;
|
||||
|
||||
if (canLand) {
|
||||
this.landed = true;
|
||||
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) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue