Симпс ошибки - ошибка геометрии - PullRequest
0 голосов
/ 28 апреля 2020

Я пишу программу, которая будет принимать две L-образные фигуры с длинными сторонами 1.

L выглядит так: enter image description here

Вот мой код:

    from sympy import *
    from sympy.geometry import *
    import math


    fi=acos(2/sqrt(5))
    fi2=asin(2/sqrt(5))

    class L:
      def __init__(self, alfa, x, y):
        self.alfa = alfa
        self.A = Point(x,y)
        self.B = Point(x+cos(alfa),y+sin(alfa))
        self.C = Point(x+(sqrt(5)/2)*cos(alfa+fi),y+(sqrt(5)/2)*sin(alfa+fi))
        self.D = Point(x+(sqrt(2)/2)*cos(alfa+45),y+(sqrt(2)/2)*sin(alfa+45))
        self.E = Point(x+(sqrt(5)/2)*cos(alfa+fi2),y+(sqrt(5)/2)*sin(alfa+fi2))
        self.F = Point(x+cos(90+alfa),y+sin(alfa+90))
        self.P = Polygon(self.A, self.B, self.C, self.D, self.E, self.F)


    def inter(a=L(0,0,0), b=L(0,0,0)):
        t=false
        for i in range(len((a.P).vertices)):
          if((b.P.encloses_point((a.P).vertices[i]))==true):
            t=true
            print("wrong:", i,"th vertex of 1st polygon")
            print("(",(a.P).vertices[i].x,",",(a.P).vertices[i].y,")")
            for j in range(len(b.P.vertices)):
              print("(", b.P.vertices[j].x,", ", b.P.vertices[j].y,")")
            break
        for i in range(len((b.P).vertices)):
          if((a.P.encloses_point((b.P).vertices[i]))==true):
            t=true
            break
        return t


    print(inter(L(0,0,0),L(0,1,0)))

Этот код выглядит хорошо для меня, но у меня ошибка. Этот код возвращает, что два L имеют пересечение. Чтобы было понятнее читателю, вот как выглядит этот L:

o

Итак, C не во втором L, вот вывод моего кода:

wrong 2th vertex of 1st polygon
( 1 , 1/2 )
( 1 ,  0 )
( 2 ,  0 )
( 2 ,  1/2 )
( sqrt(2)*cos(45)/2 + 1 ,  sqrt(2)*sin(45)/2 )
( 3/2 ,  1 )
( cos(90) + 1 ,  sin(90) )
True

Также по документации (https://docs.sympy.org/latest/modules/geometry/polygons.html) точка на границе многоугольника считается ложной. Поэтому точка C может вернуть false, но программа возвращает true. Когда я пытаюсь упростить код, он работает нормально:

    >>> a=Polygon((1,0),(2,0),(2,1),(1,1))
    >>> a.encloses_point(Point(1,1/2))
    False

У меня нет идей, что пошло не так. Что случилось с функцией encloses_point? Может кто-нибудь помочь?

Заранее спасибо

1 Ответ

2 голосов
/ 29 апреля 2020

Пересечение состоит из общих точек. SymPy не вычисляет общие области, как указано здесь . Хотя точка на границе не является в полигоне, точка считается действительной сущностью пересечения:

>>> from sympy import Triangle
>>> Triangle((0,0),(1,1),(0,1)).intersection(Triangle((0,0),(-1,-1),(0,-1)))
[Point2D(0, 0)]

В вашем случае это логическая проблема, но не фактическая проблема. Вы думаете, что имеете дело с L-образным многоугольником, но это не так. Функции триггера SymPy интерпретируют свои аргументы в радианах, но я подозреваю, что вы думаете, что работаете с градусами (cos(90) != 0, но cos(rad(90)) = 0, где rad импортируется из sympy.geometry.polygon). (1, 1/2) находится в полигоне, который вы определили ... просто не в том, с которым вы, как вы думаете, имеете дело. : -)

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