I wanted to make the object bounce inside the circle, as a result of which the object moved along the edge of the circle

Here is the code in question:

public void calculate() { // Center of circle is at (250, 250). //THIS ALGORITHM IS NOW PROVEN TO BE WORSE THAN I FEARED... /* What it does: * Moves object around in a circle. * Does not move the object towards the center. * Object always stays on the rim of the circle. * * Algorithm I used. (DOES NOT WORK): * N is normalized vector. * R = -2*(V dot N)*N + V */ vx += Accelero.X * 0.1; vy += Accelero.Y * 0.1; double nx = x - 250; double ny = y - 250; double nd = Math.hypot(nx, ny); if (nd == 0) nd = 1; nx /= nd; ny /= nd; double dotProduct = vx * nx + vy * ny; vx += (float) (-2 * dotProduct * nx); vy += (float) (-2 * dotProduct * ny); x -= vx * 2; y -= vy * 2; vx *= 0.99; vy *= 0.99; } 

And this is what happens.

Picture.

The black line on which you see the purple object (box) moves. It just happens on the circle line that I drew using Canvas.drawCircle() .

I do not understand why the reflection did not work. If an object hits a circular wall, should it not reflect the direction of movement of the object, what was the algorithm supposed to be? Or did I use the wrong algorithm?

Any help is appreciated. Thanks in advance.

0
source share
3 answers

This is what I have, and I am going to share my findings with all of you.

 public void calculate() { // Center of circle is at (250, 250). Radius is 40. //THIS ALGORITHM IS PROVEN TO BE BETTER THAN I FEARED... /* What it does: * Moves object around in a circle, if object is * inside of circle. * Does not move the object towards the center, * nor outwards. This is crucial. * Object always stays on the rim of the circle, * if the collision detection allows it to. * * Algorithm I used. (DOES WORK, NOT EXPECTING THIS THOUGH.): * N is normalized vector. * R = -2*(V dot N)*N + V */ double nx = x - 250; double ny = y - 250; double nd = Math.hypot(nx, ny); if (nd < 40){ vx += Accelero.X * 0.1; vy += Accelero.Y * 0.1; x -= vx; y -= vy; vx *= 0.9; vy *= 0.9; return; } vx += Accelero.X * 0.1; vy += Accelero.Y * 0.1; if (nd == 0) nd = 1; nx /= nd; ny /= nd; double dotProduct = vx * nx + vy * ny; vx += (float) (-2 * dotProduct * nx); vy += (float) (-2 * dotProduct * ny); x -= vx * 2; y -= vy * 2; vx *= 0.99; vy *= 0.99; } 

I turned on collision detection inside my function, basically making this function not as efficient as possible. Ignore this, as this is not the main focus.

The radius of the circle is 40, the position (x, y) is (250 250).

Only when the object is either on the circle or further from the center of the circle, we must calculate the collision reaction, which is given by the algorithm R = -2 * (V dot N) * N + V, where the normal vector N is already normalized.

The algorithm is really correct, this is the logical condition for my collision detection - this is what makes the object stay on the rim of the circle and go back and forth.

I did not say the other algorithm provided by @trashgod is wrong. This is due to some strange problem that somehow makes the object move unusually. I would have guessed that the API, I am using an error that does not allow doubling, but I may be incorrect. I just could not find the source of the problem. Which I am also glad not to look into her further.

A boolean collision detection condition can change everything if it has been slightly modified. If it werenโ€™t for @nm indicating that I somehow forgot the minus sign (in this case, the NOT sign), I probably never understood how trivial it would be.

+1
source

Can you bounce off a straight wall of an arbitrary angle? This should be the first step. (You may find that the polar representation of the velocity vector is easier to work with.)

Once it works for you, it should be pretty simple: the rebound from the circle is similar to the rebound from the tangent of this circle, which touches it at the point of contact.

You can calculate this tangent by observing that it is perpendicular to the radius vector at the point of contact (that is, a vector that indicates where the object is in the center of the circle)

+2
source

Is there such a vector implementation without relying on angles?

Yes, see 2-dimensional elastic collisions without trigonometry , illustrated in this KineticModel . It seems that your implementation lacks a tangential component. See Ensemble#collideAtoms() more details.

+2
source

Source: https://habr.com/ru/post/1242502/


All Articles