我是编码新手。现在我有一个问题。我有一个物体继续在一个矩形区域移动。而且我在这个领域也有很多圈子。我想获得轨迹和所有圆圈之间的所有交点。当物体逐步移动时,我认为可以计算物体位置与每个圆的所有中心之间的距离,并将距离与圆的半径进行比较。但我认为这会做很多计算,因为你需要计算每一步的距离。你有什么好主意或参考。顺便说一下,我正在使用python。谢谢。由于我没有足够的声誉,我无法添加关于问题的图片
答案 0 :(得分:1)
除非您的轨迹已经是直线,否则您可能想要计算它的分段线性近似。然后对于每个段,您可以使用二次方程计算line-circle intersections,并检查交点是否真实(如果线经过圆并且平方根下的项变为负,则检查是否复杂)以及是否它们位于段上(与端点之外的线段相对)。
假设您有一个从( x1 , y1 )到( x2 , y2 )的线段和想要与半径 r 的以( xc , yc )为中心的圆相交。那么你想解决方程式
((1 - t)*x1 + t*x2 - xc)² + ((1 - t)*y1 + t*y2 - yc)² = r²
如果你根据 t 的力量收集术语,你会在 t 中得到以下二次方程式:
((x1 - x2)² + (y1 - y2)²)*t²
+ 2*((x1 - x2)*(xc - x1) + (y1 - y2)*(yc - y1))*t
+ ((xc - x1)² + (yc - y1)² - r²) = 0
所以你可以用Python代码写这个(未经测试):
def circleSegmentIntersections(x1, y1, x2, y2, xc, yc, r):
dx = x1 - x2
dy = y1 - y2
rx = xc - x1
ry = yc - y1
a = dx*dx + dy*dy
b = dx*rx + dy*ry
c = rx*rx + ry*ry - r*r
# Now solve a*t^2 + 2*b*t + c = 0
d = b*b - a*c
if d < 0.:
# no real intersection
return
s = math.sqrt(d)
t1 = (- b - s)/a
t2 = (- b + s)/a
if t1 >= 0. and t1 <= 1.:
yield ((1 - t1)*x1 + t1*x2, (1 - t1)*y1 + t1*y2)
if t2 >= 0. and t2 <= 1.:
yield ((1 - t2)*x1 + t2*x2, (1 - t2)*y1 + t2*y2)
如果您的轨迹是弯曲的,但有一些很好的数学描述,如自由落体抛物线或Bézier曲线或类似的东西,那么您可以避免分段线性逼近并尝试直接计算交点。但有可能这样做需要找到一些高阶多项式的根,这只能用数字来完成。
答案 1 :(得分:1)
让a
为大圆的半径和直径之间的某个数字(如果它们具有不同的半径)。
生成边长为a的正方形图块网格,以便grid(i,k)
是从(i*a,k*a)
到((i+1)*a, (k+1)*a)
的正方形。
网格的每个图块都包含一个列表,其中包含指向圆形数组中圆圈或索引的指针。
对于每个圆圈,将其与每个圆相交的每个瓷砖进行注册。应该少于4个。
现在测试圆形交叉点轨迹的(x,y)
点。在相应磁盘内包含,您只需要根据图块((int)(x/a), (int)(y/a)
中的圆圈列表进行测试。
答案 2 :(得分:0)
一般情况下,我建议您首先使算法运行,然后在需要时加快速度。你会惊讶于Python与一组精心挑选的库结合的速度有多快。
因此,对于您的问题,我会执行以下操作:
1。)安装一套让您的生活更轻松的库: - 用于2D矩形,圆形和圆形绘图的Matplotlib 轨迹
2。)Numpy用于通用数组操作
3.。)Scipy可选择其KDTree支持(最近邻搜索)
4.)开始实施您的问题 a。)创建一个矩形并使用Matplotlib
显示它b。)创建一组圆并在4a的矩形区域内绘制它们
c。)创建轨迹并在矩形区域内绘制它们
现在更困难的部分开始了。前进的方向取决于您的轨迹如何定义。例如,如果您的轨迹由线段组成,则可以分析地计算圆与线段之间的交点。存在三种可能的解决方案,没有交叉点,1个交叉点(线接触圆)和2个交叉点。如果您的轨迹更复杂,您可以通过沿其生成许多点来离散它,并计算该点是否位于其中一个圆的边缘。你必须要有点聪明,但是如何确定3个可能的解决方案,因为沿着轨迹的点是有限的。
另一种选择是将圆圈边缘上的点离散化。这意味着问题会在很大程度上减少到最近邻搜索,您可以使用Scipy KDTree类。