2012-11-01 3 views
4

나는 분리 된 축 정리에 대한 내 자신의 구현을 작성하려고하는데, 원하는대로 정확하게 작동하도록하는 데 어려움이 있습니다. 확실히 말할 수는 없지만 모양 주위의 가상 상자가 첫 번째 모양처럼 충돌 할 때 충돌이 발생하는 것처럼 보입니다. 그러나 두 번째 형태는 완벽하게 작동합니다. 여기다각형 충돌 감지 구현

vertsx = [ 200, 220, 220, 200 ] 
vertsy = [ 220, 220, 200, 200 ] 

1 (마우스에 비해) 시험 모양의 정점 데이터의 : 여기

가 광장 (정확한 좌표)에 대한 정점 데이터의

vertsx = [ -10, 0, 10, 10, -10 ] 
vertsy = [ -10, -50, -10, 10, 10 ] 

그리고 마지막으로 여기에 정점 데이터입니다 테스트 모양 2 (마우스와 관련 있음) :

vertsx = [ -10, 0, 10, 10, -10 ] 
vertsy = [ -10, -20, -10, 10, 10 ] 

설명을 위해 번역 된 쿠어 rdinates는 테스트 된 것이고 모양은 표시된 좌표로 테스트되었습니다.

enter image description here

여기에 실제 기능입니다.

function collisionConvexPolygon (vertsax, vertsay, vertsbx, vertsby) { 
    var alen = vertsax.length; 
    var blen = vertsbx.length; 
    // Loop for axes in Shape A 
    for (var i = 0, j = alen - 1; i < alen; j = i++) { 
     // Get the axis 
     var vx = vertsax[ j ] - vertsax[ i ]; 
     var vy = -(vertsay[ j ] - vertsay[ i ]); 
     var len = Math.sqrt(vx * vx + vy * vy); 

     vx /= len; 
     vy /= len; 

     // Project shape A 
     var max0 = vertsax[ 0 ] * vx + vertsay[ 0 ] * vy, min0 = max0; 
     for (k = 1; k < alen; k++) { 
      var proja = vertsax[ k ] * vx + vertsay[ k ] * vy; 

      if (proja > max0) { 
       max0 = proja; 
      } 
      else if (proja < min0) { 
       min0 = proja; 
      } 
     } 
     // Project shape B 
     var max1 = vertsbx[ 0 ] * vx + vertsby[ 0 ] * vy, min1 = max1; 
     for (var k = 1; k < blen; k++) { 
      var projb = vertsbx[ k ] * vx + vertsby[ k ] * vy; 

      if (projb > max1) { 
       max1 = projb; 
      } 
      else if (projb < min1) { 
       min1 = projb; 
      } 
     } 
     // Test for gaps 
     if (!axisOverlap(min0, max0, min1, max1)) { 
      return false; 
     } 
    } 
    // Loop for axes in Shape B (same as above) 
    for (var i = 0, j = blen - 1; i < blen; j = i++) { 
     var vx = vertsbx[ j ] - vertsbx[ i ]; 
     var vy = -(vertsby[ j ] - vertsby[ i ]); 
     var len = Math.sqrt(vx * vx + vy * vy); 

     vx /= len; 
     vy /= len; 

     var max0 = vertsax[ 0 ] * vx + vertsay[ 0 ] * vy, min0 = max0; 
     for (k = 1; k < alen; k++) { 
      var proja = vertsax[ k ] * vx + vertsay[ k ] * vy; 

      if (proja > max0) { 
       max0 = proja; 
      } 
      else if (proja < min0) { 
       min0 = proja; 
      } 
     } 
     var max1 = vertsbx[ 0 ] * vx + vertsby[ 0 ] * vy, min1 = max1; 
     for (var k = 1; k < blen; k++) { 
      var projb = vertsbx[ k ] * vx + vertsby[ k ] * vy; 

      if (projb > max1) { 
       max1 = projb; 
      } 
      else if (projb < min1) { 
       min1 = projb; 
      } 
     } 
     if (!axisOverlap(min0, max0, min1, max1)) { 
      return false; 
     } 
    } 
    return true; 
} 

나에게 필요한 경우 다른 도형을 사용해 보겠습니다.

여기 내 axisOverlap 기능입니다.

function axisOverlap (a0, a1, b0, b1) { 
    return !(a0 > b1 || b0 > a1); 
} 
+0

당신도 당신의'axisOverlap()'기능을 게시 할 수 있습니까? – techfoobar

+0

vy의 방향을 바꾸지 않고 이것을 시도해 주시겠습니까? –

+0

@Asad 예, 불행히도 결과가 변경되지 않았습니다. – SpaceFace

답변

6

알아 냈습니다.

필자는 종이에 숫자 줄을 그리기 시작했고 축이 올바르게 계산되지 않았다는 것을 알게되었습니다. 수직 벡터를 계산하려면 x와 y 좌표를으로 바꾼 다음 THEN을 반전시켜야합니다. 좌표를 바꾸는 것을 완전히 잊었습니다.

새로운 코드

var vx = vertsay[ i ] - vertsay[ j ]; 
var vy = -(vertsax[ i ] - vertsax[ j ]); 
+0

질문을 해결했다면 답을 _the_ 답으로 표시하십시오! –

+3

@ A.Webb 2 일 동안 사용할 수 없습니다. – SpaceFace