Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Вычислить среднее расстояние от точки до сегмента линии и от сегмента линии до сегмента линии

Автор вопроса: FredОтветов: 3

Я ищу алгоритм для вычисления среднего расстояния между точкой и отрезком линии в 3D. Итак, учитывая две точки A (x1, y1, z1) и B (x2, y2, z2), которые представляют отрезок AB, и третью точку C (x3, y3, z3), каково среднее расстояние между каждой точкой на AB? в точку C?

Меня также интересует среднее расстояние между двумя отрезками линии. Итак, учитывая отрезки AB и CD, каково среднее расстояние от каждой точки на AB до ближайшей точки на CD?

Мне не повезло с поиском в Интернете, поэтому я буду благодарен за любые предложения.

Спасибо.

  • По какой причине вы пытаетесь это вычислить? Кажется, что это необычный расчет, и, боюсь, он не очень простой. Вы уверены, что ищете? brainjam 20.04.2010

mathgeometrywolfram-mathematica

Ответы

Ответ 1 · рейтинг 1 · David Z

Если вы имеете в виду то, что, по моему мнению, вы подразумеваете под "средним" (и "расстоянием", т. Е. Норму L2, упомянутую dreeves), вот процедура, которая, думаю, должна работать для определения среднего расстояния между точками. и отрезок линии. Вам понадобится функция dot(A,B), которая принимает скалярное произведение двух векторов.

// given vectors (points) A, B, C
K1 = dot(A-C,A-C)
K2 = 2*dot(B-A,A-C)
K3 = dot(B-A,B-A)
L1 = sqrt(K3*(K1+K2+K3))
L2 = sqrt(K3*K1)
N = 4*K3*L1 + 2*K2*(L1-L2) + (K2*K2-4*K1*K3)*log((K2+2*L2)/(2*K3+K2+2*L1))
D = N / (8*K3^1.5)

Если предположить, что я все правильно расшифровал, тогда D будет средним расстоянием.

По сути, это просто псевдокод для оценки результата интеграла, который я сделал в Mathematica. Для этого может быть какой-нибудь изящный вычислительный ярлык, но если он есть, я этого не знаю. (И если его нет, я бы спросил, сколько вам действительно нужно для этого вычисления)

Если вы хотите найти среднее расстояние от ближайшей точки на линейном сегменте CD до всех точек на AB, в большинстве случаев ближайшей точкой будет либо C, либо D, поэтому вы можете просто проверить оба из них, чтобы увидеть, какая из них ближе (возможно, используя некоторый расчет минимального расстояния, как указано в других ответах). Единственное исключение - когда CD и AB параллельны, и вы можете провести перпендикуляр от одного к другому, и в этом случае вам придется более точно определить свои требования.

Если бы вы хотели найти среднее расстояние между всеми точками на CD и всеми точками на AB ... это можно было бы сделать с помощью двойного интеграла, хотя я с содроганием представляю, насколько сложной будет полученная формула.

Ответ 2 · рейтинг 2 · dreeves

Во-первых, расстояние между двумя точками - это квадратный корень из суммы квадратов попарных разностей координат. (Например, расстояние от (0,0,0) до (1,1,1) равно sqrt (3), но это работает для произвольных точек в любом количестве измерений.) Это расстояние известно как l2-norm (L в нижнем регистре) или евклидова норма. Напишите норму (A, B) для расстояния между точками A и B.

Что касается интересной проблемы средних расстояний ... (Обратите внимание, что определение минимального расстояния от точки до линии или между сегментами линии - гораздо более распространенная проблема. Здесь был ответ с хорошими указателями для этой проблемы, но, похоже, он был удален тем временем.)

Чтобы найти среднее расстояние от точки C до отрезка AB, рассмотрите расстояние до произвольной точки между A и B, а именно (1-k) A + kB, где k изменяется от 0 до 1. Это норма (C, ( 1-к) А + кБ). Таким образом, среднее расстояние - это интеграл от k = 0 до 1 нормы (C, (1-k) A + kB).

Mathematica может сделать этот интеграл для любых конкретных A, B и C.

Вот реализация Mathematica:

avgd[A_,B_,C_] :=  Integrate[Sqrt@Dot[(1-k)*A+k*B-C, (1-k)*A+k*B-C], {k, 0, 1}]

Подынтегральное выражение также можно записать Norm[(1-k)*A+k*B-C]. В любом случае, Mathematica может сделать это для определенных точек, но не может интегрировать это символически, хотя, очевидно, Дэвид каким-то образом добился этого. Вот пример Дэвида из комментариев:

> avgd[{0, 0, 0}, {4, 0, 0}, {4, 3, 0}] // N

3.73594

Теоретически я думаю, что для проблемы среднего расстояния между двумя отрезками линии это должно сработать:

avgd[A_,B_,C_,D_] := Integrate[Norm[(1-k)A+k*B - (1-j)C - j*D], {k,0,1}, {j,0,1}]

Но Mathematica, кажется, задыхается от этого даже для конкретных моментов, не говоря уже о символах.

Ответ 3 · рейтинг 1 · High Performance Mark

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

У меня тоже есть копия Mathematica. Для простоты, поскольку треугольник должен лежать в плоскости, я проработал следующее в 2D-пространстве. Чтобы упростить задачу, я указываю точку в {0,0} и отрезок от {1,0} до {0,1}. Среднее расстояние от точки до линии должно быть, если это имеет смысл, средней длиной всех линий, которые могут быть проведены от {0,0} до любой точки сегмента линии. Конечно, таких строк очень много, поэтому давайте начнем, скажем, с 10. В системе Mathematica это можно вычислить как

Mean[Table[EuclideanDistance[{0, 0}, {1 - k, 0 + k}], {k, 0, 1, 10.0^-1}]]]

что дает 0.830255. Следующий шаг очевиден - увеличьте количество измеряемых линий. Фактически, давайте составим таблицу средних значений, когда показатель степени 10.0 станет меньше (они отрицательны!). В системе Mathematica:

Table[Mean[Table[EuclideanDistance[{0, 0}, {1 - k, 0 + k}], {k, 0, 1,
10.0^-i}]], {i, 0, 6}]

который производит:

{1, 0.830255, 0.813494, 0.811801, 0.811631, 0.811615, 0.811613}

Следуя этому подходу, я переработал пример @Dave (забудьте о третьем измерении):

Table[Mean[Table[EuclideanDistance[{0, 0}, {4, 0 + 3 k}], {k, 0, 1,
10.0^-i}]], {i, 0, 6}]

который дает:

{9/2, 4.36354, 4.34991, 4.34854, 4.34841, 4.34839, 4.34839}

Это не согласуется с тем, что, по словам @dreeves, вычисляет алгоритм @Dave.

РЕДАКТИРОВАТЬ: Хорошо, поэтому я потратил на это еще немного времени. Для простого примера, который я использовал в первую очередь, то есть с точкой в {0,0} и отрезком линии, простирающимся от {0,1} до {1,0}, я определяю функцию в Mathematica (как всегда), например:

fun2[k_] := EuclideanDistance[{0, 0}, {0 + k, 1 - k}]

Теперь это интегрируемо. Mathematica дает:

   In[13]:= Integrate[fun2[k], {k, 0, 1}]

   Out[13]= 1/4 (2 + Sqrt[2] ArcSinh[1])

Или, если вы предпочитаете числа, это:

In[14]:= NIntegrate[fun2[k], {k, 0, 1}]
Out[14]= 0.811613

что дает чисто численный подход, который я использовал ранее.

Теперь я собираюсь вернуться к работе и предоставить вам возможность обобщить это на произвольный треугольник, определяемый точкой и конечными точками отрезка линии.

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы