public static double bearingFinal(position startPoint, position finalPoint) { //calculate de delta lon double Δlong = DegreesToRadians(finalPoint.lon - startPoint.lon); //get the lat values double lat1 = DegreesToRadians(startPoint.lat); double lat2 = DegreesToRadians(finalPoint.lat); //divide and conqueror double y = Math.Sin(Δlong) * Math.Cos(lat2); double x = ((Math.Cos(lat1) * Math.Sin(lat2)) - (Math.Sin(lat1) * Math.Cos(lat2) * Math.Cos(Δlong))); //tc1=mod(atan2(sin(lon1-lon2)*cos(lat2),cos(lat1)*sin(lat2)-sin(lat1)*cos(lat2)*cos(lon1-lon2)), 2*pi) //apply the values obtained //double θ = Math.Atan2(y,x) % (2*Math.PI); //θ = RadiansToDegrees(θ); double θ = RadiansToDegrees(Math.Atan2(y, x)); θ = (θ + 180) % 360; //return the value in decial degrees θ+360) % 360 return θ; }
//funcion para setear la velocidad del grid desde un hilo private void ajustaCoordenadas(position coord, int indiceLista) { if (this.dgObjetivos.InvokeRequired) { SetTextDelegateCoordenadas d = new SetTextDelegateCoordenadas(ajustaCoordenadas); this.Invoke(d, new object[] { coord, indiceLista }); } else { listaObjetivos[indiceLista].lat = (float)(coord.lat); listaObjetivos[indiceLista].lon = (float)(coord.lon); //lbObjetivos.Text = System.Convert.ToString(velocidad); // this.listaObjetivos[indice].speed = velocidad; } }
//funcion donde se simula el movimiento de los objetivos private void simulacion() { //timer para controlar el tiempo de sleep del hilo, cada ese tiempo, ejecutara la acción. TimeController temporizador = new TimeController(3, false); while (true) { if (temporizador.isCycleDone) { if (listaObjetivos.Count > 0) { for (int i = 0; i < listaObjetivos.Count; i++) { //float tiempo = 10;//hrs double timestampNow = TimeController.timeStamp(); double tiempoEnHoras = (timestampNow - listaObjetivos[i].lastTime) / 3600;//en Hrs //PONER EL NUEVO TIMESTAMP double timestampNow2 = TimeController.timeStamp(); listaObjetivos[i].lastTime = timestampNow2; //distancia en Kilometros float distanciaKm = geodesicUtils.nauticalMilesToKilometer(calculaDistanciaMN2((float)tiempoEnHoras, listaObjetivos[i].speed)); position origen = new position(listaObjetivos[i].lat, listaObjetivos[i].lon); position destino = geodesicUtils.FindPointAtDistanceFrom(origen, geodesicUtils.DegreesToRadians(listaObjetivos[i].course), distanciaKm); //ajustamos las coordenadas de la nueva posicion ajustaCoordenadas(destino, i); //ajustamos el nuevo curso o bearing en la nueva posicion. ajustaRumbo((float)geodesicUtils.bearingFinal(destino, origen),i); }//del ciclo for } } //esperar evento para detener el hilo if (eventoSimulacion.WaitOne(0, false) == true) { //just wait until the last thread is done //Sleep(500); eventoSimulacion.Reset();//reset the event break; } } }
private void simulacion() //funcion donde se simula el movimiento de los objetivos { //timer para controlar el tiempo de sleep del hilo, cada ese tiempo, ejecutara la acción. TimeController temporizador = new TimeController(3, false); while (true) { if (temporizador.isCycleDone) { if (listaObjetivos.Count > 0) { for (int i = 0; i < listaObjetivos.Count; i++) { //float tiempo = 10;//hrs double timestampNow = TimeController.timeStamp(); double tiempoEnHoras = (timestampNow - listaObjetivos[i].lastTime) / 3600; //en Hrs //PONER EL NUEVO TIMESTAMP double timestampNow2 = TimeController.timeStamp(); listaObjetivos[i].lastTime = timestampNow2; //distancia en Kilometros float distanciaKm = geodesicUtils.nauticalMilesToKilometer(calculaDistanciaMN2((float)tiempoEnHoras, listaObjetivos[i].speed)); position origen = new position(listaObjetivos[i].lat, listaObjetivos[i].lon); position destino = geodesicUtils.FindPointAtDistanceFrom(origen, geodesicUtils.DegreesToRadians(listaObjetivos[i].course), distanciaKm); //ajustamos las coordenadas de la nueva posicion ajustaCoordenadas(destino, i); //ajustamos el nuevo curso o bearing en la nueva posicion. double x = geodesicUtils.bearingFinal(destino, origen); ajustaRumbo(x, i); /* * //EXTRA * int g = 18; * int m = 46; * int s = 7; * * double DecimalLat = geodesicUtils.coordinatesFromDMStoDecimalDegrees(g, m, s); * Console.WriteLine("Latitud grados decimales: " + DecimalLat); * * g = 91; * m = 50; * s = 31; * * double DecimalLon = geodesicUtils.coordinatesFromDMStoDecimalDegrees(g, m, s); * Console.WriteLine("Longitud grados decimales: " + DecimalLon); * Console.WriteLine("course: " + x); * //*/ } //del ciclo for } } //esperar evento para detener el hilo if (eventoSimulacion.WaitOne(0, false) == true) { //just wait until the last thread is done //Sleep(500); eventoSimulacion.Reset(); //reset the event break; } } }
double DistanceInKilometers(position a, position b) { return((double)EARTH_RADIUS_IN_METERS * this.arcInRad(a, b) / 1000.0); }
double DistanceInMeters(position a, position b) { return (double)EARTH_RADIUS_IN_METERS * this.arcInRad(a, b); }
/*If you need to check a pair of coordinates.*/ bool checkCoordinates(position a, position b) { if ((checkCoordinates(a)) && (checkCoordinates(b))) { return true; } else { return false; } }
//const decimal EARTH_RADIUS_IN_METERS = 6371000.00M; /*if you need to check just a point*/ bool checkCoordinates(position a) { if (((a.lat < 90) && (a.lat > -90)) && ((a.lon < 180) && (a.lon > -180))) { return true; } else { return false; } }
double arcInRad(position from, position to) { /*to use the trigonometric function, first convert to radians*/ double latitudeArc = (from.lat - to.lat) * (double)DEG_TO_RAD; double longitudeArc = (from.lon - to.lon) * (double)DEG_TO_RAD; double latitudeH = Math.Sin(latitudeArc * 0.5); latitudeH *= latitudeH; double lontitudeH = Math.Sin(longitudeArc * 0.5); lontitudeH *= lontitudeH; double tmp = Math.Cos(from.lat * (double)DEG_TO_RAD) * Math.Cos(to.lat * (double)DEG_TO_RAD); return 2.0 * Math.Asin(Math.Sqrt(latitudeH + tmp * lontitudeH)); }
/*To calculate a lat of destination point, given distance and bearing from start point * The return of destinatin lat is in decimal degrees * position has lat/lon implicit data */ public static position FindPointAtDistanceFrom(position startPoint, double initialBearingRadians, double distanceKilometres) { const double radiusEarthKilometres = (double)(EARTH_RADIUS_IN_METERS) / 1000.0; var distRatio = distanceKilometres / radiusEarthKilometres; var distRatioSine = Math.Sin(distRatio); var distRatioCosine = Math.Cos(distRatio); var startLatRad = DegreesToRadians(startPoint.lat); var startLonRad = DegreesToRadians(startPoint.lon); var startLatCos = Math.Cos(startLatRad); var startLatSin = Math.Sin(startLatRad); var endLatRads = Math.Asin((startLatSin * distRatioCosine) + (startLatCos * distRatioSine * Math.Cos(initialBearingRadians))); var endLonRads = startLonRad + Math.Atan2(Math.Sin(initialBearingRadians) * distRatioSine * startLatCos, distRatioCosine - startLatSin * Math.Sin(endLatRads)); position endPoint = new position(RadiansToDegrees(endLatRads), RadiansToDegrees(endLonRads)); return endPoint; }