In a 2D game, i'm trying to repositionate a circle after it passed through a segment. Taking the picture as example situation, i need to reposition back the circle so that B will become the tangent point on the circle.
The informations that i have are:
x,y of the circle
Radius of the circle
dirx, diry: Direction of x,y the circle is having
Distance between A and B
What i'm doing is to calculate the coordinates of point C, then coordinates of point B, and then subtract vector AB from AC (radius), and repositionate x,y back of -BC.
There is something wrong in the algorithm because after that the orthogonal distance between the center and the line is never exactly like the radius.
Len = Sqrt( dirx^2 + diry^2 )
dx = dirx / Len
dy = diry / Len
// these should be coordinates of point C
tangX = x + radius * dx
tangY = y + radius * dy
// these should be coordinates of point B
wrongX = x + distance* dx
wrongY = y + distance* dy
//these should be vector BC
BCx = tangX - wrongX;
BCy = tangY - wrongY;
// now i reposition the center back of BC
x = x - BCx
y = y - BCy
The center is repositionated in the correct direction but never enough to match the distance AC.
In other words: I want to move the center and make B to be the tangent point between the circle and the line. Let me explain you in other words the problem: as you can see length of AC is equal to my radius. The radius is 40. in my log, i print out the value of the distance between A and B. Taking the image as example such distance would be something like 30, after my algorithm i expect that AB is 40 (the radius, AC) but it's always an other number, never 40
This issue is relatively easy to solve, if formulated appropriately. It seems a simple case of collision detection, where you're seeking to adjust the object's position after detecting the collision. The intuitive way to frame it is: you have an event telling you your object crossed a boundary. Its last motion vector is
(dirX, dirY)
and you're given thedelta
your object crossed beyond the boundary. All you need to do is to move your object backwards, the same delta it crossed beyond the boundary, along the same motion vector.And instead of reasoning about the problem in terms of tangent points, you can simply reason about it in terms of the center coordinates of the object itself.
Now, the following parameters are given input:
x, y
be the last coordinates of your object's center andr
its radius(dirX, dirY)
be your motion vectoralpha
be the angle of your motion vector to the x axis (you can compute it from the motion vector itself)delta
be the distance crossed beyond the boundaryThe problem's resolution reduces to the following:
And here's an executable code sample in python 2 that implements and tests that solution:
Addendum
I went through the code you pasted and unless I am mistaken, there is a problem with the logic through which, you are checking for collision and computing the distance from the center of the circle to the intersecting line. An accurate implementation of that logic implies solving a quadratic equation (check this link for future reference) to find out whether the line intersects the circle. Then to compute the distance you'll have to solve an equation based on the dot product of the direction vector of the intersecting line, and the orthogonal line passing through the center of the circle.
Here's a python snippet illustrating the first part (figuring out whether or not the line intersects the circle) and loosely following the steps detailed in the above link: