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. 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. 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")
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. This will give us the correct solution for your problem in the special case of 2D.
Your function signature would look like this:
p1andp2are vectors of length N. In your case,p1 = np.array([1, 1]), andp2 = np.array([1.5, 1.5]).cis a vector of the same length (c = np.array([3, 3])), andris 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 (e.g.p2 - p1) without using a loop.A line passing through
p1andp2can be parametrized asp = p1 + t * (p2 - p1). Every point on the linepcorresponds some value of the parametert. Specifically,t == 0corresponds top = p1andt == 1corresponds top = 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].The problem then becomes finding the value of
tsuch thatpis closest toc. Ift < 0ort > 1, then you know that the extrema for the line segment are at the endpoints. Otherwise, you need to compare the distances of both the endpoints and thepyou found.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
cto the line. 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:
You can now write your function like this:
The problem of finding the distance between a point and a line has cropped up a number of times on Stack Overflow, and in my applications as well, so I recently added it to a library of utilities that I maintain,
haggis. You can build a solution usinghaggis.math.segment_distancewith very similar logic. I specifically made the function operate in line segment or full-line mode for this purpose:You could rewrite the last two lines as follows: