2010-10-14 10 views
4

Im essayant de comprendre la détection de collision dans le monde 2D. J'ai récemment obtenu ces tutoriels http://www.gotoandplay.it/_articles/2003/12/bezierCollision.php. J'ai une question qui m'a beaucoup intrigué - sur la boule de démo flash est tomber sans répondre si j'essaie d'échanger le point de départ et de fin. Quelqu'un peut-il m'expliquer comment fonctionne la simulation? J'ai modifié cet exemple de code. Il fonctionne parfaitement jusqu'à ce que le point de départ et le point final soient échangés. Voici le même code dans l'objectif c2d collision entre la ligne et un point

Merci d'avance. .

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

    } 
} 

} 
+0

L'avez-vous simplement porté ou êtes-vous familier avec les maths de Bézier? – Pedery

Répondre

1

Si vous échangez l.end et l.start il servira de ligne sans le segment (l.start, l.end). C'est parce que toutes les valeurs sont signées ici. L'algorithme fait tourner le plan de sorte que la ligne soit horizontale et que l'une des extrémités du segment ne bouge pas. Après cela, il est facile de comprendre si la balle touche la ligne. Et si c'est le cas, sa vitesse devrait changer: dans le plan pivoté, il suffit d'inverser la coordonnée y et nous devrions la faire tourner de nouveau pour obtenir une ligne non horizontale à nouveau. En fait pas une très bonne implémentation. Tout cela peut être fait sans péché, cos, juste des vecteurs.

2

L'ordre des points définit une orientation sur la courbe. Si le point de départ est à gauche et le point final à droite, alors la courbe est orientée de telle sorte que le point «haut» pointe au-dessus de la courbe. Cependant, si vous changez les points de départ/d'arrivée, la courbe est orientée de manière opposée, de sorte que maintenant "up" pointe en dessous de la courbe.

Lorsque votre code détecte une collision et corrige ensuite la vitesse, il utilise l'orientation de la courbe. C'est pourquoi lorsque la balle tombe sur la courbe avec les points de départ/fin échangés, elle semble sauter dans la courbe.

Pour corriger cela, votre code de résolution de collision doit vérifier de quel côté de la courbe la boule est activée (par rapport à l'orientation de la courbe) et ajuster en conséquence.