2013-03-08 2 views
1

로봇이 인공 지능으로 축구를하고있는 robocup에 관한 학교 프로젝트를하고 있습니다. 모든 것이 잘 작동하기 때문에 나는 여전히 무엇인가 붙어 있습니다.영향 지점 : 원형 충돌

로봇은 위에서 본 단순한 구입니다. 두 플레이어는 서로 걸어 갈 수 없으며 충격 지점에 대해 새로운 업데이트 된 자세를 취해야합니다.

충돌 처리기가 충돌 여부를 확인하기 때문에 원이 충돌하는 곳을 감지 할 수있는 방법이 있는지 알고 싶습니다. 따라서 충돌 구체의 위치를 ​​마지막으로 알려진 충돌하지 않는 위치로 업데이트하여 서로 물마루를 걸을 수 없으며 어쩌면 튀어 오를 수도 있습니다.

+0

그들은 단지 원이므로 원의 중심점 사이의 중간 점을 계산하면됩니다. 원의 반지름이 다른 경우 하나의 원을 선택하고 중심에서 반지름 1만큼 떨어진 선을 따라 점을 계산합니다. –

+1

@Chris : Chris보다 훨씬 단순합니다. 아래를보십시오. –

+1

@PieterGeerkens 나는 실제 충돌 _location_을 계산하여 충돌하지 않는지 아닌 단순히 상대적인 방향/각도를 (가능한) 유지하면서 가장 가까운 비 충돌 위치를 계산할 수있는 간단한 방법을 제안했습니다. 나는 Jesse가 요구 한 것이라고 생각했다. –

답변

0

두 개의 원 사이의 교차점을 찾는 것은 두 점, 한 점 또는 없음이 될 수 있습니다. 이것은 기본적으로 두 동그라미의 방정식을 풀어서 수행됩니다. 이 이후

http://www.analyzemath.com/CircleEq/circle_intersection.html

함께 내가

+0

도움에 감사드립니다. 코딩은 문제가되지 않습니다. 그렇게 할 공식을 찾지 못했습니다. 제가 코딩을 시작할 수 있다고 생각해주세요, 고마워요! –

2

원의 둘레에있는 모든 점은 원의 중심에서 동일한 거리, 반경입니다. 이것은 경기장의 모든 원에 해당됩니다.

따라서 센터 사이의 거리가 < = 해당 반지름의 합인 경우 두 개의 원이 정확히 충돌합니다.

+0

Jesse가 이미 충돌 한 것처럼 소리가났습니다. 충돌했을 때 _ 충돌 _이 발생했습니다. –

+0

크리스가 말하는 것. 충돌 감지는 문제가 아닙니다. 그것은 2D 환경에서 서클이 교차하는 곳을 찾아 X & Y 위치를 가져 와서 아직 충돌하지 않은 지점에 다시 놓습니다. 그래서 그들은 원의 각면에서 서로 움직이는 것을 멈 춥니 다. –

0

글쎄, 당신은 이미 답을 표시 :) 당신에게 코딩을 떠날거야,하지만 난 가서 넣어 완전히 기능 조각 학교됩니다 다음은 수학이다 어쨌든 코드를 사용하면됩니다. :) 내 댓글에서 :

그들은 단지 서클이므로 서클의 중심점 사이의 중간 점을 계산하면됩니다. 원의 반지름이 다른 경우 하나의 원을 으로 선택하고 반지름을 따라 한 점을 따라 의 중심을 계산합니다.

이것은 간단한 구현 일 수 있습니다. 아주 빈약 한 도우미 클래스를 만들었습니다. 나는 그것들을 확장하는 것을 완전히 고무 할 것이고, 구조체를 정말로 불변으로 만들고, 좋은 재즈를 만들 것이다. 그러나 지금은 데모 용으로 괜찮다. 헬퍼 클래스 그래서

는 :

private void CheckCollision(Circle circle1, Circle circle2) 
{ 
    CollisionResult result = new CollisionResult(circle1, circle2); 
    if (result.CalculateCollision()) 
    { 
     Console.WriteLine(String.Format("Collision detected at {0}! Safe location for circle 1: {1}, circle 2: {2}", result.CollisionLocation, result.Circle1SafeLocation, result.Circle2SafeLocation)); 
    } 
    else 
    { 
     Console.WriteLine("Did not collide."); 
    } 
} 

var circle1 = new Circle() {Radius = 5, Position = new Point(){X = 0, Y = 0} }; 
var circle2 = new Circle() {Radius = 5, Position = new Point(){X = 10, Y = 0} }; 
var circle3 = new Circle() {Radius = 3, Position = new Point(){X = 0, Y = 1} }; 
var circle4 = new Circle() {Radius = 5, Position = new Point(){X = 3, Y = 7} }; 

CheckCollision(circle1, circle2); 
CheckCollision(circle3, circle4); 

출력 :

public class CollisionResult 
{ 
    public Circle Circle1 { get; private set; } 
    public Circle Circle2 { get; private set; } 

    public Point Circle1SafeLocation { get; private set; } 
    public Point Circle2SafeLocation { get; private set; } 

    public Point CollisionLocation { get; private set; } 

    public CollisionResult(Circle circle1, Circle circle2) 
    { 
     this.Circle1 = circle1; 
     this.Circle2 = circle2; 
    } 

    public bool CalculateCollision() 
    { 
     double distanceFromCentres = Circle1.Position.Distance(Circle2.Position); 
     if (distanceFromCentres >= Circle1.Radius + Circle2.Radius) 
      return false; 

     double angleBetweenCircles = System.Math.Atan2(Circle2.Position.Y - Circle1.Position.Y, Circle2.Position.X - Circle1.Position.X); 

     Point midpointBetweenCircles = new Point(){X = (Circle1.Position.X + Circle2.Position.X)/2, Y = (Circle1.Position.Y + Circle2.Position.Y)/2}; 

     Point circle1Offset = (new Polar() { Radius = Circle1.Radius, Angle = System.Math.PI + angleBetweenCircles }).ToCartesian(); 
     Point circle2Offset = (new Polar() { Radius = Circle2.Radius, Angle = angleBetweenCircles }).ToCartesian(); 

     CollisionLocation = midpointBetweenCircles; 
     Circle1SafeLocation = new Point(){X = midpointBetweenCircles.X + circle1Offset.X, Y = midpointBetweenCircles.Y + circle1Offset.Y }; 
     Circle2SafeLocation = new Point(){X = midpointBetweenCircles.X + circle2Offset.X, Y = midpointBetweenCircles.Y + circle2Offset.Y }; 

     return true; 
    } 
} 

사용법과 같습니다

public struct Point 
{ 
    public double X; 
    public double Y; 

    public double Distance(Point otherPoint) 
    { 
     double deltaX = this.X - otherPoint.X; 
     double deltaY = this.Y - otherPoint.Y; 
     return System.Math.Sqrt(deltaX * deltaX + deltaY * deltaY); 
    } 

    public override string ToString() 
    { 
     return String.Format("({0}, {1})", X, Y); 
    } 
} 

public struct Polar 
{ 
    public double Radius; 
    public double Angle; 

    public double X { get { return Radius * System.Math.Cos(Angle); } } 
    public double Y { get { return Radius * System.Math.Sin(Angle); } } 

    public Point ToCartesian() 
    { 
     return new Point() { X = X, Y = Y }; 
    } 
} 

public class Circle 
{ 
    public double Radius { get; set; } 
    public Point Position { get; set; } 
} 

우리의 고기와-감자 클래스/메소드는이입니다

Did not collide. 
Collision detected at (1.5, 4)! Safe location for circle 1: (0.158359213500125, 1.31671842700025), circle 2: (3.73606797749979, 8.47213595499958) 

2 개의 원 (두 점에서 교차하는 점) 등의 실제 교차점을 계산하는 복잡성을 처리하는 것이 필요한지 잘 모르겠습니다. 이 줄을 따라 뭔가가 당신에게 충분할 것입니다. 나는 확실히 건강한 단위 테스트를 격려하고 반을 내가 여기있는 것 이상으로 만드는 것을 장려한다.:)

편집 : 중요한 것은이 경우에, 당신이 당신의 응용 프로그램을 위해 수행 할 작업에 따라 달라 이것은 원이 겹치는 경우, 단순히 다음 이동 각 원 를 그들 사이의 중간 점을 계산하는 것입니다 그 중간 지점으로부터 각각의 반경 인을 제거하십시오. 따라서 서클의 속도와 크기 또는 이동 방법에 따라 이상한 결과가 발생할 수 있습니다. 예를 들어 큰 반원 서클이 여전히 앉아 있으면 큰 원의 중심에서 0.5 개의 거리 만 반경의 원을 던져서 그 큰 원이 약 9.75 단위를 이동하게됩니다! 커다란 중첩 조건에 빠지지 않으면 그다지 문제가되지 않을 수도 있습니다. 제 생각에는 최소한 정보를에 충돌시킨 다음 님이 어떻게 반응 시킬지 궁금합니다.