簡體   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

正如我在標題中提到的,假設我有一條從點 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):

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 ). 我強烈建議您使用 numpy arrays 進行數學運算,因為如果正確使用它會更快,並且您可以在不使用循環的情況下對 arrays(例如p2 - p1 )應用逐元素運算。

通過p1p2的線可以參數化為p = p1 + t * (p2 - p1) p上的每個點都對應於參數t的某個值。 具體來說, t == 0對應於p = p1並且t == 1對應於p = p2 這意味着您可以通過檢查其參數是否在[0, 1]范圍內來知道一個點是否在線段上。

然后問題變成找到t的值,使得p最接近c 如果t < 0t > 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM