Skip to content

Instantly share code, notes, and snippets.

@walkingpendulum
Last active December 18, 2018 21:13
Show Gist options
  • Save walkingpendulum/a7334b353b3ff1920d870957c0f4ee72 to your computer and use it in GitHub Desktop.
Save walkingpendulum/a7334b353b3ff1920d870957c0f4ee72 to your computer and use it in GitHub Desktop.
check if point belongs to polygon
# coding: utf-8
import cmath
import unittest
from itertools import chain
def eq_to_zero(x, eps=1e-7):
return abs(x) < eps
def degree(c_0, *cs):
"""
см. http://ru.wikipedia.org/wiki/Теорема_Жордана,
часть про описание внутренности как множества точек,
у которых степень относительно кривой равна +- 1.
"""
cs = iter(cs)
deg = 0
initial_num = cs.next()
prev_vector = initial_num - c_0
for cur_num in chain(cs, iter([initial_num])):
cur_vector = cur_num - c_0
if eq_to_zero(cur_vector):
deg += 0
continue
deg += cmath.phase(prev_vector / cur_vector)
prev_vector = cur_vector
return deg
def is_inner(point, closed_polyline):
deg = degree(complex(*point), *map(lambda t: complex(*t), closed_polyline))
return not eq_to_zero(deg)
class UnitsIntersectionTestCase(unittest.TestCase):
def test_degree(self):
self.assertTrue(is_inner([0.5, 0.5], [[0, 0], [1, 0], [0, 1], [0, 0]]))
self.assertTrue(is_inner([0, 0], [[1, 0], [1, 1], [-1, 1], [-1, -1], [1, -1], [1, 0]]))
self.assertFalse(is_inner([-1, -1], [[0, 0], [1, 0], [0, 1], [0, 0]]))
if __name__ == '__main__':
unittest.main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment