user-0 提问: 应该用哪种公式？？

回复:
user: user-1
content: 镜像似乎是不错的思路，但是处理起来不简单吧。 小球碰到盒子的四个边，运动方向变化时不同的，分段处理，算出反弹位置和方向，然后递归即可。  #include <stdio.h> #include <math.h>  /**   * @brief 小球与盒子  *   * @param x1 盒子左下角 x 坐标  * @param y1 盒子左下角 y 坐标  * @param x2 盒子右上角 x 坐标  * @param y2 盒子右上角 y 坐标  * @param x0 小球 x 坐标  * @param y0 小球 y 坐标  * @param d0 小球方向角 [-pi,+pi)  * @param n 计数器  */  /*  *                        (x2,y2)  *   -----------------------  *   |\                   /|  *   | \                 / |  *   |  \               /  |  *   |   d4           d3   |  *   |    \           /    |  *   |     \         /     |  *   |      \       /      |  *   |       \     /       |  *   |        \   /        |  *   |         \ /         |  *   |          + (x0,y0)  |  *   |         / \         |  *   |        /   \        |  *   |       /     \       |  *   |      /       \      |  *   |     /         \     |  *   |   d1           d2   |  *   |   /             \   |  *   |  /               \  |  *   | /                 \ |  *   |/                   \|  *   ----------------------  * (x1,y1)  */   void ball_box(         double x1, double y1, double x2, double y2,         double x0, double y0, double d0, int n) {     double d1, d2, d3, d4;     double xn, yn, dn;      if (n == 1) {         printf("%02d O: x0=%f,y0=%f\n", 0, x0, y0);     }      d1 = atan2(y1 - y0, x1 - x0);     d2 = atan2(y1 - y0, x2 - x0);     d3 = atan2(y2 - y0, x2 - x0);     d4 = atan2(y2 - y0, x1 - x0);      if (0) {         ;     } else if (d0 >= d1 && d0 < d2) {         /* 小球方向 d0 在 [d1,d2) 区间 */         /* 在底边反弹 */         yn = y1;         xn = x0 + (y1 - y0) / tan(d0);         dn = -d0;         printf("%02d B: xn=%f,yn=%f\n", n, xn, yn);     } else if (d0 >= d2 && d0 < d3) {         /* 小球方向 d0 在 [d2,d3) 区间 */         /* 在右边反弹 */         xn = x2;         yn = y0 + (x2 - x0) * tan(d0);         if (d0 > 0) {             dn = M_PI - d0;         } else {             dn = -M_PI - d0;         }         printf("%02d R: xn=%f,yn=%f\n", n, xn, yn);     } else if (d0 >= d3 && d0 < d4) {         /* 小球方向 d0 在 [d3,d4) 区间 */         /* 在顶边反弹 */         yn = y2;         xn = x0 + (y2 - y0) / tan(d0);         dn = -d0;         printf("%02d T: xn=%f,yn=%f\n", n, xn, yn);     } else if (d0 >= d4 || d0 < d1) {         /* 小球方向 d0 在 [d4,+pi) 和 [-pi,d1) 区间 */         /* 在左边反弹 */         xn = y1;         yn = y0 + (x1 - x0) * tan(d0);         if (d0 > 0) {             dn = M_PI - d0;         } else {             dn = -M_PI - d0;         }         printf("%02d L: xn=%f,yn=%f\n", n, xn, yn);     }      if (n < 20) {         ball_box(x1, y1, x2, y2, xn, yn, dn, n + 1);     } }  int main(int argc, char *argv[]) {      ball_box(0, 0, 2, 2, 1, 0, M_PI / 4.0, 1);     ball_box(0, 0, 2, 100, 1, 1, +M_PI * (1.0/4.0), 1);     ball_box(0, 0, 2, 100, 1, 1, atan2(1, 2), 1);     ball_box(0, 0, 4, 6, 2, 1, M_PI / 4.0, 1);      return 0; }

user: user-2
content: 这个思路有意思。 求触点的时候，扩展的盒子的翻转可以这样： 纵向：距离为奇数时上下翻转，偶数不变 横向：距离为奇数时左右翻转，偶数不变  变换后，就是反算到原盒子的坐标了

user: user-3
content: 其实lz应该先写一下大概思路，找出规律

user: user-3
content: 不知道。。。

user: user-4
content: 可以給完整代碼嗎? 我這樣看這裡有問題 int i; for(i=0; i<0;i++){ printf("(%f, %f)\n)", x,y);  i 你用整數 迴圈就有問題了

user: user-0
content: 没人会吗？？？？？？