确定点是否在一个旋转的矩形内(仅使用标准Python 2.7库)。
确定点是否在旋转的矩形内(仅使用标准Python 2.7库)
在纯Python代码中,可以通过2点构建形式为ax+by+c==0
的线方程。对于要判断是否在凸多边形内的给定点,我们需要测试它是否在由多边形的边界定义的每条线的同一侧。
以下是代码的实现:
def is_on_right_side(x, y, xy0, xy1): x0, y0 = xy0 x1, y1 = xy1 a = float(y1 - y0) b = float(x0 - x1) c = - a*x0 - b*y0 return a*x + b*y + c >= 0 def test_point(x, y, vertices): num_vert = len(vertices) is_right = [is_on_right_side(x, y, vertices[i], vertices[(i + 1) % num_vert]) for i in range(num_vert)] all_left = not any(is_right) all_right = all(is_right) return all_left or all_right vertices = [(670273, 4879507), (677241, 4859302), (670388, 4856938), (663420, 4877144)]
该代码通过在纯Python中编写等式来避免除法,并通过测试每个点与多边形边界的关系来确定点是否在旋转的矩形内。
此外,代码还提供了一个可视化的测试,绘制了几个形状并在平面上随机生成了一些点进行测试。
如果需要频繁进行此计算,可以预先计算并存储a,b,c
值。如果已知边的方向,则只需要一个all_left
或all_right
。
当形状固定时,可以生成函数的文本版本。例如:
def generate_test_function(vertices, is_clockwise=True, function_name='test_function'): ext_vert = list(vertices) + [vertices[0]] unequality_sign = '>=' if is_clockwise else '<=' print(f'def {function_name}(x, y):') parts = [] for (x0, y0), (x1, y1) in zip(ext_vert[:-1], ext_vert[1:]): a = float(y1 - y0) b = float(x0 - x1) c = a * x0 + b * y0 parts.append(f'({a}*x + {b}*y {unequality_sign} {c})') print(' return', ' and '.join(parts)) vertices = [(670273, 4879507), (677241, 4859302), (670388, 4856938), (663420, 4877144)] generate_test_function(vertices)
这段代码可以生成一个函数,然后可以通过Jython编译器进行优化。注意,形状不需要是矩形,任何凸多边形都可以,这样可以使用更紧凑的边界框。
关于水平线的特殊情况如何处理?
这些方程是以没有除法(也没有计算斜率)的方式编写的。因此,它们适用于线的任何方向。由于使用了>=
,即使两个连续点相等也可以工作,尽管这并不推荐。但对于凹多边形则效果不好。
对于代码报错的问题,可能是因为您的Python版本不支持星号语法。可以将代码适配为不使用星号语法。
确定点是否在旋转矩形内部(仅使用标准Python 2.7库)
问题的出现原因:
在某些情况下,我们需要确定一个点是否在一个旋转的矩形内部。然而,标准Python 2.7库中没有直接提供这样的功能。因此,我们需要找到一种方法来解决这个问题。
解决方法:
我们可以通过以下步骤来确定一个点是否在旋转矩形内部:
1. 取三个连续的顶点A、B、C(用1、2、3表示)。
2. 计算边AB和BC的长度。
lAB = sqrt((B.x - A.x)^2+(B.y - A.y)^2)
3. 获取单位(归一化)方向向量。
uAB = ((B.x - A.x) / lAB, (B.y - A.y) / lAB)
4. 对于被测试的点P,获取向量BP。
BP = ((P.x - B.x), (P.y - B.y))
5. 使用叉积计算从边到点的有符号距离。
SignedDistABP = Cross(BP, uAB) = BP.x * uAB.y - BP.y * uAB.x
SignedDistBCP = - Cross(BP, uBC) = - BP.x * uBC.y + BP.y * uBC.x
6. 对于在矩形内部的点,这两个距离应该有相同的符号(根据顶点的顺序是顺时针还是逆时针),并且它们的绝对值不应大于lBC和lAB。
Abs(SignedDistABP) <= lBC
Abs(SignedDistBCP) <= lAB
通过以上步骤,我们可以确定一个点是否在旋转矩形内部。
确定点是否在旋转的矩形内(仅使用标准的Python 2.7库)
问题出现的原因:在给定一个旋转的矩形和一组点的情况下,需要判断这些点是否在旋转的矩形内部。由于矩形是旋转的,传统的方法无法直接比较坐标来判断点的位置。
解决方法:可以使用复数来表示所有的点,并计算由某一边定义的向量,然后将所有点乘以共轭。这样,矩形就变成了与坐标轴对齐的形状,只需要进行四个坐标比较即可。复数可以很容易地进行旋转计算。
另一种稍微不同的方法是考虑到将某个角点移到原点,并将两条相邻边移到(1,0)和(0,1)的坐标系变换。这是一种仿射变换。然后,测试就简化为检查是否在单位正方形内。
参考链接:[codereview.stackexchange.com/a/248449/206844](https://codereview.stackexchange.com/a/248449/206844)