线与点之间的2d碰撞

时间:2010-10-14 04:16:58

标签: iphone objective-c physics

我试图理解第二世界的碰撞检测。我最近得到了这个教程http://www.gotoandplay.it/_articles/2003/12/bezierCollision.php。我有一些问题让我很困惑 - 如果我尝试交换起点和终点,那么flash演示球正在下降而没有响应。 有人可以解释我,模拟是如何工作的。 我修改了示例代码。它工作完美,直到开始和结束点交换,这是目标c中的相同代码

提前致谢。

-(void)render:(ccTime)dt {

 if(renderer)
 {
  CGPoint b = ball.position;


  float bvx = ball.vx;
  float bvy = ball.vy;

  bvx += .02;
  bvy -= .2;

  b.x += bvx;
  b.y += bvy;

  float br = ball.contentSize.width/2;
  for ( int p = 0 ; p < [map count]  ; p++ ) {

   line *l = [map objectAtIndex:p];
   CGPoint p0 = l.end;
   CGPoint p1 = l.start;

   float p0x = p0.x, p0y = p0.y, p1x = p1.x, p1y = p1.y;

   // get Angle //

   float dx = p0x - p1x;
   float dy = p0y - p1y;

   float angle = atan2( dy , dx );

   float _sin = sin ( angle );
   float _cos = cos ( angle );

   // rotate p1 ( need only 'x' ) //

   float p1rx = dy * _sin + dx * _cos + p0x;

   // rotate ball //

   float px = p0x - b.x;
   float py = p0y - b.y;

   float brx = py * _sin + px * _cos + p0x;
   float bry = py * _cos - px * _sin + p0y;

   float cp = ( b.x - p0x ) * ( p1y - p0y ) - ( b.y - p0y ) * ( p1x - p0x );

   if ( bry > p0y - br && brx > p0x && brx < p1rx && cp > 0 ) {

    // calc new Vector //

    float vx = bvy * _sin + bvx * _cos;
    float vy = bvy * _cos - bvx * _sin;

    vy *= -.8;
    vx *= .98;

    float __sin = sin ( -angle );
    float __cos = cos ( -angle );

    bvx = vy * __sin + vx * __cos;
    bvy = vy * __cos - vx * __sin;

    // calc new Position //

    bry = p0y - br;

    dx = p0x - brx;
    dy = p0y - bry;

    b.x = dy * __sin + dx * __cos + p0x;
    b.y = dy * __cos - dx * __sin + p0y;

   }

  }
  ball.position = b;
  ball.vx = bvx;
  ball.vy = bvy;

  if ( b.y < 42)
  {

   ball.position = ccp(50, size.height - 42);
   ball.vx = .0f;
   ball.vy = .0f;

  }
 }

}

2 个答案:

答案 0 :(得分:2)

点的顺序定义了曲线上的方向。如果起点位于左侧,而终点位于右侧,则曲线的方向使得“向上”指向曲线上方。但是,如果你交换起点/终点曲线是相反的,所以现在“向上”实际上指向曲线下方。

当您的代码检测到碰撞然后更正速度时,它会使用曲线的方向。这就是为什么当球在曲线上落下并且开始/结束点交换时,它似乎会跳过曲线。

要纠正此问题,您的碰撞分辨率代码应检查球所在的曲线的哪一侧(相对于曲线的方向),并相应地进行调整。

答案 1 :(得分:1)

如果交换l.end和l.start,它将用于没有段的行(l.start,l.end)。这是因为所有值都在这里签名。 算法转动平面,使得线条是水平的,并且其中一个线段末端不移动。之后,很容易理解球是否接触线。如果确实如此,它的速度应该改变:在旋转平面中它只是反转y坐标,我们应该将其旋转回来以使线不再水平。 实际上并不是一个很好的实现。所有这一切都可以在没有罪,cos,只是向量的情况下完成。