简体   繁体   English

我有 2 个点 (x1,y1) & (x2,y2) 和一个圆,假设 2 个点之间有一条线我需要检查是否与圆发生碰撞

[英]I have 2 points (x1,y1) & (x2,y2) and a circle, suppose there is a line between the 2 points I need to check if there is collision with the circle

As I mentioned in the title, suppose I have a line segment from point 1 to point 2 and there is a circle with a center and radius I need to check if there is going to be a collision with the circle using code.正如我在标题中提到的,假设我有一条从点 1 到点 2 的线段,并且有一个具有中心和半径的圆,我需要使用代码检查是否会与圆发生碰撞。 This is how far I got.这就是我走多远。 However, there is an issue with closestX and closestY since I need to check if they are on the line segment from point 1 to point 2 because if they are not on the line segment then there will be No collision.但是,最近X 和最近Y 存在问题,因为我需要检查它们是否在从点1 到点2 的线段上,因为如果它们不在线段上,则不会发生碰撞。 Sadly though Im stuck here and I cannot figure out a way to check if they are on the line segment or not.可悲的是,虽然我被困在这里,但我无法找到一种方法来检查它们是否在线段上。 Please help thank you.请帮忙谢谢。

import math
p=2
obsHeight=200
DroneHeight=150
cx=3
cy=3
r=1
x1=1
y1=1
x2=1.5
y2=1.5


if DroneHeight<=obsHeight:
    distX= x1 - x2
    distY= y1 - y2
    length=math.sqrt((distX*distX) + (distY*distY ))
    dot= (((cx-x1)*(x2-x1)) + ((cy-y1)*(y2-y1)) )/(math.pow(length,p))
    closestX=x1+( dot * (x2-x1))
    closestY=y1+( dot * (y2-y1))
    print(" Closest x: ",closestX)
    print(" Closest y: ",closestY)
    distX=closestX-cx
    distY= closestY-cy
    distance= math.sqrt((distX*distX) + (distY*distY ))
    print("The distance is: ", distance)
    print("The length is: ", length)
    if (r==distance):
        print("Touching")
    elif (distance<r):
        print("COLLIDING")
    else:
        print("Will not collide")
else:
    print(" Will not collide, the drone is higher than the obstacle")


You can calculate the squared distance of the center of the circle to the line by您可以通过以下方式计算圆心到直线的平方距离

d2 = ((y1-y2)*(cx-x1)+(x2-x1)*(cy-y1))**2/((x2-x1)**2+(y2-y1)**2)

Now just compare that value to the squared radius.现在只需将该值与平方半径进行比较。 If d2<r**2 then the line cuts the circle如果 d2<r**2 则线切圆

Ignoring the specificity of your code, let's say that you have a line segment, a center and a radius.忽略代码的特殊性,假设您有一条线段、一个中心和一个半径。 Let's write a general solution to whether a line segment in N-dimensions intersects a hyper-sphere in N-dimensions.让我们写一个 N 维中的线段是否与 N 维中的超球面相交的通用解决方案。 This will give us the correct solution for your problem in the special case of 2D.这将为我们在 2D 的特殊情况下为您的问题提供正确的解决方案。

Your function signature would look like this:您的 function 签名将如下所示:

def intersects(p1, p2, c, r):

p1 and p2 are vectors of length N. In your case, p1 = np.array([1, 1]) , and p2 = np.array([1.5, 1.5]) . p1p2是长度为 N 的向量。在您的情况下, p1 = np.array([1, 1])p2 = np.array([1.5, 1.5]) c is a vector of the same length ( c = np.array([3, 3]) ), and r is a scalar radius ( r = 1 ). c is a vector of the same length ( c = np.array([3, 3]) ), and r is a scalar radius ( r = 1 ). I strongly recommend using numpy arrays for your math because it is much faster if you use it right, and you can apply element-wise operations to arrays (eg p2 - p1 ) without using a loop.我强烈建议您使用 numpy arrays 进行数学运算,因为如果正确使用它会更快,并且您可以在不使用循环的情况下对 arrays(例如p2 - p1 )应用逐元素运算。

A line passing through p1 and p2 can be parametrized as p = p1 + t * (p2 - p1) .通过p1p2的线可以参数化为p = p1 + t * (p2 - p1) Every point on the line p corresponds some value of the parameter t .线p上的每个点都对应于参数t的某个值。 Specifically, t == 0 corresponds to p = p1 and t == 1 corresponds to p = p2 .具体来说, t == 0对应于p = p1并且t == 1对应于p = p2 That means that you can know if a point is on the line segment by checking if its parameter is in the range [0, 1] .这意味着您可以通过检查其参数是否在[0, 1]范围内来知道一个点是否在线段上。

The problem then becomes finding the value of t such that p is closest to c .然后问题变成找到t的值,使得p最接近c If t < 0 or t > 1 , then you know that the extrema for the line segment are at the endpoints.如果t < 0t > 1 ,那么您知道线段的极值在端点处。 Otherwise, you need to compare the distances of both the endpoints and the p you found.否则,您需要比较端点和您找到的p的距离。

There are a couple of different ways of coming up with the solution.有几种不同的方法可以提出解决方案。 The geometric approach uses the fact that the nearest approach happens at the perpendicular from c to the line.几何方法使用最近的方法发生在从c到直线的垂直线的事实。 The differential approach finds where the derivative of the length is zero.微分方法找到长度的导数为零的位置。 I will show the former here.我将在这里展示前者。

在此处输入图像描述

Looking at the diagram, you have the following equation:查看图表,您有以下等式:

(c - p).dot(p2 - p1) == 0
(c - p1 + t * (p2 - p1)).dot(p2 - p1) == 0
c.dot(p2 - p1) - p1.dot(p2 - p1) + t * (p2 - p1).dot(p2 - p1) == 0
t == (p1.dot(p2 - p1) - c.dot(p2 - p1)) / (p2 - p1).dot(p2 - p1)

You can now write your function like this:您现在可以像这样编写 function :

def intersects(p1, p2, c, r):
    c1 = np.subtract(p1, c)
    c2 = np.subtract(p2, c)

    dist1 = np.linalg.norm(c1)
    dist2 = np.linalg.norm(c2)

    # If point are on opposite sides of circle, intersects
    if (r - dist1) * (r - dist2) < 0:
        return True

    # If both on inside, does not intersect
    if r > dist1:
        return False

    dp = np.subtract(p2, p1)
    t == dp.dot(c1) / dp.dot(dp)

    # If closest approach is outside segment, does not intersect
    # convince yourself of this (use symmetry about the line c-p)
    if t < 0 or t > 1:
        return False

    cp = np.subtract(p1 + t * dp, c)
    distp = np.linalg.norm(cp)
    # only other possibility of approach is when closest point is inside radius
    return distp <= r

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用matplotlib.pyplot [[x1,y1],[x2,y2]]绘制点 - draw points using matplotlib.pyplot [[x1,y1],[x2,y2]] 坐标几何/如何用点(x1 y1)和(x2 y2)之间的距离分配point_dist? - Coordinates geometry / How to assign point_dist with distance between points (x1 y1) and (x2 y2)? 如何在Python中缩放一条线的长度并获得相应的坐标((x1,y1),(x2,y2))? - How can I scale the length of a line and obtain the corresponding co-ordinates ((x1, y1), (x2, y2)) in Python? 如何将 x1、x2、y1、y2 数组转换为矩形顶点数组? - How do I turn x1, x2, y1, y2 array into rectangular vertices array? 比较两个numpy数组:(x1,y1)和(x2,y2),以检查元素是否相交 - Comparing two numpy arrays: (x1, y1) and (x2, y2) to check whether elements intersect 如何将 numpy 数组 [(x1,y1),(x2,y2),(x3,y3),...(xn,yn)] 转换为 [(x1,y1,x1^2,y1^2),(x2 ,y2,x2^2,y2^2),…(xn,yn,xn^2,yn^2)] - How to convert a numpy array [(x1,y1),(x2,y2),(x3,y3),…(xn,yn)] to [(x1,y1,x1^2,y1^2),(x2,y2,x2^2,y2^2),…(xn,yn,xn^2,yn^2)] Python:从 x 轴上的点 (X1,0) 到点 (X2,Y2) 绘制线的问题 - Python: Problem with plotting lines from points (X1,0) on x axis to points (X2,Y2) 如何计算x,y坐标的点相对于直线的比例百分比(也有x1,y1,x2,y2) - How to calculate the proportional percentage of a point of an x,y coordinate with respect to a line (also with x1, y1, x2, y2) 如何从列表中表达 x1, y1, x2, y2 - How to express x1, y1, x2, y2 from a list 通过完全控制自动将鼠标从 X1、Y1 移动到 X2、Y2 - Automate Mouse Movement from X1,Y1 to X2,Y2 with complete control
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM