In [57]:
import random
import numpy
In [15]:
-
In [16]:
triangles = ((0, 1, 2),
(3, 4, 5),
(6, 7, 8),
(4, 9, 10),
(6, 8, 11),
(12, 3, 13),
(11, 8, 14),
(9, 15, 16),
(11, 14, 17),
(15, 18, 16),
(14, 19, 17),
(20, 21, 22),
(14, 23, 19),
(18, 24, 16),
(14, 25, 26),
(27, 28, 29),
(25, 30, 26),
(28, 31, 32),
(33, 19, 23),
(31, 34, 35),
(23, 14, 26),
(34, 36, 37),
(25, 38, 30),
(36, 39, 40),
(30, 38, 20),
(39, 41, 42),
(22, 30, 20),
(39, 42, 40),
(20, 12, 21),
(43, 21, 12),
(13, 44, 12),
(45, 46, 47),
(44, 43, 12),
(45, 47, 48),
(5, 13, 3),
(45, 48, 49),
(36, 40, 37),
(49, 48, 50),
(37, 51, 34),
(49, 50, 52),
(51, 53, 34),
(52, 50, 5),
(53, 54, 34),
(55, 52, 5),
(34, 54, 35),
(56, 57, 58),
(31, 35, 59),
(56, 58, 60),
(31, 59, 61),
(56, 60, 62),
(63, 64, 65),
(62, 60, 66),
(67, 63, 68),
(62, 66, 69),
(64, 70, 71),
(66, 72, 69),
(70, 73, 74),
(66, 55, 72),
(73, 75, 74),
(55, 76, 72),
(77, 67, 68),
(72, 76, 78),
(70, 74, 71),
(79, 80, 81),
(64, 71, 65),
(80, 82, 81),
(63, 65, 68),
(80, 83, 82),
(84, 77, 85),
(82, 83, 86),
(77, 68, 85),
(83, 87, 86),
(84, 85, 88),
(86, 87, 89),
(61, 84, 31),
(89, 87, 72),
(84, 88, 31),
(89, 72, 78),
(31, 88, 32),
(55, 5, 76),
(28, 32, 90),
(76, 4, 91),
(28, 92, 93),
(91, 4, 94),
(90, 95, 28),
(94, 4, 96),
(95, 92, 28),
(96, 4, 97),
(28, 93, 98),
(97, 4, 10),
(28, 98, 29),
(76, 5, 4),
(27, 29, 99),
(100, 10, 9),
(101, 102, 103),
(104, 105, 106),
(102, 107, 108),
(109, 105, 110),
(111, 101, 112),
(113, 109, 110),
(114, 115, 116),
(117, 105, 109),
(99, 111, 118),
(119, 113, 110),
(120, 107, 102),
(104, 121, 105),
(116, 120, 114),
(121, 122, 123),
(120, 124, 107),
(123, 122, 125),
(126, 127, 128),
(129, 130, 131),
(127, 132, 133),
(134, 135, 136),
(137, 126, 138),
(135, 129, 136),
(127, 133, 128),
(136, 129, 139),
(126, 128, 138),
(139, 129, 131),
(137, 138, 140),
(130, 141, 131),
(137, 140, 124),
(131, 141, 142),
(124, 140, 107),
(141, 125, 142),
(120, 102, 114),
(125, 122, 142),
(102, 108, 103),
(121, 123, 105),
(101, 103, 112),
(105, 117, 106),
(111, 112, 118),
(106, 117, 143),
(27, 99, 16),
(143, 117, 144),
(99, 118, 145),
(146, 147, 144),
(99, 145, 148),
(146, 149, 147),
(99, 148, 16),
(2, 106, 0),
(24, 27, 16),
(150, 151, 152),
(100, 9, 16),
(153, 154, 155),
(149, 100, 156),
(157, 158, 159),
(160, 2, 1),
(158, 155, 159),
(100, 16, 156),
(158, 153, 155),
(149, 156, 147),
(154, 161, 155),
(162, 163, 160),
(154, 150, 161),
(163, 151, 160),
(161, 150, 152),
(144, 147, 143),
(143, 0, 106),
(1, 162, 160),
(151, 163, 152),
)
In [17]:
def lines(triangle):
t = sorted(triangle)
return [(t[0], t[1]), (t[0], t[2]), (t[1], t[2])]
In [18]:
hull = set()
for triangle in triangles:
for line in lines(triangle):
if line in hull:
hull.remove(line)
else:
hull.add(line)
In [19]:
hull
Out[19]:
Each point should be in the hull exactly twice.
In [20]:
points = dict()
for line in hull:
for point in line:
if point not in points:
points[point] = 1
else:
points[point] += 1
In [21]:
for key in points.keys():
assert points[key] == 2
Now check whether a ray originating from the point (x, y) in the east dirrection intersects a line segment with endpoints (ax, ay) and (bx, by). First we check whether y lies in the segment [ay, by]. The we observe whether x, a, b makes a left turn.
In [58]:
def intersects(p, a, b):
p = (p[0] + random.random()*0.000001, p[1] + random.random()*0.000001)
a, b = sorted([a, b], key=lambda p: p[1])
if a[1] < p[1] and p[1] < b[1]:
# Check the turn
a = numpy.array([[1] + list(p),
[1] + list(a),
[1] + list(b)])
return numpy.linalg.det(a) > 0
return False
In [24]:
a = (1, 3)
b = (-3, 5)
sorted([a, b], key=lambda p: p[1])
Out[24]:
In [47]:
intersects((0.00001, 0.00001), (1, -1), (-0.5, 1))
Out[47]:
In [42]:
def count_intersections(point_coordines, lines, point):
intersections = 0
for line in lines:
a, b = point_coordinates[line[0]], point_coordinates[line[1]]
if intersects(point, a, b):
intersections += 1
return intersections
In [63]:
count_intersections(point_coordinates, hull, (0,0))
Out[63]:
In [ ]: