Quería hacer rebotar un objeto dentro de un círculo, terminó haciendo que el objeto se moviera a lo largo del borde del círculo

Aquí está el código en cuestión:

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

Y esto es lo que pasa.

La línea negra que ve es donde se mueve el objeto púrpura (cuadro). Resulta que está justo en la línea circular que dibujé conCanvas.drawCircle().

No entiendo por qué la reflexión no funcionó. Si un objeto es golpear una pared circular, ¿no debería reflejar la dirección de la velocidad del objeto, que es lo que se supone que debe ser el algoritmo? ¿O usé el algoritmo equivocado?

Cualquier ayuda es apreciada. Gracias por adelantado.

Respuestas a la pregunta(3)

Su respuesta a la pregunta