What I am doing wrong? I donot geting numbers trace shows Infinity
function geolocationUpdateHandler(event: GeolocationEvent): void {
event.latitude.toString();
event.longitude.toString();
trace(lat = event.latitude);
trace(lng = event.longitude);
trace(Star.x = (((lng * Math.PI / 180) - (MinLongitude * Math.PI / 180)) / ((MaxLongitude * Math.PI / 180) - (MinLongitude * Math.PI / 180)) / Map.width));
trace(Star.y = (((lat * Math.PI / 180) - (MinLatitude* Math.PI / 180)) / ((MaxLatitude * Math.PI / 180) - (MinLatitude * Math.PI / 180)) / Map.height));
}
var MinLongitude:int;
MinLongitude = 25.139585;
var MaxLongitude:int;
MaxLongitude = 25.332134;
var MaxLatitude:int;
MaxLatitude = 57.790398;
var MinLatitude:int;
MinLatitude = 57.693223;
I'm sure the long/latitudes return as converted to [text] string. No need for .toString method.
Correct way to trace is example: trace("my latitude is.. " + event.location);
In your code try like this:
trace( "lat = " + event.latitude );
trace( "lng = " + event.longitude );
trace( "Star.x = " + (((lng * Math.PI / 180) - (MinLongitude... etc
trace( "Star.y = " + (((lat * Math.PI / 180) - (MinLatitude... etc
Edit:
I just realised you're casting int as the type for your four vars (var MinLongitude:int etc) but also setting them up with fractional inputs. Int's cannot be fractions or have decimal places so change those types to Number eg: (var MinLongitude:Number) etc. Hopefully now you'll get good results.
Otherwise seems there is nothing with your calculation formula. So minus infinity is strange. I did manual calculation...
Star.x = (((lng * Math.PI / 180) - (MinLongitude * Math.PI / 180)) / ((MaxLongitude * Math.PI / 180) - (MinLongitude * Math.PI / 180)) / Map.width));
in calculator becomes: (assume Map.width = 500, Math.PI = 3.14)...
(25.33213 * 3.14 / 180) - (25.139585 * 3.14 / 180) / (25.332134 * 3.14 / 180) - (25.139585 * 3.14 / 180) / 500
and the result 6.077202837190 etc.... so Star.x = 6.0
Related
Here is my code. For some reason Sheets is saying that the "Split function is not recognized".
function distance3(latlon1, latlon2){
var [lat1, lon1] = split(latlon1,",");
var [lat2, lon2] = split(latlon2,",");
var R = 6371000; // radius of the earth in meters, https://en.wikipedia.org/wiki/Earth_radius
var dLat = (lat2-lat1) * Math.PI / 180; // Convert degrees to radians
var dLon = (lon2-lon1) * Math.PI / 180; // Convert degrees to radians
var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.cos(lat1 * Math.PI / 180 ) * Math.cos(lat2 * Math.PI / 180 ) *
Math.sin(dLon/2) * Math.sin(dLon/2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
var d = R * c;
// Distance in meters, rounded to an integer.
return Math.round(d)*0.000621371;
}
THANK YOU!
Try:
var [lat1, lon1] = latlon1.split(",");
I am implementing consistent hashing and hence drawing a circle with sectors as shown in the Circle Demo. The sectors represents the Nodes.
The HTML withing which my Circle resides is :
<div id="container1">
<div id="svgcontainer"></div>
</div>
Now I want to add some dots(small rings) over the circumference of the circle to show the key-value pair that belong to a particular node.
I am sing HTML5 for my circle.
After adding the data(key value pair my circle) , the circle should have some rings(or any other representations) on its boundary like required circle output
How can I achieve this in HTML5 ?
TIA :)
The dot for a given sector will be positioned at a point (xd,yd) on the circumference half ways between the sector's (x1,y1) and (x2,y2) points. Calculating the dot's position (xd,yd) will be similar to calculating the sector's (x1,y1) and (x2,y2) but with an angle that is half ways between the anlges used for calculating (x1,y1) and (x2,y2). If you wish to place text near the dot and outside the circle then calculating the text's position (xt,yt) will be similar to calculating the dot's position (xd,yd) but with a larger radius. For example, the existing addSector() function could be modified to...
function addSector() {
sector++;
group.clear();
paper.clear();
var start = 0;
var angle = 360 / sector;
var col = 0;
var x1;
var y1;
var x2;
var y2;
var xd;
var yd;
var xt;
var yt;
var i;
var path;
var dot;
var text;
var textPadding = 15;
for (i = 0; i < sector; i++) {
x1 = Math.round((x + Math.cos(start * Math.PI / 180) * radius) * 100) / 100;
y1 = Math.round((y + Math.sin(start * Math.PI / 180) * radius) * 100) / 100;
x2 = Math.round((x + Math.cos((start + angle) * Math.PI / 180) * radius) * 100) / 100;
y2 = Math.round((y + Math.sin((start + angle) * Math.PI / 180) * radius) * 100) / 100;
path = paper.path("M" + x + "," + y + " L" + x1 + "," + y1 + " A" + radius + "," + radius + " 0 0 1 " + x2 + "," + y2 + "z");
path.attr({"fill": colors[col], "stroke" : null});
group.push(path);
col++;
if (col == colors.length) col = 0;
start += angle;
}
for (i = 0; i < sector; i++) {
start = i * angle;
xd = Math.round((x + Math.cos((start + angle / 2) * Math.PI / 180) * radius) * 100) / 100;
yd = Math.round((y + Math.sin((start + angle / 2) * Math.PI / 180) * radius) * 100) / 100;
dot = paper.circle(xd, yd, 5);
dot.attr({"fill": "#FFFFFF", "stoke": "#000000"});
xt = Math.round((x + Math.cos((start + angle / 2) * Math.PI / 180) * (radius + textPadding)) * 100) / 100;
yt = Math.round((x + Math.sin((start + angle / 2) * Math.PI / 180) * (radius + textPadding)) * 100) / 100;
text = paper.text(xt, yt, i.toString());
}
}
I want to draw a cylinder on canvas with control box to re size the cylinder.
Here's some javascript code I created to answer my own question:
function drawCylinder ( x, y, w, h ) {
context.beginPath(); //to draw the top circle
for (var i = 0 * Math.PI; i < 2 * Math.PI; i += 0.001) {
xPos = (this.x + this.w / 2) - (this.w / 2 * Math.sin(i)) *
Math.sin(0 * Math.PI) + (this.w / 2 * Math.cos(i)) *
Math.cos(0 * Math.PI);
yPos = (this.y + this.h / 8) + (this.h / 8 * Math.cos(i)) *
Math.sin(0 * Math.PI) + (this.h / 8 *
Math.sin(i)) * Math.cos(0 * Math.PI);
if (i == 0) {
context.moveTo(xPos, yPos);
}
else
{
context.lineTo(xPos, yPos);
}
}
context.moveTo(this.x, this.y + this.h / 8);
context.lineTo(this.x, this.y + this.h - this.h / 8);
for (var i = 0 * Math.PI; i < Math.PI; i += 0.001) {
xPos = (this.x + this.w / 2) - (this.w / 2 * Math.sin(i)) * Math.sin(0 * Math.PI) + (this.w / 2 * Math.cos(i)) * Math.cos(0 * Math.PI);
yPos = (this.y + this.h - this.h / 8) + (this.h / 8 * Math.cos(i)) * Math.sin(0 * Math.PI) + (this.h / 8 * Math.sin(i)) * Math.cos(0 * Math.PI);
if (i == 0) {
context.moveTo(xPos, yPos);
}
else
{
context.lineTo(xPos, yPos);
}
}
context.moveTo(this.x + this.w, this.y + this.h / 8);
context.lineTo(this.x + this.w, this.y + this.h - this.h / 8);
context.stroke();
}
Thank you! This is just what I was looking for. While implementing your function in my own code I made some changes like passing in the canvas context as an argument, simplifying the math and getting the code to pass JSLint.
function drawCylinder(ctx, x, y, w, h) {
'use strict';
var i, xPos, yPos, pi = Math.PI, twoPi = 2 * pi;
ctx.beginPath();
for (i = 0; i < twoPi; i += 0.001) {
xPos = (x + w / 2) - (w / 2 * Math.cos(i));
yPos = (y + h / 8) + (h / 8 * Math.sin(i));
if (i === 0) {
ctx.moveTo(xPos, yPos);
} else {
ctx.lineTo(xPos, yPos);
}
}
ctx.moveTo(x, y + h / 8);
ctx.lineTo(x, y + h - h / 8);
for (i = 0; i < pi; i += 0.001) {
xPos = (x + w / 2) - (w / 2 * Math.cos(i));
yPos = (y + h - h / 8) + (h / 8 * Math.sin(i));
if (i === 0) {
ctx.moveTo(xPos, yPos);
} else {
ctx.lineTo(xPos, yPos);
}
}
ctx.moveTo(x + w, y + h / 8);
ctx.lineTo(x + w, y + h - h / 8);
ctx.stroke();
}
If you want to draw a 3D cylinder, the easiest way is to use a library like tQuery (http://jeromeetienne.github.com/tquery/) :
var world = tQuery.createWorld().boilerplate().start();
var object = tQuery. createCylinder().addTo(world);
If you want to draw a '2d' cylinder, you can do so using canvas 2d API to draw a rectangle then a elipse in top of it. It will appear as a cylinder.
var canvas = document.getElementById('canvas')
var ctx = canvas.getContext('2d');
var pos={};
const angleToRadian = function (angle) {
return Math.PI / 180 * angle;
}
var Arc = function (x, y, r, d,s) {
this.r = r;
this.x = x;
this.y = y;
// this.d=d;
ctx.beginPath();
ctx.arc(x, y, r, angleToRadian(0), angleToRadian(180));
ctx.moveTo((Number(x) + Number(r)), y);
// ctx.lineTo((Number(x) + Number(r)), d);
ctx.arc(x, y - d, r, angleToRadian(0), angleToRadian(360));
ctx.moveTo((Number(x)+Number(r)),y);
ctx.lineTo((Number(x)+Number(lX())), ((Number(y)-Number(d))+Number(r)-Number(lY())));
// ctx.moveTo((Number(x)+Number(lX())), ((Number(y)-Number(d))-Number(lY())+Number(r)));
ctx.lineTo((Number(x)+Number(lX())),(Number(y)+Number(r)-Number(lY())));
// ctx.moveTo((Number(x)+Number(lX())),(Number(y)+Number(r)-Number(lY())));
ctx.lineTo(Number(x), ((Number(y)+Number(r))-Number(d)));
// ctx.moveTo(Number(x), ((Number(y)+Number(r))-Number(d)));
ctx.lineTo(Number(x),(Number(y)+Number(r)));
// ctx.moveTo(Number(x),(Number(y)+Number(r)));
ctx.lineTo((Number(x)-Number(lX())), (Number(y)-Number(d)+Number(r)-Number(lY())));
// ctx.moveTo((Number(x)-Number(lX())), (Number(y)-Number(d)+Number(r)-Number(lY())));
ctx.lineTo((Number(x)-Number(lX())), (Number(y)+Number(r)-Number(lY())));
// ctx.moveTo((Number(x)-Number(lX())), (Number(y)+Number(r)-Number(lY())));
ctx.lineTo((Number(x)-Number(r)), (Number(y)-Number(d)));
// ctx.moveTo((Number(x)-Number(r)), (Number(y)-Number(d)));
ctx.lineTo((Number(x)-Number(r)), y);
ctx.strokeStyle = "#9c3028";
ctx.closePath();
// ctx.stroke();
ctx.fillStyle="#9b3028"
ctx.fill();
}
var lY = function () {
return Math.sqrt((Math.pow(((Math.cos(67.5 * Math.PI / 180) * this.r) * 2), 2) -
Math.pow((Math.cos(22.5 * Math.PI / 180) * (Math.cos(67.5 * Math.PI / 180) * this.r) * 2), 2)));
}
var lX = function () {
return Math.sqrt((Math.pow(((Math.cos(67.5 * Math.PI / 180) * this.r) * 2), 2) - (Math.pow(((Math.cos(67.5 * Math.PI / 180) * this.r) * 2), 2) -
Math.pow((Math.cos(22.5 * Math.PI / 180) * (Math.cos(67.5 * Math.PI / 180) * this.r) * 2), 2))));
}
document.addEventListener('mouseup',mouseUp);
document.addEventListener('mousedown',mouseDown);
document.addEventListener('mousemove',draw);
function mouseDown(e){
pos.x=e.clientX;
pos.y=e.clientY;
}
function mouseUp(e){
pos.pozX=e.clientX;
pos.pozY=e.clientY;
}
function draw(e){
if(e.buttons!==1) return;
ctx.clearRect(0,0,500,500);
Arc(pos.x, pos.y, e.clientY, e.clientX);
}
distance (straight)
from: (lat) 48.73233 (long) 2.36618
to: lat() 48.84647 (long) 2.41026
equals some: 13096.16 meters
If I use PHP formula, I get proper result.
But when I translate same PHP formula directly into MySQL query - I get 5904.2757 etc.
Here is the code:
php:
$distance = atan2(sqrt(pow(sin((($to_lat - $from_lat) * M_PI / 180) / 2), 2) +
cos(($from_lat * M_PI / 180)) * cos(($to_lat * M_PI / 180)) *
pow(sin((($to_long - $from_long) * M_PI / 180) / 2), 2)), sqrt(1 - (pow(sin((($to_lat - $from_lat) * M_PI / 180) / 2), 2) +
cos(($from_lat * M_PI / 180)) * cos(($to_lat * M_PI / 180)) *
pow(sin((($to_long - $from_long) * M_PI / 180) / 2), 2)))) * 2 * $radiusOfEarth;
mysql:
atan2(sqrt(pow(sin(((ap.Latitude - $from_lat) * pi() / 180) / 2), 2) +
cos(($from_lat * pi() / 180)) * cos((ap.Latitude * pi() / 180)) *
pow(sin(((ap.Longitude - $from_long) * pi() / 180) / 2), 2)), sqrt(1 - (pow(sin(((ap.Latitude - $from_lat) * pi() / 180) / 2), 2) +
cos(($from_lat * pi() / 180)) * cos((ap.Latitude * pi() / 180)) *
pow(sin(((ap.Longitude - $from_long) * pi() / 180) / 2), 2)))) * 2 * 6371000 as Distance
The exact thing you want.
SELECT ((ACOS(SIN(48.73233 * PI() / 180) * SIN(48.84647 * PI() / 180) + COS(48.73233 * PI() / 180) *
COS(48.84647 * PI() / 180) * COS((2.36618 - 2.41026) * PI() / 180)) * 180 / PI()) * 60 *1.1515 * 1.609344 *1000)
AS distance FROM dual;
I need a function that returns a longitude value given a lat/lon coordinate, a distance in miles, and an intersecting latitude. To do that I need to use Halversine, like discussed here:
https://stackoverflow.com/a/7179026/78202. I realize that there will be two longitudes that intersect a given latitude a given distance from another ordered pair, I'd just like to get the point where I have a function that correctly returns one of them and I'll decide how to break the tie then.
I casually solved Holversine for lon1, and here's what I have. This is partly a math question, partly a programming question - what is wrong with this? There's no syntax error, I'm just not getting what I expect (see below).
function toRad(Value) {
/** Converts numeric degrees to radians */
return Value * Math.PI / 180;
}
/** returns the longitude a certain number of miles from another point given a latitude. **/
function getLon(miles, lat1, lat2, lon2) {
// see http://www.movable-type.co.uk/scripts/latlong.html
//Radius of the earth in: 1.609344 miles, 6371 km | var R = (6371 / 1.609344);
var R = 3958.7558657440545; // Radius of earth in Miles
miles = (typeof miles === "undefined") ? 1.46628357399041 : miles;
lat1 = (typeof lat1 === "undefined") ? 42.34769 : lat1;
lat2 = (typeof lat2 === "undefined") ? 42.367137 : lat2;
lon2 = (typeof lon2 === "undefined") ? -71.124383 : lon2;
var dLat = toRad( lat2-lat1 );
var sinInsideN1 = Math.sin(dLat);
var sinInsideN2 = Math.sin(miles/2*R);
var n1 = Math.pow(sinInsideN1,2);
var n2 = Math.pow(sinInsideN2,2);
var d1 = Math.cos(lat1)*Math.cos(lat2);
var inArcsin = Math.sqrt((n2-n1)/d1);
var translation = inArcsin-Math.floor(inArcsin);
var ret = -(lat1+2*Math.asin(translation))
return ret; // should be 42.34769
}
I'm getting 42.242513701215, which forms a coordinate with 42.34769 that is 8.63065661614176 mi from (42.367137,-71.124383), not 1.46628357399041 mi as expected.
I found an C-implementation of Haversine here http://code.google.com/p/siklon/source/browse/trunk/source/Haversine.c?r=11, which I have then rewritten wrt lon1:
#include <math.h>
/*Earth Radius in Kilometers.*/
/* static const double R = 6372.797560856; */
/*Earth Radius in Miles.*/
static const double R = 3958.7558657440545;
/*Degree vs. Radian conservation variables*/
static const double DEG_TO_RAD = M_PI/180.0;
static const double RAD_TO_DEG = 180.0/M_PI;
double Haversine_Distance(double lat1,double lon1, double lat2, double lon2)
{
double dlon = (lon2 - lon1) * DEG_TO_RAD;
double dlat = (lat2 - lat1) * DEG_TO_RAD;
double a = pow(sin(dlat * 0.5),2) + cos(lat1*DEG_TO_RAD) * cos(lat2*DEG_TO_RAD) * pow(sin(dlon * 0.5),2);
double c = 2.0 * atan2(sqrt(a), sqrt(1-a));
return R * c;
}
double inverseHaversine_Distance_lon1(double lat1, double dist, double lat2, double lon2)
{
/* Rewrite Haversine_Distance wrt lon1: */
/* dist = R * c = R * 2.0 * atan2(sqrt(a), sqrt(1-a)) */
/* dist / R / 2.0 = atan2(sqrt(a), sqrt(1-a)) */
/* sqrt(a) = sin(dist / R / 2.0); sqrt(1-a) = cos(dist / R / 2.0) */
/* a = (sin(dist / R / 2.0))^2; 1 - a = (cos(dist / R / 2.0))^2 */
/* pow(sin(dlat * 0.5),2) + cos(lat1*DEG_TO_RAD) * cos(lat2*DEG_TO_RAD) * pow(sin(dlon * 0.5),2) = (sin(dist / R / 2.0))^2 */
/* cos(lat1*DEG_TO_RAD) * cos(lat2*DEG_TO_RAD) * pow(sin(dlon * 0.5),2) = (sin(dist / R / 2.0))^2 - pow(sin(dlat * 0.5),2) */
/* pow(sin(dlon * 0.5),2) = (pow(sin(dist / R / 2.0), 2) - pow(sin(dlat * 0.5), 2)) / (cos(lat1*DEG_TO_RAD) * cos(lat2*DEG_TO_RAD)) */
/* sin(dlon * 0.5) = sqrt((pow(sin(dist / R / 2.0), 2) - pow(sin(dlat * 0.5), 2)) / (cos(lat1*DEG_TO_RAD) * cos(lat2*DEG_TO_RAD))) */
/* dlon = (lon2 - lon1) * DEG_TO_RAD = asin(sqrt((pow(sin(dist / R / 2.0), 2) - pow(sin(dlat * 0.5), 2)) / (cos(lat1*DEG_TO_RAD) * cos(lat2*DEG_TO_RAD)))) * 2.0 */
/* lon2 - lon1 = asin(sqrt((pow(sin(dist / R / 2.0), 2) - pow(sin(dlat * 0.5), 2)) / (cos(lat1*DEG_TO_RAD) * cos(lat2*DEG_TO_RAD)))) * 2.0 / DEG_TO_RAD*/
/* lon1 = lon2 - asin(sqrt((pow(sin(dist / R / 2.0), 2) - pow(sin(dlat * 0.5), 2)) / (cos(lat1*DEG_TO_RAD) * cos(lat2*DEG_TO_RAD)))) * 2.0 / DEG_TO_RAD*/
double dlat = (lat2 - lat1) * DEG_TO_RAD;
return lon2 - asin(sqrt((pow(sin(dist / R / 2.0), 2) - pow(sin(dlat * 0.5), 2)) / (cos(lat1*DEG_TO_RAD) * cos(lat2*DEG_TO_RAD)))) * 2.0 * RAD_TO_DEG;
}
int main()
{
double lat1 = 42.34769;
double dist = 1.46628357399041;
double lat2 = 42.367137;
double lon2 = -71.124383;
double lon1 = inverseHaversine_Distance_lon1(lat1, dist, lat2, lon2);
printf("lon1 %f\n", lon1);
printf("dist %f\n", Haversine_Distance(lat1, lon1, lat2, lon2));
}
The result:
gcc inverse_haversine.c -lm
./a.out
lon1 -71.135880
dist 1.466284
It may be possible to reduce the expression...
At least lat1, lat2 and lon2 has to be converted into radians before calling the trigonometric functions! But maybe there are more problems... :)
Example: Using the simple version I got this code i C:
#include <math.h>
#define METERS_PER_DEGREE_EQUATOR 111319.5
#define MILES_PER_DEGREE_EQUATOR (METERS_PER_DEGREE_EQUATOR / 1000.0 / 1.609344)
/* Select preferred unit: */
#define UNITS_PER_DEGREE_EQUATOR MILES_PER_DEGREE_EQUATOR
double horDist(double lat1, double lon1, double lat2, double lon2)
{
/* From "Note on conversion from decimal degrees to meters"
* (http://southport.jpl.nasa.gov/GRFM/cdrom/2a/DOCS/HTML/GEOLOC/METERS.HTM)
* NOTE: BELOW IS ONLY PRECISE IF THE TWO LATITUDES ARE NOT TOO DISTANT! */
double latDelta = UNITS_PER_DEGREE_EQUATOR * (lat1 - lat2);
double lonDelta = UNITS_PER_DEGREE_EQUATOR * (lon1 - lon2) * cos(lat1 * M_PI / 180);
return sqrt(latDelta * latDelta + lonDelta * lonDelta);
}
double invHorDist_lon1(double lat1, double dist, double lat2, double lon2)
{
/* Rewrite horDist wrt lon1: */
/* (dist * dist) = (latDelta * latDelta) + (lonDelta * lonDelta); */
/* (dist * dist) - (latDelta * latDelta) = (lonDelta * lonDelta); */
/* sqrt((dist * dist) - (latDelta * latDelta)) = lonDelta = UNITS_PER_DEGREE_EQUATOR * (lon1 - lon2) * cos(lat1 * M_PI / 180); */
/* sqrt((dist * dist) - (latDelta * latDelta)) / UNITS_PER_DEGREE_EQUATOR / cos(lat1 * M_PI / 180) = (lon1 - lon2); */
double latDelta = UNITS_PER_DEGREE_EQUATOR * (lat1 - lat2);
return sqrt((dist * dist) - (latDelta * latDelta)) / UNITS_PER_DEGREE_EQUATOR / cos(lat1 * M_PI / 180) + lon2;
}
int main()
{
double lon1 = invHorDist_lon1(42.34769, 1.46628357399041, 42.367137, -71.124383);
printf("lon1 %f\n", lon1);
printf("dist %f\n", horDist(42.34769, lon1, 42.367137, -71.124383));
}
And the result is:
gcc haversine.c -lm
./a.out
lon1 -71.112968
dist 1.466284
But again this simple version does not fit if the two latitudes are too distant. But try rewrite Haversine again and convert to radians whenever you use trigonometric functions.