可以以相同的方式递归检查点位置,方法是如何创建科赫雪花.步骤如下:
>检查是给定三角形内的点,
>如果不是,则点位于某些三角形边缘的负侧.对于点在负侧的每个边,递归检查该点的“中间三角形”中的点,如果不是递归检查下两个可能的雪花边缘部分.
这种方法速度更快,因为它不会创建整个多边形并对其进行检查.
这是使用numpy进行积分的实现:
import numpy
def on_negative_side(p, v1, v2):
d = v2 - v1
return numpy.dot(numpy.array([-d[1], d[0]]), p - v1) < 0
def in_side(p, v1, v2, n):
if n <= 0:
return False
d = v2 - v1
l = numpy.linalg.norm(d)
s = numpy.dot(d / l, p - v1)
if s < 0 or s > l: # No need for a check if point is outside edge 'boundaries'
return False
# Yves's check
nd = numpy.array([-d[1], d[0]])
m_v = nd * numpy.sqrt(3) / 6
if numpy.dot(nd / l, v1 - p) > numpy.linalg.norm(m_v):
return False
# Create next points
p1 = v1 + d/3
p2 = v1 + d/2 - m_v
p3 = v1 + 2*d/3
# Check with two inner edges
if on_negative_side(p, p1, p2):
return in_side(p, v1, p1, n-1) or in_side(p, p1, p2, n-1)
if on_negative_side(p, p2, p3):
return in_side(p, p2, p3, n-1) or in_side(p, p3, v2, n-1)
return True
def _in_koch(p, V, n):
V_next = numpy.concatenate((V[1:], V[:1]))
return all(not on_negative_side(p, v1, v2) or in_side(p, v1, v2, n)
for v1, v2 in zip(V, V_next))
def in_koch(L, V, n):
# Triangle points (V) are positive oriented
return [p for p in L if _in_koch(p, V, n)]
L = numpy.array([(16, -16), (90, 90), (40, -40), (40, -95), (50, 10), (40, 15)])
V = numpy.array([(0, 0), (50, -50*numpy.sqrt(3)), (100, 0)])
for n in xrange(3):
print n, in_koch(L, V, n)
print in_koch(L, V, 100)