Is there a way to rotate the object with the property rotation, and then calculate its x and y coordinates as if it was turned around some point
without measurement accuracy?
public static function pointRotate (object:DisplayObject, center:Point,angle:Number) : void
{
var r:Number = angle * Math.PI / 180;
var s:Number = Math.sin(r);
var c:Number = Math.cos(r);
var dX:Number = object.x - center.x;
var dY:Number = object.y - center.y;
object.rotation += angle;
object.x = center.x + dX * c - dY * s;
object.y = center.y + dX * s + dY * c;
}
package
{
import flash.geom.Point;
import flash.display.DisplayObject;
public function pointRotate(object:DisplayObject, center:Point, angle:Number) : void
{
// return to zero
angle += object.rotation;
var a0:Number = - object.rotation * Math.PI / 180;
var s0:Number = Math.sin(a0);
var c0:Number = Math.cos(a0);
var dX0:Number = object.x - center.x;
var dY0:Number = object.y - center.y;
object.rotation = 0;
object.x = Math.round(center.x + dX0 * c0 - dY0 * s0);
object.y = Math.round(center.y + dX0 * s0 + dY0 * c0);
// new rotation
var r:Number = angle * Math.PI / 180;
var s:Number = Math.sin(r);
var c:Number = Math.cos(r);
var dX:Number = object.x - center.x;
var dY:Number = object.y - center.y;
object.rotation += angle;
object.x = center.x + dX * c - dY * s;
object.y = center.y + dX * s + dY * c;
}
}
i am going to develop a location service app i have the application part now i have the work on server side for this i have to calculate the distance between 2 points
for ex(point 1 to point 2 distance = 1 km) and i have got a code when i tried implementing the code shows wrong distance actual km is 1 but the code shows 300 meters.
Can anybody say me why this happens?
Thank you..
Why c# if you can achieve it by javascript
var R = 6371; // km
var dLat = (lat2-lat1).toRad();
var dLon = (lon2-lon1).toRad();
var lat1 = lat1.toRad();
var lat2 = lat2.toRad();
var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.sin(dLon/2) * Math.sin(dLon/2) * Math.cos(lat1) * Math.cos(lat2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
var d = R * c;
If I'd like to make a circle with particles, I'd define random coordinates for particles like this:
for(var i:int = 0; i != 100; i++)
{
var angle:Number = Math.random() * 360;
var r:Number = 600;
var nX:Number = r * Math.cos(angle / 180 * Math.PI);
var nY:Number = r * Math.sin(angle / 180 * Math.PI);
}
But I want to make a ball with particles on 3d space but I don't know how to define random coordinates for particles. Radius is fixed again but there should be a "nZ" value. Can you help me to define these coordinates?
for(var i:int = 0; i != 100; i++)
{
var angle:Number = Math.random() * 360;
var r:Number = 600;
var nX:Number = ???
var nY:Number = ???
var nZ:Number = ???
}
Thanks in advance...
Spherical coordinates are what you want.
You need two angles:
for(var i:int = 0; i != 100; i++)
{
var azimuthAngle:Number = Math.random() * 360;
var elevationAngle:Number = (Math.random() * 180) - 90;
var r:Number = 600;
var nX:Number =
r * Math.cos(azimuthAngle / 180 * Math.PI) * Math.sin(elevationAngle / 180 * Math.PI);
var nY:Number =
r * Math.sin(azimuthAngle / 180 * Math.PI) * Math.sin(elevationAngle / 180 * Math.PI);
var nZ:Number =
r * Math.cos(elevationAngle / 180 * Math.PI);
}
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.
How can I create a polygon(only a square in my case) around a given point(lat/lang) x meters around the given point. It's just a visual representation of a geofence but I dont need all the calculations whether a point is outside a geofence or not. I tried using the code below but its creating a rectangle instead of a square and I'm not even sure if the 1000 meter boudaries are being rendered correctly.
var map = new GMap2(document.getElementById("map_canvas"));
map.setCenter(new GLatLng(37.4419, -122.1419), 13);
map.addControl(new GSmallMapControl());
GEvent.addListener(map, 'click', function(overlay, latlng) {
var lat = latlng.lat();
var lng = latlng.lng();
var height = 1000; //meters
var width = 1000; //meters
var polygon = new GPolygon(
[
new GLatLng(lat + height / 2 * 90 / 10000000, lng + width / 2 * 90 / 10000000 / Math.cos(lat)),
new GLatLng(lat - height / 2 * 90 / 10000000, lng + width / 2 * 90 / 10000000 / Math.cos(lat)),
new GLatLng(lat - height / 2 * 90 / 10000000, lng - width / 2 * 90 / 10000000 / Math.cos(lat)),
new GLatLng(lat + height / 2 * 90 / 10000000, lng - width / 2 * 90 / 10000000 / Math.cos(lat)),
new GLatLng(lat + height / 2 * 90 / 10000000, lng + width / 2 * 90 / 10000000 / Math.cos(lat))
], "#f33f00", 2, 1, "#ff0000", 0.2);
map.addOverlay(polygon);
});
I ported this PHP function to calculate the location an arbitrary distance and bearing from a known location, to Javascript:
var EARTH_RADIUS_EQUATOR = 6378140.0;
var RADIAN = 180 / Math.PI;
function calcLatLong(longitude, lat, distance, bearing)
{
var b = bearing / RADIAN;
var lon = longitude / RADIAN;
var lat = lat / RADIAN;
var f = 1/298.257;
var e = 0.08181922;
var R = EARTH_RADIUS_EQUATOR * (1 - e * e) / Math.pow( (1 - e*e * Math.pow(Math.sin(lat),2)), 1.5);
var psi = distance/R;
var phi = Math.PI/2 - lat;
var arccos = Math.cos(psi) * Math.cos(phi) + Math.sin(psi) * Math.sin(phi) * Math.cos(b);
var latA = (Math.PI/2 - Math.acos(arccos)) * RADIAN;
var arcsin = Math.sin(b) * Math.sin(psi) / Math.sin(phi);
var longA = (lon - Math.asin(arcsin)) * RADIAN;
return new GLatLng (latA, longA);
}
I have written a working example of this function that you can check out (source).
I use the Pythagorean Theorem to translate from a width of a square to a radius, if you want to use a simple 1000 meter radius from the center you can do that instead:
// this
var radius = 1000;
// instead of this
var radius = (Math.sqrt (2 * (width * width))) / 2;