Мои проблемы состоят в следующем: мне даны две пары углов (в сферических координатах), которые состоят из двух частей - азимута и угла падения.Если мы расширяем оба угла (увеличивая их соответствующие радиусы) бесконечно, чтобы сделать длинную линию, указывающую в направлении, заданном парой углов, то моя цель состоит в том, чтобы определить
- , пересекаются ли они или очень близкодруг к другу и
- , где именно они пересекаются.
В настоящее время я пробовал несколько методов:
Наиболее очевидным является итеративное сравнение каждого радиуса до тех пор, пока между ними не будет совпадения или достаточно малого расстояния.(Когда я говорю, сравнивайте каждый радиус, я имею в виду преобразование каждой сферической координаты в декартову, а затем находим евклидово расстояние между ними).Тем не менее, это время выполнения $ O (n ^ {2}) $, что очень медленно, если я пытаюсь масштабировать эту программу
Второй наиболее очевидный метод - это использование оптимизациипакет, чтобы найти это расстояние.К сожалению, я не могу выполнить пакет оптимизации итеративно, и после одного случая алгоритм оптимизации повторяет один и тот же ответ, что бесполезно.
Наименее очевидным методом является прямой расчет (с использованием исчисления) точных радиусов от углов.Хотя это быстрый метод, он не очень точен.
Примечание: хотя может показаться простым, что пересечение всегда имеет нулевое начало (0,0,0), это не всегда так.Некоторые точки никогда не пересекаются.
Код для метода (1)
def match1(azimuth_recon_1,colatitude_recon_1,azimuth_recon_2, colatitude_recon_2,centroid_1,centroid_2 ):
# Constants: tolerance factor and extremely large distance
tol = 3e-2
prevDist = 99999999
# Initialize a list of radii to loop through
# Checking iteravely for a solution
for r1 in list(np.arange(0,5,tol)):
for r2 in list(np.arange(0,5,tol)):
# Get the estimates
estimate_1 = np.array(spher2cart(r1,azimuth_recon_1,colatitude_recon_1)) + np.array(centroid_1)
estimate_2 = np.array(spher2cart(r2,azimuth_recon_2,colatitude_recon_2))+ np.array(centroid_2)
# Calculate the euclidean distance between them
dist = np.array(np.sqrt(np.einsum('i...,i...', (estimate_1 - estimate_2), (estimate_1 - estimate_2)))[:,np.newaxis])
# Compare the distance to this tolerance
if dist < tol:
if dist == 0:
return estimate_1, [], True
else:
return estimate_1, estimate_2, False
## If the distance is too big break out of the loop
if dist > prevDist:
prevDist = 9999999
break
prevDist = dist
return [], [], False
Код для метода (3)
def match2(azimuth_recon_1,colatitude_recon_1,azimuth_recon_2, colatitude_recon_2,centriod_1,centroid_2):
# Set a Tolerance factor
tol = 3e-2
def calculate_radius_2(azimuth_1,colatitude_1,azimuth_2,colatitude_2):
"""Return radius 2 using both pairs of angles (azimuth and colatitude). Equation is provided in the document"""
return 1/((1-(math.sin(azimuth_1)*math.sin(azimuth_2)*math.cos(colatitude_1-colatitude_2))
+math.cos(azimuth_1)*math.cos(azimuth_2))**2)
def calculate_radius_1(radius_2,azimuth_1,colatitude_1,azimuth_2,colatitude_2):
"""Returns radius 1 using both pairs of angles (azimuth and colatitude) and radius 2.
Equation provided in document"""
return (radius_2)*((math.sin(azimuth_1)*math.sin(azimuth_2)*math.cos(colatitude_1-colatitude_2))
+math.cos(azimuth_1)*math.cos(azimuth_2))
# Compute radius 2
radius_2 = calculate_radius_2(azimuth_recon_1,colatitude_recon_1,azimuth_recon_2,colatitude_recon_2)
#Compute radius 1
radius_1 = calculate_radius_1(radius_2,azimuth_recon_1,colatitude_recon_1,azimuth_recon_2,colatitude_recon_2)
# Get the estimates
estimate_1 = np.array(spher2cart(radius_1,azimuth_recon_1,colatitude_recon_1))+ np.array(centroid_1)
estimate_2 = np.array(spher2cart(radius_2,azimuth_recon_2,colatitude_recon_2))+ np.array(centroid_2)
# Calculate the euclidean distance between them
dist = np.array(np.sqrt(np.einsum('i...,i...', (estimate_1 - estimate_2), (estimate_1 - estimate_2)))[:,np.newaxis])
# Compare the distance to this tolerance
if dist < tol:
if dist == 0:
return estimate_1, [], True
else:
return estimate_1, estimate_2, False
else:
return [], [], False
У меня вопрос двоякий:
Существует ли более быстрый и точный способ найти радиусы для обеих точек?
Если это так, как мне это сделать?
РЕДАКТИРОВАТЬ: я думаю о создании двух числовых массивов из двух радиусов, а затем сравнивать их с помощью логической логики,Однако я бы все равно сравнивал их.Есть ли более быстрый способ выполнить это сравнение?