Stack Overflow 커뮤니티의 도움으로 저는 꽤 기본적이지만 재미있는 물리 시뮬레이터를 작성했습니다.
마우스를 클릭하고 끌어 공을 시작합니다. 튀어 나와 결국 "바닥"에서 멈 춥니 다.
내가 추가하고 싶은 다음 큰 기능은 볼 투 볼 충돌입니다. 공의 움직임은 도끼와 y 속도 벡터로 나뉩니다. 중력 (각 단계마다 y 벡터의 작은 감소)이 있고 마찰이 있습니다 (벽과 충돌 할 때마다 두 벡터의 작은 감소). 공은 놀랍도록 사실적으로 움직입니다.
내 질문에는 두 부분이 있다고 생각합니다.
- 공 대 공 충돌을 감지하는 가장 좋은 방법은 무엇입니까?
각 볼을 반복하고 다른 모든 볼을 검사하여 반경이 겹치는 지 확인하는 O (n ^ 2) 루프가 있습니까? - 공 대 공 충돌을 처리하기 위해 어떤 방정식을 사용합니까? 물리학 101
두 개의 볼 속도 x / y 벡터에 어떤 영향을 미칩니 까? 두 개의 볼이 향하는 방향은 무엇입니까? 이것을 각 공에 어떻게 적용합니까?
"벽"의 충돌 탐지 및 결과적인 벡터 변경을 처리하는 것은 쉽지만 볼-볼 충돌과 관련된 더 많은 합병증을 볼 수 있습니다. 벽을 사용하면 적절한 x 또는 y 벡터의 음수를 가져와야 올바른 방향으로 이동합니다. 공으로 나는 그것이 그렇게 생각하지 않습니다.
몇 가지 빠른 설명 : 단순성을 위해 지금은 완벽하게 탄력있는 충돌로 괜찮습니다. 또한 모든 볼은 동일한 질량을 갖지만 앞으로는 변경할 수 있습니다.
편집 : 내가 찾은 자료
벡터가 포함 된 2D 볼 물리학 : Trigonometry가없는 2 차원 충돌 .pdf
2d 볼 충돌 감지 예 : 충돌 감지 추가
성공!
볼 충돌 감지 및 응답이 훌륭하게 작동합니다!
관련 코드 :
충돌 감지 :
for (int i = 0; i < ballCount; i++)
{
for (int j = i + 1; j < ballCount; j++)
{
if (balls[i].colliding(balls[j]))
{
balls[i].resolveCollision(balls[j]);
}
}
}
이것은 모든 공 사이의 충돌을 검사하지만 중복 검사를 건너 뜁니다 (공 1이 공 2와 충돌하는지 확인 해야하는 경우 공 2가 공 1과 충돌하는지 여부를 확인할 필요가 없습니다. 또한 자체 충돌과 충돌 검사를 건너 뜁니다. ).
그런 다음 내 볼 클래스에는 colliding () 및 resolveCollision () 메서드가 있습니다.
public boolean colliding(Ball ball)
{
float xd = position.getX() - ball.position.getX();
float yd = position.getY() - ball.position.getY();
float sumRadius = getRadius() + ball.getRadius();
float sqrRadius = sumRadius * sumRadius;
float distSqr = (xd * xd) + (yd * yd);
if (distSqr <= sqrRadius)
{
return true;
}
return false;
}
public void resolveCollision(Ball ball)
{
// get the mtd
Vector2d delta = (position.subtract(ball.position));
float d = delta.getLength();
// minimum translation distance to push balls apart after intersecting
Vector2d mtd = delta.multiply(((getRadius() + ball.getRadius())-d)/d);
// resolve intersection --
// inverse mass quantities
float im1 = 1 / getMass();
float im2 = 1 / ball.getMass();
// push-pull them apart based off their mass
position = position.add(mtd.multiply(im1 / (im1 + im2)));
ball.position = ball.position.subtract(mtd.multiply(im2 / (im1 + im2)));
// impact speed
Vector2d v = (this.velocity.subtract(ball.velocity));
float vn = v.dot(mtd.normalize());
// sphere intersecting but moving away from each other already
if (vn > 0.0f) return;
// collision impulse
float i = (-(1.0f + Constants.restitution) * vn) / (im1 + im2);
Vector2d impulse = mtd.normalize().multiply(i);
// change in momentum
this.velocity = this.velocity.add(impulse.multiply(im1));
ball.velocity = ball.velocity.subtract(impulse.multiply(im2));
}
소스 코드 : ball to ball collider의 완전한 소스.
누군가이 기본 물리 시뮬레이터를 개선하는 방법에 대한 제안 사항이 있으면 알려주십시오! 아직 추가하지 않은 한 가지는 각도 운동량이므로 볼이 더 사실적으로 굴립니다. 다른 제안? 코멘트를 남겨주세요!
Vector2d impulse = mtd.multiply(i);
은 i * 정규화 된 mtd 벡터 여야합니다. 뭔가 같은 :Vector2d impulse = mtd.normalize().multiply(i);