vectorgame-physicsphysicspath-findinggeometry-surface

How do I figure out the path along a circle when a velocity vector encounters it?


I am trying to push an object/particle on a 2-d plane which is populated with immovable circular obstacles. My desire is that when the particle encounters an obstacle, it "pushes" around the parameter of the circle until it can resume its original vector (albeit offset by having to "push around" the circle. I've attached an image to illustrate what I'm trying to do.

My problem is not only do I not know how to do this, I don't even know how to search for this with the correct geometry/math/physics jargon. I know I've seen this sort of movement displacement before (in games) so I fully expect it may have already been asked.

I'd love it if someone could point me in the right direction. Even better if someone can explain the solution in code.

So far, this is what I've managed to coble together with my own understanding...

  1. Particle moves a given distance over time (velocity)
  2. When calculating position each "frame", it's not difficult to find out how much of next step would puncture the circle's perimeter.
  3. I could just use the length of this increment as an arc length on the circle and use that adjustment as the final position for the particle for this "frame".

But I don't know how to determine which direction the particle should travel on the circle. Also, I don't know if the arc-length is the best solution because, in theory if the particle struck the circle directly head-on, it should basically not move at all (pushing directly against an immovable object). This would be rare edge-case and similar to the egg perched perfectly on a barn roof.

Like I said, any help for any kind of solution would be much appreciated.Image of what this looks like in a 2-d environment What I think the math problem is What I think the math problem is


Solution

  • I've come up with a solution that works specifically in my situation and is what I think is the common and "easy" answer.

    This answer depends on a few things:

    1. This is a frame-by-frame calculation of position
    2. The velocity or change in position between frames will (almost) always be less than the radius of the obstacle (otherwise this solution will allow suitably fast particles to pass through the obstacle)

    Basically, when the position of the particle is inside the circle, I reposition the particle at the perimeter of the circle at an angle based on the circle's center. So this is like the circle "pushes" any particle caught inside of it directly away from its center to its perimeter.

    This definitely isn't as realistic or robust as a proper formula, but it solves my current problem.

    I'm doing this in Unity/C#:

    Vector3 nextPos = testPos.transform.position;
        
    float dx = nextPos.x - obstacle.transform.position.x;
    float dy = nextPos.y - obstacle.transform.position.y;
    float d2 = dx * dx + dy * dy;
    float r = obstacle.transform.localScale.x / 2;
    float r2 = r * r;
    if (d2 < r2) {
        float d = Mathf.Sqrt(d2);
        
        float dxNorm = dx / d;
        float dyNorm = dy / d;
        Vector3 skirtPos = new Vector3(obstacle.transform.position.x + (dxNorm * r), obstacle.transform.position.y + (dyNorm * r));
        resultPos = skirtPos;
    } else {
        resultPos = nextPos;
    }