加速度计 - 在球滚动的球
问题描述:
我想用手机加速计用于滚动球的球。运动工程 正确的,问题是,当球撞到墙。我怎样才能得到一个平滑的滚动 动画球沿大球的内侧?
i want to use the phones accelerometer for rolling a Ball in a Ball. The movement works correctly, the problem is that when the ball hits the Wall. How can i get a smooth rolling animation that the ball slides along the inner side of the bigger ball?
这是我目前的code键移动球和检查的交集:
This is my current code to move the Ball and check the intersection:
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];
}
};
感谢您的帮助:)
Thanks for Helping :)
答
在短短的滑动情况下使用参数圆式
x=x0+r*cos(a)
y=y0+r*sin(a)
- 其中X0,Y0是大圆圈中心
-
R = R0,R1
- R0是大圈半径
- R1是小圆半径
- where x0,y0 is the big circle center
r = R0-R1
- R0 is big circle radius
- R1 is small circle radius
- 最简单的办法是把
A =重力方向
这样: -
A = atanxy(acceleration.x,acceleration.y)
- atanxy是ATAN2这是4象限弓tangens
- 如果你没有它用我的 atanxy C ++实现
- 和纠正角度,你的坐标系
- (也许否定和或者增加一些90degree多个)
- the simplest would be to place
a=gravity direction
so: a=atanxy(acceleration.x,acceleration.y)
- atanxy is atan2 which is 4-quadrant arcus tangens
- if you dont have it use mine atanxy C++ implementation
- and correct the angle to your coordinate systems
- (maybe negate and or add some 90degree multiple)
- 如果您有兼容的协调屏和设备加速计之间的系统
- 然后就扩展加速度矢量大小| R |加(X0,Y0),将它
- 和你有同样的结果withouth的任何测角功能...
现在的夹角 A
[注]
进行适当的模拟使用D'兰伯特方程+圆边界
所以2D运动是pretty的方便:
so the 2D movement is pretty easy:
// 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;
现在如果(|位置big_circle_center |&GT; big_circle_radius)
发生碰撞
- 所以当你不希望任何反弹(所有的能量被吸收),那么:
-
位置 - = big_circle_center;
-
位置* = big_circle_radius / |位置|;
-
位置+ = big_circle_center;
- 现在,你需要删除的径向速度,只剩下切速度
-
=正常位置big_circle_center
//法线表面 -
正常* =点(速度,正常)
//这是正常速度的一部分 -
网速度=正常
//现在只是切线速度应留 -
- 在打完这只是正切(黄色)速度的一部分,仍然...
- 希望我没有忘了什么东西(像化妆单位向量或+/-某处...)
- so when you do not want any bounce (all energy was absorbed) then:
position-=big_circle_center;
position*=big_circle_radius/|position|;
position+=big_circle_center;
- now you need remove the radial speed and left just tangent speed
-
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 - so after this just tangent (Yellow) part of velocity remains ...
- hope I did not forget something (like make unit vector or +/- somewhere...)