Thursday, April 23, 2015

UVa 11817 - Tunnelling the Earth

#include <stdio.h>
#include <math.h>
#include <cmath>
using namespace std;

#define EARTH_RADIUS 6371009

struct cartesian_coordinates {
	double x, y, z;
};

struct geographical_coordinates {
	double latitude, longitude;
};

double dist(cartesian_coordinates p, cartesian_coordinates q) {
	return sqrt((p.x - q.x) * (p.x - q.x) + (p.y - q.y) * (p.y - q.y) + (p.z - q.z) * (p.z - q.z));
}

double degrees_to_radians(double degrees) {
	return degrees / 180 * M_PI;
}

cartesian_coordinates geographycal_to_cartesian(geographical_coordinates g, double sphere_radius) {
	cartesian_coordinates c;
	c.x = sphere_radius * cos(g.latitude) * cos(g.longitude);
	c.y = sphere_radius * cos(g.latitude) * sin(g.longitude);
	c.z = sphere_radius * sin(g.latitude);
	return c;
}

double great_circle_distance(geographical_coordinates p1, geographical_coordinates p2, double radius) {
	double central_angle = acos(sin(p1.latitude) * sin(p2.latitude) + cos(p1.latitude) * cos(p2.latitude) * cos(abs(p1.longitude - p2.longitude)));
	return central_angle * radius;
}

int main() {

	int cases;
	for (scanf("%d", &cases); cases; cases--) {
		geographical_coordinates g1, g2;
		scanf("%lf%lf%lf%lf", &g1.latitude, &g1.longitude, &g2.latitude, &g2.longitude);
		g1.latitude = degrees_to_radians(g1.latitude);
		g1.longitude = degrees_to_radians(g1.longitude);
		g2.latitude = degrees_to_radians(g2.latitude);
		g2.longitude = degrees_to_radians(g2.longitude);

		cartesian_coordinates c1 = geographycal_to_cartesian(g1, EARTH_RADIUS);
		cartesian_coordinates c2 = geographycal_to_cartesian(g2, EARTH_RADIUS);

		double straight_line_distance = dist(c1, c2);
		double ggreat_circle_distance = great_circle_distance(g1, g2, EARTH_RADIUS);
		printf("%.0f\n", ggreat_circle_distance - straight_line_distance);
	}

	return 0;
}

No comments:

Post a Comment