3
votes

In a timestep-based simulation, a collision between a point particle p(x,y) with velocity v(x,y), that started off from inside a circle (x-a)^2 + (y-b)^2 = r^, with that circle, occurred between two timesteps, such that the point particle has already left the circle when the collision gets detected.

Therefore I want to move the particle back by amount outsideDepth(x,y) such that it lies exactly on the circle.

Now the question is: How can I determine the distance l between the point p and the intersection of the velocity vector with the circle?

In code:

Vector2 circleCollision(double a, double b, double r, double x, double y){

    double s = sqrt( pow((x-a),2) + pow((y-b),2) );

    if (s>r) {
        Vector2 outsideDepth = {0,0};

        // determine depth by which point lies outside circle as vector (x,y)

        return outsideDepth;
    }
}

EDIT Attempt at Ian's solution, substitute 2 and 3 in 1 and rearange for t, then determine p and q as follows:

p = 1/( pow(v.x,2) + pow(v.y,2) ) * (-2*x*v.x + 2*v.x*a - 2*y*v.y + 2*v.y*b);
q = 1/( pow(v.x,2) + pow(v.y,2) ) * (-2*x*a -2*y*b + x*x + y*y + a*a + b*b - r*r);

root = sqrt( pow((p/2),2) - q );
t1 = -p/2 + root;
t2 = -p/2 - root;

// ???
2

2 Answers

1
votes

Simultaneously solve(easy code)

(x-a)^2 + (y-b)^2 = r^2

and

x = p(x) - v(x)*t

y = p(y) - v(y)*t

for some t. There may be zero, one or two solutions depending on the discriminant (use conditionals on b^2 - 4ac). If two solutions (b^2 > 4ac) choose the t which minimizes size(p(x,y) - t(x, y)) (use pythag). Return.

0
votes

You want the new point to be at the same angle as the original point (x, y), but moved in. To move your point "in" to the boundary of the circle, adjust its x coordinate by subtracting

(x -a) * r / d
(y - b) * r / d