[英]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])
. p1
和p2
是长度为 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)
.通过
p1
和p2
的线可以参数化为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 < 0
或t > 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.