I recently came across a YouTube video that discussed handling GPS coordinates by using space filled curves. There was a formula provided to accomplish this so I've decided to try and replicate it, however I have not been able to figure out how to get to the same result using JavaScript.
The formula was as follows:
Scale Latitude and longitude to use 16 available bits each:
scaled_x = (-122.4012 + 180) / 360 * 2 ^ 16 // result = 10485
scale_y = (37.7839 + 90) / 180 * 2 ^ 16 // result = 46524
Video Reference
I've tries several ways of writing the formula and my results are far off from what I should be getting based on what was shown in the presentation. Either the presentation was inaccurate or I've not landed on the correct way of getting to this.
Here are some of my attempts, all fail.
Using Pow
base = Math.round((lat + 180) / 360);
scale = Math.pow(base * 2, 16); // Result = 0
Exact Formula
base = Math.round((lat + 180) / 360 * 2 ^ 16); // Result = 16
Inline Power
base = Math.round((lat + 180) / 360 * Math.pow(2, 16)); // Result = -22282
Does anyone know how this formula needs to be structured in JavaScript to get the expected outcome?
base = Math.round((lat + 180) / 360);
scale = Math.pow(base * 2, 16)
This doesn't work because you're rounding the value before multiplying it by 216 -- so it will round to either 0 or 1. This is not what you want.
base = Math.round((lat + 180) / 360 * 2 ^ 16);
In Javascript -- and many other languages -- ^ is used for bitwise XOR, not exponentiation. 2 ^ 16 is 18, not 65536.
base = Math.round((lat + 180) / 360 * Math.pow(2, 16));
This looks correct. The result you've quoted isn't right for lat = -122.4012, though -- did you leave out the + 180, perhaps?
Related
Referring to the first diagram, I am trying to copy the three objects, looking at them from an arbitrary angle(A1). The distance between where I'm and the first object does not matter just the relative location of the object to one another.
In the second diagram, I select a point to copy these objects, facing another arbitrary angle(B1).
Angle (C1) shows the approximate position of -90 degrees.
I can get this to work if A1 = 0,90,180,270 and even 45,135 etc but the equations I come up with only work for 0 and 180 or 90 and 270. I have to modify them to work in those directions by changing a hardcoded offset angle and putting/removing a negative sign before the offset.
I'm doing this is javascript (and its Minecraft) usually I can figure out this but I have been working on it for weeks.
Here is some pseudo-code that works some of the time in certain right-angle directions. I have updated this to be more accurate, the 1x and 2x are the blocks x coordinate, etc. - everything is relative from the (1) block.
Minecraft's coordinate system is a little different from normal - 0 is south, +90 is west, 180 is north, 270 is east.
the only difference is that I am making negative az, ax.
// works for north/south looking - A1 is either 180/0 , B1 can be anything
var x = 1x - 2x;
var z = 1z - 2z;
var direction = Math.atan2(z1, x1);
var L1 = Math.sqrt(Math.pow(x1, 2) + Math.pow(z1, 2));
var az = Math.round(L1 * Math.sin((B1 + A1 + (direction * 180 / Math.PI)) * Math.PI / 180));
var ax = Math.round(L1 * Math.cos((B1 + A1 + (direction * 180 / Math.PI)) * Math.PI / 180));
// works for east/west looking - A1 is either 90/270 , B1 can be anything
var x = 1x - 2x;
var z = 1z - 2z;
var direction = Math.atan2(z1, x1);
var L1 = Math.sqrt(Math.pow(x1, 2) + Math.pow(z1, 2));
var az = -Math.round(L1 * Math.sin((B1 + A1 + (direction * 180 / Math.PI)) * Math.PI / 180));
var ax = -Math.round(L1 * Math.cos((B1 + A1 + (direction * 180 / Math.PI)) * Math.PI / 180));
First diagram
Second diagram
I'm working on a project to solve triangles, but I cant seem to figure out how to get the inverse of sine, I've already set up switching from radians to degrees in my program I just need inverse operators.
Simply use Math.asin:
Math.asin(opposite / hypotenuse);
Math.sin(x) takes a radian and outputs a range [-1 , 1].
Math.asin(x) takes a range [-1 , 1] and outputs a radian value.
To convert these radian values, use these two functions:
degreeToRadian = d => d * Math.PI * 180 ** -1
radianToDegree = r => r * 180 * Math.PI ** -1
For example:
Math.sin(degreeToRadian(30)).toFixed(3) * 1
results -> 0.5
or:
radianToDegree(Math.asin(0.5)).toFixed(3) * 1
results -> 30
I am trying to draw polar curves on HTML canvas using Javascript. What should I do when I want to convert plus-minus sign (±)?
Example: Watt's curve
Below is what I tried. Since I need to get value of r, I enclose entire equation with square root, also I use it's absolute value, otherwise I get null for trying to get square root if number is negative. Following code draws something that looks like a polar curve, but not Watt's curve.
var a = 1;
var b = 1;
var c = 2;
r = Math.sqrt(Math.abs(Math.pow(b, 2) - Math.pow(a * Math.sin(t) * Math.sqrt(Math.abs(Math.pow(c, 2) - Math.pow(a, 2) * Math.pow(Math.cos(t), 2), 2)), 2) ));
I get similar deviations of expected results with other equations containing plus-minus sign (ones without it work fine), so I suppose the problem is that I wrongly 'translate' this symbol. What do I do wrong?
It looks like there is an incorrect multiplication of a squared theta with the inner square root (Math.sin(t) * Math.sqrt(...)).
To plot the equation, convert the plus-minus sign into two equations:
var a = 1;
var b = 1;
var c = 2;
var b2 = Math.pow(b, 2);
var asint = a * Math.sin(t);
var sqroot = Math.sqrt(Math.pow(c, 2) - Math.pow(a, 2) * Math.pow(Math.cos(t), 2), 2);
var r = Math.sqrt(b2 - Math.pow(asint + sqroot, 2));
// now plot r
r = Math.sqrt(b2 - Math.pow(asint - sqroot, 2));
// now plot r again
The Math.abs() shouldn't be necessary.
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
The Formula looks like this:
(25000 x (.06 / 12)) / (1 - ((1 + (.06 / 12))^(-36))) = 760.548436
I have been attempting to convert this to javascript but with not much luck. If you put that above formula into google you will see the answer.
After many attempts and different methods, braking up the formula into different variables then dividing them, I haven't had any luck, when I came up with this, it got me the wrong answer:
var loan = 25000;
var rate = 6 / 100;
var term = 36;
var calculate = (loan * (rate / 12)) / (1 - ((1 + (rate / 12))^(-term)));
console.log(calculate);
Output was:
3.4722222222222223
And not 760.548436. Anyone have any ideas?
The caret is a bitwise operator. You want this formula instead:
calculate = (loan * (rate / 12)) / (1 - Math.pow(1 + (rate / 12), -term));
It gives you the answer you expect, 760.5484362888927