How to properly apply a low pass filter in javascript? I'm not sure if my doing is correct or not. And I can't find a good example in javascript language
I tried using this but it returns NaN
// Use a basic low-pass filter to keep only the gravity component of each axis.
var grav_accelX = (acceleration.x * kFilteringFactor) + ( grav_accelX * (1.0 - kFilteringFactor));
var grav_accelY = (acceleration.y * kFilteringFactor) + ( grav_accelY * (1.0 - kFilteringFactor));
var grav_accelZ = (acceleration.z * kFilteringFactor) + ( grav_accelZ * (1.0 - kFilteringFactor));
So what I did is like this. It gives value but I'm not sure if this is the proper way.
const kFilteringFactor = 0.9
var accelX = x * kFilteringFactor
var accelY = y * kFilteringFactor
var accelZ = z * kFilteringFactor
accelX = accelX * (1.0 - kFilteringFactor)
accelY = accelY * (1.0 - kFilteringFactor)
accelZ = accelZ * (1.0 - kFilteringFactor)
The inline grav_accelX variable seems like not working here's the example
Related
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.
If I did not know that side AB was 489.84 or that side BC was 12.66, how could I calculate these two lengths with JavaScript given I had all the other information?
Use the Math.sin and Math.cos functions. Note: these functions accept radians, you would thus need to convert degrees by using rad = deg * Math.PI/180:
Math.cos(88.52 * Math.PI/180) * 490; // 12.655720238100102
Math.sin(88.52 * Math.PI/180) * 490; // 489.83653676022874
Sin(angle) = opposite / hypotenuse
So
opposite = Sin(angle) * hypotenuse
Therefore...
<script>
var angle = 88.52;
var angleInRadians = angle * Math.PI / 180;
var hypotenuse = 490;
var opposite = Math.sin(angleInRadians) * hypotenuse;
console.log('Opposite: ' + opposite);
console.log('Opposite (to 2 decimal places): ' + opposite.toFixed(2));
</script>
You can get the equivalent for the bottom value by using Math.cos instead of Math.sin, of course.
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.
I have this code in JavaScript:
SolarPanels = parseInt(lRemainingWidth / (panel_width + ( 2 * lPanelInterSpace)));
and then I alert the SolarPanels value which gives NaN as output,
alert("SolarPanels "+SolarPanels);
This 1 line is a tiny part of a huge calculation, but my code seems to fail here,
with the use of alerts i've read out the values of SolarPanels, lRemainingWidth, panel_width and lPanelInterSpace
which are the following:
lRemainingwidth = 17.4.320227272727276
SolarPanels = 0
panel_width = 1.65
lPanelInterSpace = 0.02
I think it has to do with the 2 dots in lRemainingWidth, either way, I don't know how to fix it. Why the lRemainingWidth has 2 dots?
Update :
This is the part that calculates the lRemainingWidth :
if(HalforDouble === "Yes")
{
lRemainingWidth = (roof_ridge /2) + ((lRemainingHeight / Math.tan((lRoofEdgeDegrees * Math.PI) / 180)) - lRoofEdge);
}
else
{
lRemainingWidth = roof_ridge + (2 * ((lRemainingHeight / Math.tan((lRoofEdgeDegrees * Math.PI) / 180)) - lRoofEdge));
}
The values here are:
lRemainingWidth = 0
roof_ridge = 17
lRemainingHeight = 20.769000000000002
lRoofEdgeDegrees = 83.5169263071276
lRoofEdge = 0.2
Your problem is that you mix strings and numbers
Start with this code before any computation :
var roof_ridge = parseFloat(roof_ridge);
There might be other strings hidden in your code but we don't see them. Apply the same conversion on them.
lRemainingWidth = roof_ridge + (2 * ((lRemainingHeight / Math.tan((lRoofEdgeDegrees * Math.PI) / 180)) - lRoofEdge));
If roof_ridge is a string then the + does string concatenation instead of addition.
Change this to
lRemainingWidth = +roof_ridge + (2 * ((lRemainingHeight / Math.tan((lRoofEdgeDegrees * Math.PI) / 180)) - lRoofEdge));
The prefix + operator in +roof_ridge coerces its argument to a number.
It seems like a cornerstone of the issue in roof_ridge variable. This variable is instance of String class, not a number. So, when you code go to this line:
lRemainingWidth = roof_ridge + (2 * ((lRemainingHeight / Math.tan((lRoofEdgeDegrees * Math.PI) / 180)) - lRoofEdge));
the next calculation is done:
'17' + whatever_float_value = got string concatenation instead of number's sum.
To fix this just add:
lRemainingWidth = parseFloat(roof_ridge) + (2 * ((lRemainingHeight / Math.tan((lRoofEdgeDegrees * Math.PI) / 180)) - lRoofEdge));