Sympy: пересечение сегментов - PullRequest
       17

Sympy: пересечение сегментов

2 голосов
/ 26 октября 2019

Мне нужно вычислить пересечение сегментов, я делаю это, используя sympy и его функцию intersection. Кажется, это хорошо работает, когда координаты даются напрямую, но в моем случае я строю конечные точки итеративно. В качестве примера, давайте вычислим пересечение сегментов s0 (синий) и s1 (красный) на следующем рисунке:

drawing

Это можно сделать следующим образом:

import sympy
from sympy.geometry import *
from numpy import sqrt, cos, sin

PI = float(sympy.pi)

p0 = Point(0.0, 0.0, evaluate=False)
p1 = Point(1.0, 0, evaluate=False)
p2 = Point(0.5, sqrt(3)/2.0, evaluate=False)
p3 = Point(0.5, -sqrt(3)/2.0, evaluate=False)

s0 = Segment(p0, p1)
s1 = Segment(p2, p3)

print(intersection(s0, s1))
# [Point2D(0.500000000000000, 0)]

Или начав с p0 и построив другие точки (названные q1, q2, q3 для последующего сравнения), добавив соответствующие векторы:

angle = 0.0
q0 = Point(0.0, 0.0, evaluate=False)
q1 = q0 + Point(cos(angle), sin(angle), evaluate=False)
angle = 2.0*PI/3.0
q2 = q1 + Point(cos(angle), sin(angle), evaluate=False)
angle = -0.5*PI
q3 = q2 + Point(sqrt(3)*cos(angle), sqrt(3)*sin(angle), evaluate=False)

r0 = Segment(q0, q1)
r1 = Segment(q2, q3)

print(intersection(r0, r1))
# []

Что не получается (возвращенное пересечение пусто).

Мы можем проверить, что p0 = q0 и т. Д., По крайней мере, численно:

print("|p0-q0| = ", p0.distance(q0)) # |p0-q0| =  0
print("|p1-q1| = ", p1.distance(q1)) # |p1-q1| =  0
print("|p2-q2| = ", p2.distance(q2)) # |p2-q2| =  2.48253415324727e-16
print("|p3-q3| = ", p3.distance(q3)) # |p3-q3| =  3.51083346857670e-16

Я хочу, чтобы это было разумнобыстро, поэтому я использую evaluate=False только для операций с плавающей точкой, поэтому я не могу понять разницу в результатах. Также обратите внимание, что функции cos, sin и sqrt относятся к пакету numpy, поэтому мы (должны?) Избегать ленивых вычислений. Я что-то пропустил?

Редактировать: это использует python 3.7.4 и sympy 1.4

1 Ответ

0 голосов
/ 26 октября 2019

Это похоже на ошибку в SymPy. Вы можете использовать srepr(), чтобы показать внутреннее представление s0, s1, r0, r1 и заметить, что они очень похожи по структуре.

Проблема в том, что ваши координаты почти, но не совсем равны. Итак, это скорее числовая, чем символическая проблема.

Обратите внимание, что SymPy блестит в символических вычислениях и дает прекрасные точные результаты. Для проблем с этой сложностью вы действительно не выигрываете много времени, позволяя SymPy выполнять численные расчеты. Мой совет - либо пропустить численные расчеты, либо выполнить пересечение внутри NumPy

.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...