Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/242.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 2.7 确定点是否位于旋转矩形内(仅限标准Python 2.7库)_Python 2.7_Math_Geometry_Coordinates_Jython 2.7 - Fatal编程技术网

Python 2.7 确定点是否位于旋转矩形内(仅限标准Python 2.7库)

Python 2.7 确定点是否位于旋转矩形内(仅限标准Python 2.7库),python-2.7,math,geometry,coordinates,jython-2.7,Python 2.7,Math,Geometry,Coordinates,Jython 2.7,我有一个旋转的矩形,其中的坐标是顶点: 1 670273 4879507 2 677241 4859302 3 670388 4856938 4 663420 4877144 我有这些坐标的点: 670831 4867989 675097 4869543 仅使用Python2.7标准库,我想确定这些点是否位于旋转的矩形内 我无法将其他Python库添加到Jython实现中 这样做需要什么?取三个后续顶点A,B,C(你的1

我有一个旋转的矩形,其中的坐标是顶点:

   1   670273   4879507
   2   677241   4859302
   3   670388   4856938
   4   663420   4877144


我有这些坐标的点:

670831  4867989
675097  4869543
仅使用Python2.7标准库,我想确定这些点是否位于旋转的矩形内

  • 我无法将其他Python库添加到Jython实现中


这样做需要什么?

取三个后续顶点
A,B,C
(你的1,2,3)

查找边的长度
AB
BC

lAB = sqrt((B.x - A.x)^2+(B.y - A.y)^2)
获取单位(标准化)方向向量

uAB = ((B.x - A.x) / lAB, (B.y - A.y) / lAB) 
对于测试点
p
获取向量
BP

BP = ((P.x - B.x), (P.y - B.y)) 
并使用叉积计算从边到点的有符号距离

SignedDistABP = Cross(BP, uAB) = BP.x * uAB.y - BP.y * uAB.x
SignedDistBCP = - Cross(BP, uBC) = - BP.x * uBC.y + BP.y * uBC.x
对于矩形内的点,两个距离应具有相同的符号-根据顶点顺序(CW或CCW)为负或正,且其绝对值不应大于相应的
lBC
lAB

Abs(SignedDistABP) <= lBC
Abs(SignedDistBCP) <= lAB

Abs(SignedDistABP)可以从2个点构造形式为
ax+by+c==0的直线方程。对于位于凸面形状内部的给定点,我们需要测试它是否位于由形状的边定义的每条线的同一侧

在纯Python代码中,注意编写避免除法的方程式,可以如下所示:

def位于右侧(x,y,xy0,xy1):
x0,y0=xy0
x1,y1=xy1
a=浮动(y1-y0)
b=浮点数(x0-x1)
c=-a*x0-b*y0
返回a*x+b*y+c>=0
def测试点(x、y、顶点):
num_vert=len(顶点)
is_right=[is_在_right_侧(x,y,顶点[i],顶点[(i+1)%num_vert]),对于范围内的i(num_vert)]
all_left=无任何(是_right)
all_right=all(is_right)
返回全部向左或全部向右
顶点=[(6702734879507),(6772414859302),(6703884856938),(6634204877144)]
下面的图直观地测试了几个形状的代码。请注意,对于具有水平线和垂直线的形状,通常的线方程可能会导致除以零

导入matplotlib.pyplot作为plt
将numpy作为np导入
vertices1=[(6702734879507),(6772414859302),(6703884856938),(6634204877144)]
vertices2=[(680000,4872000),(680000,4879000),(690000,4879000),(690000,4872000)]
vertices3=[(6550004857000),(6550004875000),(6650004857000)]
k=np.arange(6)
r=8000
vertices4=np.vstack([690000+r*np.cos(k*2*np.pi/6),4863000+r*np.sin(k*2*np.pi/6)]).T
所有形状=[vertices1,vertices2,vertices3,vertices4]
对于所有形状的顶点:
plt.plot([x代表x,y在顶点中]+[vertices[0][0],[y代表x,y在顶点中]+[vertices[0][1],'g-',lw=3)
对于zip中的x,y(np.random.randint(6500007000001000),np.random.randint(485500048800001000)):
颜色=‘绿松石色’
对于所有形状的顶点:
如果测试点(x、y、顶点):
颜色=‘番茄’
plt.绘图(x,y,'.',颜色=颜色)
plt.gca().set_aspect('equal'))
plt.show()

PS:如果您运行的是32位版本的numpy,那么对于这个大小的整数,可能需要将值转换为浮点以避免溢出

如果需要经常进行此计算,可以预先计算并存储
a、b、c
值。如果边的方向已知,则只需要
all_left
all_right
中的一个

形状固定后,可以生成函数的文本版本:

def generate_test_函数(顶点,is_顺时针=True,function_name='test_function'):
ext_vert=列表(顶点)+[顶点[0]]

由于形状是一个精确的矩形,最简单的方法是按角度旋转所有点

-arctan((4859302-4856938)/(677241-670388))
这样,矩形将与轴对齐,您只需执行四个坐标比较。旋转很容易用复数计算


事实上,您可以简单地将所有点表示为复数,计算由某一侧定义的向量,然后将所有点乘以共轭



一种稍有不同的方法是考虑坐标系的变化,它给原点和两个入射面带来了一个角到(1,0)和(0,1)。这是一个仿射变换。然后,您的测试归结为检查单位正方形的内部。

它是否始终是一个旋转的矩形?你知道旋转的角度吗?而且它的形状总是一样的。旋转的矩形是市政的近似边界。如果一个答案解决了你的问题,你可能会认为它是被接受的。这是如何处理水平线的特殊情况的?@布莱恩方程是这样写成的,没有划分(没有计算斜率)。这样,它们可以在任何方向的直线上工作。由于
=
的原因,当两个连续点相等时,它甚至可以工作,尽管不建议这样做。但它对凹形不起作用。谢谢!说到Python,我非常不懂。当我粘贴到您的脚本中时,会出现语法错误。你知道为什么吗?也许您的Python版本不知道星形语法。我只是修改了代码,使之在没有它的情况下工作。@User1973:mh,不,不是那样的。