加速度计 – 球滚球

我想用手机加速度计来滚动球。 运动正常,问题是当球击中墙壁时。 我怎样才能得到一个平滑的滚动动画,球在大球的内侧滑动?

球在球

这是我当前移动球并检查交叉点的代码:

onSuccess: function(acceleration) { var xPos = this.xPos + (-1 * (acceleration.x * 0.5)); var yPos = this.yPos + (acceleration.y * 0.5); var intersect = this.intersection(xPos + 32, yPos + 32, 32, self.canvas.width * 0.5, self.canvas.height * 0.5, self.canvas.width * 0.5); if (!intersect) { this.yPos = yPos; this.xPos = xPos; } this.cnv.clearRect(0.0, 0.0, this.canvas.width, this.canvas.height); this.cnv.drawImage(this.target, this.xPos, this.yPos); }, intersection: function(x0, y0, r0, x1, y1, r1) { var a, dx, dy, d, h, rx, ry; var x2, y2; /* dx and dy are the vertical and horizontal distances between * the circle centers. */ dx = x1 - x0; dy = y1 - y0; /* Determine the straight-line distance between the centers. */ d = Math.sqrt((dy*dy) + (dx*dx)); /* Check for solvability. */ if (d > (r0 + r1)) { /* no solution. circles do not intersect. */ return false; } if (d < Math.abs(r0 - r1)) { /* no solution. one circle is contained in the other */ return false; } /* 'point 2' is the point where the line through the circle * intersection points crosses the line between the circle * centers. */ /* Determine the distance from point 0 to point 2. */ a = ((r0*r0) - (r1*r1) + (d*d)) / (2.0 * d) ; /* Determine the coordinates of point 2. */ x2 = x0 + (dx * a/d); y2 = y0 + (dy * a/d); /* Determine the distance from point 2 to either of the * intersection points. */ h = Math.sqrt((r0*r0) - (a*a)); /* Now determine the offsets of the intersection points from * point 2. */ rx = -dy * (h/d); ry = dx * (h/d); /* Determine the absolute intersection points. */ var xi = x2 + rx; var xi_prime = x2 - rx; var yi = y2 + ry; var yi_prime = y2 - ry; return [xi, xi_prime, yi, yi_prime]; } }; 

谢谢你的帮助:)

在滑动情况下使用参数圆方程

 x=x0+r*cos(a) y=y0+r*sin(a) 

哪里:

  • x0,y0是大圆心
  • r = R0-R1
  • R0是大圆半径
  • R1是小圆半径

现在角度a

最简单的方法是放置a=gravity direction这样:

 a=atanxy(acceleration.x,acceleration.y) 

atanxyatan2 ,它是4象限的atanxy tangens。 如果你没有它使用我的

  • atanxy C ++实现

并纠正你的坐标系的角度(可能否定和或添加一些90度的多个)

[笔记]

如果屏幕和设备加速度计之间有相容的坐标系,那么只需将加速度矢量缩放到尺寸|r| 并添加(x0,y0) ,你有相同的结果,没有任何测角function……

为了正确模拟,使用D’Lambert方程+圆边界

所以2D运动非常简单:

 // in some timer with interval dt [sec] velocity.x+=acceleration.x*dt; velocity.y+=acceleration.y*dt; position.x+=velocity.x*dt; position.y+=velocity.y*dt; 

现在if (|position-big_circle_center|>big_circle_radius)发生碰撞,那么当你不想要任何反弹(所有能量被吸收)时,那么:

 position-=big_circle_center; position*=big_circle_radius/|position|; position+=big_circle_center; 

现在你需要移除径向速度并保持切线速度:

 normal=position-big_circle_center; // normal vector to surface normal*=dot(velocity,normal); // this is the normal speed part velocity-=normal; // now just tangential speed should be left 

在此处输入图像描述

所以在这之后只有切线(黄色)部分的速度仍然存在…希望我没有忘记一些东西(比如制造单位矢量或+/-某处…)