[英]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
正如我在標題中提到的,假設我有一條從點 1 到點 2 的線段,並且有一個具有中心和半徑的圓,我需要使用代碼檢查是否會與圓發生碰撞。 這就是我走多遠。 但是,最近X 和最近Y 存在問題,因為我需要檢查它們是否在從點1 到點2 的線段上,因為如果它們不在線段上,則不會發生碰撞。 可悲的是,雖然我被困在這里,但我無法找到一種方法來檢查它們是否在線段上。 請幫忙謝謝。
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")
您可以通過以下方式計算圓心到直線的平方距離
d2 = ((y1-y2)*(cx-x1)+(x2-x1)*(cy-y1))**2/((x2-x1)**2+(y2-y1)**2)
現在只需將該值與平方半徑進行比較。 如果 d2<r**2 則線切圓
忽略代碼的特殊性,假設您有一條線段、一個中心和一個半徑。 讓我們寫一個 N 維中的線段是否與 N 維中的超球面相交的通用解決方案。 這將為我們在 2D 的特殊情況下為您的問題提供正確的解決方案。
您的 function 簽名將如下所示:
def intersects(p1, p2, c, r):
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
). 我強烈建議您使用 numpy arrays 進行數學運算,因為如果正確使用它會更快,並且您可以在不使用循環的情況下對 arrays(例如p2 - p1
)應用逐元素運算。
通過p1
和p2
的線可以參數化為p = p1 + t * (p2 - p1)
。 線p
上的每個點都對應於參數t
的某個值。 具體來說, t == 0
對應於p = p1
並且t == 1
對應於p = p2
。 這意味着您可以通過檢查其參數是否在[0, 1]
范圍內來知道一個點是否在線段上。
然后問題變成找到t
的值,使得p
最接近c
。 如果t < 0
或t > 1
,那么您知道線段的極值在端點處。 否則,您需要比較端點和您找到的p
的距離。
有幾種不同的方法可以提出解決方案。 幾何方法使用最近的方法發生在從c
到直線的垂直線的事實。 微分方法找到長度的導數為零的位置。 我將在這里展示前者。
查看圖表,您有以下等式:
(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)
您現在可以像這樣編寫 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.