I am trying to make a client-server architecture. I am stuck at the interpolation part. Right now, I have a very naive implementation of the interpolation algorithm. I have every player given a position history and whenever I receive a position data for other player from the server I push the position in to that array. Every client frame I use the oldest position history to interpolate to a new position with a constant speed.
// when new position for other player recieved
p.stateHistory.push(data)
// Every client frame
if(p.stateHistory.length < 1)
return false
let deltaPosition = p.stateHistory[0].position.clone().sub(p.clientPosition)
let direction = Math.atan2(deltaPosition.y, deltaPosition.x)
let velocity = new Vector2(Math.cos(direction), Math.sin(direction)).scale(30/100)
let threshold = 10
if(deltaPosition.magnitude() < threshold) {
p.clientPosition.x = p.stateHistory[0].position.x
p.clientPosition.y = p.stateHistory[0].position.y
p.stateHistory.shift()
} else {
p.clientPosition.add(velocity.clone().scale(deltaTime))
}
I couldn't find way other to interpolate with a constant speed. I came to know about hermite interpolation from gafferongames. But it's sad that the article didn't have anything about its math and its implementation. I tried to go through the wikipedia article on hermite interpolation, but it didn't help. I know nothing about the math behind it. A pseudo code would be appreciated.
What I have been able to do so far: http://client-side-prediction-attempt.herokuapp.com/
Let's say say that your client receives a new position-velocity update at time currentTime. Then, you need to save the current position/velocity, the target position/velocity, the current time, and the time when you expect the next update:
function updateFromServer(position, velocity) {
startP = currentPosition; //the current position of the player
startV = currentVelocity;
endP = position;
endV = velocity;
startT = currentTime; //the current time of the game
endT = startT + 0.1; //expect the next update in 100 ms
}
Once you have stored this data, you can do your frame update using interpolation. If you are outside of the [startT, endT] interval, you might just want to continue a uniform motion:
function frameUpdate(deltaT) {
if(currentTime > endT)
//uniform motion
currentPosition += deltaT * currentVelocity;
else {
//cubic Hermite interpolation
var t = (currentTime - startT) / (endT - startT); //interpolation parameter
var t2 = t * t;
var t3 = t2 * t;
currentPosition =
(2 * t3 - 3 * t2 + 1) * startP +
(t3 - 2 * t2 + t) * (endT - startT) * startV +
(-2 * t3 + 3 * t2) * endP +
(t3 - t2) * (endT - startT) * endV;
currentVelocity = 1 / (endT - startT) * (
(6 * t2 - 6 * t) * startP +
(3 * t2 - 4 * t + 1) * (endT - startT) * startV +
(-6 * t2 + 6 * t) * endP +
(3 * t2 - 2 * t) * (endT - startT) * endV);
}
}
Note that the formulas in this snippet are not valid JavaScript code. They must be translated to whatever library you use.
Related
I am creating my own game engine in Java Script. I have many things working great but one problem I am haveing is converting game space coordinates into screen space coordinates.
In my camera class I calulate the screen position of any given entity like so
draw(Engine, Entity, FollowEntity){
var x = Entity.render_position.x - (FollowEntity.render_position.x - Engine.rendersize.x / 2) - (Entity._get_render_size().x / 2);
var y = Entity.render_position.y - (FollowEntity.render_position.y - Engine.rendersize.y / 2) - (Entity._get_render_size().y / 2);
var _x = Entity.render_position.x - (FollowEntity.render_position.x - Engine.rendersize.x / 2);
var _y = Entity.render_position.y - (FollowEntity.render_position.y - Engine.rendersize.y / 2);
Engine.ctx.save();
Engine.ctx.translate(_x, _y);
Engine.ctx.rotate(Entity.rotation * Math.PI / 180);
Engine.ctx.translate(-_x, -_y);
Engine.ctx.drawImage(Engine.rasterizer.get_cached_img(Entity), x, y); /**/
Engine.ctx.restore();
}
I have tried extensively to aid myself in solving this with ChatGPT to no avail.
here is my current attempt
// Calculate the position of the entity in the game world
var gameX = this.ContextEntity.position.x;
var gameY = this.ContextEntity.position.y;
// Calculate the position of the camera in the game world
var cameraX = this.Engine.follow_entity.position.x;
var cameraY = this.Engine.follow_entity.position.y;
// Calculate the position of the entity on the screen, taking into account the difference in pixel size between the game entities and the GUI elements
var screenX = (gameX - cameraX) * this.GUI.rasterizer.pixel_size / this.Engine.rasterizer.pixel_size;
var screenY = (gameY - cameraY) * this.GUI.rasterizer.pixel_size / this.Engine.rasterizer.pixel_size;
// Adjust the position of the entity on the screen to take into account the size of the entity
screenX -= this.ContextEntity._get_render_size().x / 2;
screenY -= this.ContextEntity._get_render_size().y / 2;
gameToScreen(game) {
var game1 = (typeof game.x !== 'undefined') ? game.x : game[0];
var game2 = (typeof game.y !== 'undefined') ? game.y : game[1];
var x = game1 - (this.control_entity._get_render_midpoint().x - (this.rendersize.x / 2)) / this.rasterizer.pixel_size;
var y = game2 - (this.control_entity._get_render_midpoint().y - (this.rendersize.y / 2)) / this.rasterizer.pixel_size;
return new Vec2(Math.floor(x), Math.floor(y));
}
and here is another previous attempt which only seems to work when my pixel multipliers for the Engine entities are 0
the engine is running at https://soft-crab-57.telebit.io
Any help would be greatly appriciated.
I have one of four possibilities for this particular variable -->
var lowVelocity = Math.random() * (45 - 30) + 30;
var medVelocity = Math.random() * (60 - 45) + 45;
var highVelocity = Math.random() * (80 - 60) + 45;
var hwyVelcoity = Math.random() * (100 - 80) +80;
In one scenario I might have either lowVelocity and medVelocity so I want to choose randomly between those two only. So I did this by:
const velocities = ["lowVelocity", "medVelocity"];
const randomUrban = Math.floor(Math.random() * velocities.length);
And this works - it now chooses one of the two velocities that I am interested in. Low velocity is between 30 and 45 and med is between 45 and 60.
In my innerHTML I want to print the number returned from that variable chosen in the array. When the user clicks this starts a function that has this in it.
document.getElementById("scenario").innerHTML = randomUrban;
But when it prints in the HTML, it doesn't print the number that is associated with the variable, it prints the array number it chose (like 0 or 1).
How do I get the variable (eg if it chose lowVelocity then the number it prints will be the random number lowVelocity found, eg 39) to print instead of the array number?
You could just use a single array to do all of this for you!
If you add the velocities to an array, then the random number can be used as an index into this array. In the code below, we use the length of this array to set the limits for the random number, then you can simply access the value from the velocities array at the position indicated by the random number:
velocities[randomUrban][1]
This gets the sub-array at the position indicated by randomUrban, and [1] gets the second element in the row, i.e. the calculated velocity.
/* Add the velocities to an array or easier management */
var velocities= [
["lowVelocity", Math.random() * (45 - 30) + 30],
["medVelocity", Math.random() * (60 - 45) + 45],
["highVelocity",Math.random() * (80 - 60) + 45],
["hwyVelcoity" ,Math.random() * (100 - 80) +80]
]
/* Pick a random position from the velocities */
const randomUrban = Math.floor(Math.random() * velocities.length);
/* Print the velocity at that position. (Also includes the velocity name for illustration) */
document.getElementById("scenario").innerHTML =
velocities[randomUrban][0] + " = " + velocities[randomUrban][1];
<div id="scenario"></div>
Note: In your example you only use 2 of the 4 velocities, so you can just add the velocities you want to choose from into the randomVelocities array.
In your case just use
document.getElementById("scenario").innerHTML = window[velocities[randomUrban]];
var lowVelocity = Math.random() * (45 - 30) + 30;
var medVelocity = Math.random() * (60 - 45) + 45;
var highVelocity = Math.random() * (80 - 60) + 45;
var hwyVelcoity = Math.random() * (100 - 80) + 80;
const velocities = ["lowVelocity", "medVelocity"];
const randomUrban = Math.floor(Math.random() * velocities.length);
console.log(randomUrban);// random from velocities
console.log(velocities[randomUrban]); //get variable name
console.log(window[velocities[randomUrban]]); // search in scope where the variables are declared in this case window
How about document.getElementById("scenario").innerHTML = velocities[randomUrban]; ?
Well, you are trying to print the wrong variable; randomUrban is the variable containing the velocities array index selected.
A quick (but pretty dirty) fix would be printing eval(velocities[randomUrban]) but eval() has been deprecated because of security issues.
A bit longer but better solution would be grouping your velocities into a single variable of type object and access its keys to retrieve the numeric value:
const velObj = {
lowVelocity: Math.random() * (45 - 30) + 30,
medVelocity: Math.random() * (60 - 45) + 45,
highVelocity: Math.random() * (80 - 60) + 45,
hwyVelocity: Math.random() * (100 - 80) + 80
};
const velocities = ["lowVelocity", "medVelocity"];
const randomUrban = Math.floor(Math.random() * velocities.length);
const velKey = velocities[randomUrban];
document.getElementById("scenario").innerHTML = velObj[velKey];
<div id="scenario"></div>
I want to change color of the dot every time it hits the wall. I saw few solutions, but I don't know why mine isn't working.
Here's the part responsible for changing color:
function chColor() {
hex = Math.floor(Math.random() * 100000 + 1);
color = '"' + "#" + hex + '"';
color.toString();
return color;
}
And here is not working fiddle:
https://jsfiddle.net/vpzd7ye6/
Colour overkill
This answer is way overkill and I was about to discard it, but, why not give a Better random colour for those who may need it... (|:D
When random seams less random
Selecting a random totally random colour for us humans does not work that well if you wish to have a clear distinct change that attracts the eye from one colour to the next.
The problem is that many of the colour values available are very close to white or black and a totally random colour may be very close to the last making the change impossible to notice.
Simple random colour
So first the simple random colour picks a totally random colour from all of the 16,777,216 possible colours.
function randColor(){
return "#" +
(Math.floor(Math.random() * 0x1000000) + 0x1000000)
.toString(16)
.substr(1);
}
The function works by finding a random 24 bit number (0 - 0xFFFFFF same as 0 - 16777216). Because numbers do not have leading zeros added all random values below 0x100000 will, when converted to hex have less than 6 digit (the CSS colour value requires 3 or 6 digit Hex value) so I add 0x1000000 to ensure that the number is > 0x100000 and will always have 7 digits. As the first (left most) digit is not needed I use substr to remove it. Then added the "#" and return.
The function Number.toString(radix) takes an argument called radix which specifies the base the number is converted to. It defaults if not supplied to 10 (base ten is what we humans use). The hex colour is base 16 so that must be specified. The toString radix argument can be any value from 2 (binary) to 36 (which uses characters 0-9 then A-Z)
Less is more Random
Ironically we humans tend to find less random sequences more random than true random sequences. Many music players use this type of random sequence when they have the play set to shuffle, to ensure tracks are not played twice in a row or that repeated sequences of tracks are played by random chance.
To make the random colour seem more random and distinct you should track the last colour return so that you can ensure you are not close to that colour. You should also use a random colour that stays away from the whites and blacks.
var randColour = (function(){ // as singleton so closure can track last colour
var lastHue = 0;
const minChange = 360 / 3; // Hue distance from last random colour
var lastVal = false; // for low high saturation and luminance
const randomAmount = 360 / 3; // random hue range
const minVal = 20; // how far from full black white to stay (percent)
const minSat = 80; // how far from grey to stay (percent)
return function(){
var hueChange = Math.random() * randomAmount ;
hueChange *= Math.random() < 0.5 ? -1 : 1; // randomly move forward or backward
lastHue += 360 + hueChange + minChange; // move away from last colour
lastHue %= 360; // ensure colour is in valid range
var sat = (Math.random() * (100 - minSat)) + minSat; // get saturation (amount of colour)
var val = (Math.random() * (50 - minVal * 2)) * 1.5; // get value (luminance)
// switch between high and low and luminance
lastVal = ! lastVal;
if(lastVal){
val = minVal + val;
} else {
val = 100 - minVal - val;
}
return "hsl(" + lastHue.toFixed(0) + "," + sat.toFixed(0) + "%," + val.toFixed(0) + "%)";
}
})(); // call singleton
This function returns a random colour but ensures that the saturation and value stay within a specific range and that the hue is at least 1/3 around the colour wheel from the last value. It cycles between low and low and high luminance values to make the colour change as clear as possible. Closure is used to keep track of the last colour returned. The function returns the random colour as a CSS hsl(hue, saturation, luminance) color string.
There are two constants that control the colour sequence. minVal set to 20 is the percentage to stay away from full black or full white. Valid range is 0-~50 and minSat set to 80 is how far to stay away from grays in percent.
const minSat = 80; // how far from grey to stay (percent)
Compare change
To compare the two methods the following demo shows side by side a set of random colours using both methods, then flashes a new random colour 4 times a second. The simple random colour will appear from time to time to miss a change. I leave it up to you to pick which side is which.
var canvas = document.createElement("canvas");
canvas.width = 620;
canvas.height = 200;
var ctx = canvas.getContext("2d");
document.body.appendChild(canvas);
var randColour = (function(){ // as singleton so closure can track last colour
var lastHue = 0;
const minChange = 360 / 3; // min hue change
var lastVal = false; // for low high saturation and luminance
const randomAmount = 360 / 3; // amount of randomness
const minVal = 20; // how far from full black white to stay (percent)
const minSat = 80; // how far from grey to stay (percent)
return function(){
var hueChange = Math.random() * randomAmount ;
hueChange *= Math.random() < 0.5 ? -1 : 1; // randomly move forward or backward
lastHue += 360 + hueChange + minChange; // move away from last colour
lastHue %= 360; // ensure colour is in valid range
var sat = (Math.random() * (100 - minSat)) + minSat; // get saturation (amount of colour)
var val = (Math.random() * (50 - minVal * 2)) * 1.5; // get value (luminance)
// switch between high and low and luminance
lastVal = ! lastVal;
if(lastVal){
val = minVal + val;
} else {
val = 100 - minVal - val;
}
return "hsl(" + lastHue.toFixed(0) + "," + sat.toFixed(0) + "%," + val.toFixed(0) + "%)";
}
})(); // call singleton
function randColor(){
return "#" +
(Math.floor(Math.random() * 0x1000000) + 0x1000000)
.toString(16)
.substr(1);
}
const grid = 16;
var gridX = 0;
var gridY = 0;
var bigSize = grid - (grid / 3 ) * 2;
const xStep = Math.floor((canvas.width - 12) / (grid * 2));
const yStep = Math.floor(canvas.height / grid);
var count = 0;
function drawRandomColour(){
ctx.fillStyle = randColor(); // simple random colour
ctx.fillRect(gridX * xStep, gridY * yStep, xStep, yStep);
ctx.fillStyle = randColour(); // smart random colour
ctx.fillRect(gridX * xStep + canvas.width / 2, gridY * yStep, xStep, yStep);
if(count < grid * grid - 1){ // fill the grid
gridX += 1; // move to next grid
if(gridX > grid-1){
gridX = 0;
gridY += 1;
gridY %= grid;
}
count += 1;
setTimeout(drawRandomColour,1); // quickly fill grid
return; // done for now
}
// if grid is full pick a random grid loc and request the next random colour
gridY = gridX = (grid / 3);
setTimeout(centerChange,250); // every quarter second
}
function centerChange(){
ctx.fillStyle = randColor(); // simple random colour
ctx.fillRect(gridX * xStep, gridY * yStep, xStep * bigSize, yStep * bigSize);
ctx.fillStyle = randColour(); // smart random colour
ctx.fillRect(gridX * xStep + canvas.width / 2, gridY * yStep, xStep * bigSize, yStep * bigSize);
setTimeout(centerChange,250); // every quarter second
}
drawRandomColour(); // start it up.
Compare sequences
This demo just draws the random colours as a sequence of random values. Examine the sequences to see how often you see two or more colours in a row that are hard to distinguish between. You will find that the sequence on the left has more similar sequences than the one on the right.
Expand demo to full-page view to see both sequences.
Click to redraw sequences.
var canvas = document.createElement("canvas");
canvas.width = 1240;
canvas.height = 800;
var ctx = canvas.getContext("2d");
document.body.appendChild(canvas);
var randColour = (function(){ // as singleton so closure can track last colour
var lastHue = 0;
const minChange = 360 / 3; // min hue change
var lastVal = false; // for low high saturation and luminance
const randomAmount = 360 / 3; // amount of randomness
const minVal = 20; // how far from full black white to stay (percent)
const minSat = 80; // how far from grey to stay (percent)
return function(){
var hueChange = Math.random() * randomAmount ;
hueChange *= Math.random() < 0.5 ? -1 : 1; // randomly move forward or backward
lastHue += 360 + hueChange + minChange; // move away from last colour
lastHue %= 360; // ensure colour is in valid range
var sat = (Math.random() * (100 - minSat)) + minSat; // get saturation (amount of colour)
var val = (Math.random() * (50 - minVal * 2)) * 1.5; // get value (luminance)
// switch between high and low and luminance
lastVal = ! lastVal;
if(lastVal){
val = minVal + val;
} else {
val = 100 - minVal - val;
}
return "hsl(" + lastHue.toFixed(0) + "," + sat.toFixed(0) + "%," + val.toFixed(0) + "%)";
}
})(); // call singleton
function randColor(){
return "#" +
(Math.floor(Math.random() * 0x1000000) + 0x1000000)
.toString(16)
.substr(1);
}
const grid = 32;
var gridX = 0;
var gridY = 0;
const xStep = Math.floor((canvas.width - 12) / (grid * 2));
const yStep = Math.floor(canvas.height / grid);
var count = 0;
function drawRandomColour(){
ctx.fillStyle = randColor(); // simple random colour
ctx.fillRect(gridX * xStep, gridY * yStep, xStep, yStep);
ctx.fillStyle = randColour(); // smart random colour
ctx.fillRect(gridX * xStep + canvas.width / 2, gridY * yStep, xStep, yStep);
if(count < grid * grid - 1){ // fill the grid
gridX += 1; // move to next grid
if(gridX > grid-1){
gridX = 0;
gridY += 1;
gridY %= grid;
}
count += 1;
setTimeout(drawRandomColour,1); // quickly fill grid
return; // done for now
}
}
drawRandomColour(); // start it up.
// redraw on click
canvas.addEventListener("click",function(){
if(count >= grid * grid - 1){
gridX = gridY = count = 0;
drawRandomColour();
}else {
gridX = gridY = count = 0;
}
});
Summary
Though the second random function is not perfect, It can from time to time get colours that within a context appear similar this occurs much less than by pure random. When it is important for the user to notice a visual changes the best approch is to cycle two complementary colours (hue + 180) with one having a high luminance and the other a low. The CSS hsl colour string makes it easy to pick luminance and hue and when you want random colours gives you better control.
The problem is in converting number to hex color string.
So you can write a function that converts random number to valid hex color (see what this function does):
function convertToColor(num){
return '#' + ('00000' + (num | 0).toString(16)).substr(-6);
}
and then just use it in chColor function:
function chColor() {
number = Math.floor(Math.random() * 100000 + 1);
color = convertToColor(number);
return color;
}
Here is the link with working example: jsfiddle
Also it makes sense to rename function to getRandomColor:
function getRandomColor(){
number = Math.floor(Math.random() * 100000 + 1);
return convertToColor(number);
}
Please check updated fiddle
I just changed your chColor function on this:
function chColor() {
color = "#" + ((1 << 24) * Math.random() | 0).toString(16);
return color;
}
I have updated the fiddle. Link https://jsfiddle.net/vpzd7ye6/2/
I made the following change to your change color function;
function chColor() {
hex = Math.floor(Math.random() * 1000000) + 1;
color = '' + '#' + hex + '';
return color;
}
I am trying to approximate the position of the sun in XYZ for a threejs project.
I am following the maths found here: http://en.wikipedia.org/wiki/Position_of_the_Sun
Following the above, I have written the following Javascript code:
var n = ((2440587.5 + (this.datemillis / 8.64E7)) - 2451545);
var L = 280.460 + 0.9856474 * n;
var g = 357.528 + 0.9856003 * n;
L = (L + 360) % 360;
g = (g + 360) % 60;
var lambda = L + 1.915 * Math.sin(g) + 0.0020 * Math.sin(2 * g);
var r = 1.00014 - 0.01671 * Math.cos(g) - 0.00014 * Math.cos(2 * g);
var e = 23.439 - 0.0000004 * n;
var x = (r * this.constants.EARTH_RADIUS * 2) * Math.cos(lambda);
var y = (r * this.constants.EARTH_RADIUS * 2) * Math.cos(e) * Math.sin(lambda);
var z = (r * this.constants.EARTH_RADIUS * 2) * Math.sin(e) * Math.sin(lambda);
this.datemillis is returned by the getMillisecond function of the Javascript date object. It is updated each frame so that time advances at about 1 hour every 2 seconds.
However something must not be correct as this does not produce the expected result. When I apply the computed x y z coordinates to my sun in my threejs project, I can see the sun rotate around the earth (sitting in 0,0,0) but at a very slow rate (rotating the earth in a few days instead of 24 hours).
I'm thinking it might have something to do with the angle calculations that I'm not doing correctly (degrees/radians?) but I'm not very good at maths so I don't really know what I'm doing so maybe I just misinterpreted the Wiki calculations.
If somebody could spot something obvious I'm doing wrong and help me fix this, would be greatly appreciated!
Thanks
EDIT: so my sun currently is not rotating around the earth in a continous way - it rotates clockwise/counterclockwise alternatively and sometimes jumps positions...
I suggest this to get the Julian Date, from Calculating Jday(Julian Day) in javascript
var today = Date();
var JD = Math.floor((today / 86400000) - (today.getTimezoneOffset()/1440) + 2440587.5);
Add to JD the desired amount of days and increment that value at the desired speed. Note that if you add 1 day each millisecond you'll get 1000 days per second, not 1 hour every 2 seconds.
JD += offset;
Then go on with the wikipedia recipe:
var n = JD - 2451545;
//...
To put L and g in the range 0-360 (you have an error here) use
L = L % 360 + ( L < 0 ? 360 : 0 );
g = g % 360 + ( g < 0 ? 360 : 0 );
The wikipedia formulas express angles in degrees. However JavaScript trigonometric functions cos and sin expect radians.
Just write a "degrees" version of them:
function cosD( deg ) {
return Math.cos( deg * Math.PI / 180.0 );
}
function sinD( deg ) {
return Math.sin( deg * Math.PI / 180.0 );
}
Then use sinD() and cosD() in subsequent calculations.
var r = 1.00014 - 0.01671 * cosD(g) - 0.00014 * cosD(2 * g);
var e = 23.439 - 0.0000004 * n;
var x = (r * this.constants.EARTH_RADIUS * 2) * cosD(lambda);
var y = (r * this.constants.EARTH_RADIUS * 2) * cosD(e) * sinD(lambda);
var z = (r * this.constants.EARTH_RADIUS * 2) * sinD(e) * sinD(lambda);
I cannot answer your question but I do know this is a solved problem in threejs. There is an example running in an architecture/engineering workflow on Github on this topic. The sun position code is here https://github.com/radio412/viewer/blob/gh-pages/sun-position.js
You can see it being tapped for a directional light in threejs at line 108 here: https://github.com/radio412/viewer/blob/gh-pages/va3c-viewer.js
I'm writing a "physics simulation" (so to speak) where using the keyboard arrows one applies forces to a sphere. In this latest iteration I added drag, like the sphere is in the air. Then, for certain values, the drag calculation starts to blow up! The number gets too big, and then Infinity and right after that NaN (cause of the Infinity / Infinity division).
You can see it happening here: http://gool.jit.su/the-drag. Open the console and start moving, left or right. In a few seconds it breaks. You can see in the console the drag value being logged until right before it becomes NaN. (we have a great force and a very small mass)
I'm really trying to understand what is happening and why it is happening, but perhaps there are already information on similar problemas that I was unable to find out or some sort of best practice to keep the number under control... Perhaps choose a value to be my MAX and test agains it every time...
Any idea, help and suggestion is very welcome. I think I am about to learn something important, but still needing a push in the right direction. :)
UPDATE 2: #Beta's test (sorta)
After #Beta's comment I did this test and indeed his calculations seems to show where my simulation breaks apart. (console log velocity in the x axis when the test returns true, false otherwise)
UPDATE 1: Some code
Most "physics" happen here:
update: function update(k, dt) {
var up = k.UP,
right = k.RIGHT,
down = k.DOWN,
left = k.LEFT;
up = up && -this.output;
right = right && this.output;
down = down && this.output;
left = left && -this.output;
this.force.x = left + right;
this.force.y = up + down;
this.calculate_drag(this.velocity);
if (!isNaN(this.drag.x)) {
console.log(this.drag);
}
// this.net_force.x = this.force.x;
// this.net_force.y = this.force.y;
this.net_force.x = this.force.x + this.drag.x;
this.net_force.y = this.force.y + this.drag.y;
this.acceleration.x = this.net_force.x / this.mass;
this.acceleration.y = this.net_force.y / this.mass;
this.velocity.x += this.acceleration.x / (1000 / dt);
this.velocity.y += this.acceleration.y / (1000 / dt);
this.momentum.x = this.mass * this.velocity.x;
this.momentum.y = this.mass * this.velocity.y;
this.position.x += (this.velocity.x * global.METRE) / (1000 / dt);
this.position.y += (this.velocity.y * global.METRE) / (1000 / dt);
this.energy += (abs(this.net_force.x) + abs(this.net_force.y)) / (1000 / dt);
}
And here:
calculate_drag: function calculate_drag() {
var c = 0.47,
a = PI * this.radius * this.radius,
rho = 1.22,
direction = function direction(velocity) {
if (velocity === 0) {
return 1;
}
return velocity / abs(velocity);
};
this.drag.x = -0.5 * c * a * rho * this.velocity.x * this.velocity.x * direction(this.velocity.x);
this.drag.y = -0.5 * c * a * rho * this.velocity.y * this.velocity.y * direction(this.velocity.y);
}
Both methods of gPrototype in gee.js.
You have a cycle in increasing the values of variables. The values will grow very fast. NaN may be the result of some float overflows.
net_force += drag;
drag = velocity * velocity;
velocity += net_force;
And so your "physics" are probably incorrect.