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...
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.
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:
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;
}