1501. Конусное расстояние

 

В трехмерном пространстве задан конус так, что его основание с радиусом r и центром в точке (0, 0, 0) лежит в плоскости z = 0. Вершина конуса расположена в точке (0, 0, h). На его поверхности заданы две точки в конусных координатах. Конусной координатой точки p называется пара чисел (d, A), где d – расстояние от вершины конуса до точки p, а A (A < 360) – угол в градусах между плоскостью y = 0 и плоскостью, проходящей через точки (0,0,0), (0, 0, h) и p, считая против часовой стрелки от направления оси x.

 На поверхности конуса заданы две точки p1 = (d1, A1) и p2 = (d2, A2). Найти кратчайшее расстояние между p1 и p2, измеряемое по поверхности конуса.

 

Вход. Каждая строка содержит 6 действительных чисел: r, h, d1, A1, d2, A2.

 

Выход. Для каждого теста вывести наименьшее расстояние между точками p1 и p2 с двумя десятичными знаками.

 

Пример входа

3.0 4.0 2.0 0.0 4.0 0.0
3.0 4.0 2.0 90.0 4.0 0.0
6.0 8.0 2.14 75.2 9.58 114.3
3.0 4.0 5.0 0.0 5.0 90.0
 

Пример выхода

2.00
3.26
7.66
4.54

 

 

РЕШЕНИЕ

геометрия

 

Анализ алгоритма

Переведем меру углов из градусной в радианную. Поскольку в 180 градусах содержится p радиан, то x градусам соответствует x * p / 180 радиан. Изобразим развертку конуса, разрезав его по прямой AB1, которая проходит через вершину A(0, 0, h) и точку p1. Поскольку ищется минимальное расстояние между точками p1 и p2, то развертку отобразим той стороной, для которой Ðp1Ap2 £  ½ÐB1AB2 (равенство достигается когда абсолютное значение разности A2 – A1 равно p). Обозначим j = Ðp1Ap2. Поскольку длина образующей конуса l равна AB1 = , а длина дуги B1B2 развертки равна  2pr, то | B1B2 | = AB1 * ÐB1AB2 или 2pr = l * ÐB1AB2. Здесь использована формула длины дуги , где l – длина дуги, r – радиус окружности, a – величина угла в радианах.

 

 

 

 

 

 

 

 

 

 

 

 


 

 

Обозначим через dA минимальное расстояние между углами A1 и A2. В развертке углу B1AB2 соответствует 2p радиан, а углу j  соответствует dA радиан. Имеем пропорцию:

Откуда j = ÐB1AB2 * dA / 2p = (2pr / l) * dA / 2p = r * dA / l. Поскольку длины Ap1 и Ap2 известны, то из треугольника p1Ap2 по теореме косинусов находим длину отрезка p1p2. Она равна .

 

Реализация алгоритма

Объявим константу p:

 

const double MY_PI = acos(-1.0);

 

Читаем входные данные, переводим меру углов из градусной в радианную. Вычисляем минимальное угловое расстояние da между p1 и p2.

 

while (scanf("%lf %lf %lf %lf %lf %lf",&r, &h, &d1, &a1, &d2, &a2) == 6)

{

  a1 *= MY_PI / 180; a2 *= MY_PI / 180;

  da = fabs(a2 - a1);

  if (da > MY_PI) da = 2*MY_PI - da;

 

Вычисляем длину образующей l и угол j, на который отображается угол dA на развертке. По теореме косинусов находим расстояние между точками p1 и p2 и выводим результат.

 

  l = sqrt(r*r+h*h);

  fi = da * r / l;

  l = sqrt(d1*d1 + d2*d2 - 2*d1*d2*cos(fi));

  printf("%.2lf\n",l);

}