posted by 나무꾼! 2011. 1. 16. 23:49

유도탄 구현 결과

 

 

계산 공식

 

 

구현 과정

 

MyPosition 위치에 있는 유도탄이 Direction 방향으로 발사됩니다.

유도탄은 Target Position 을 추적하게 됩니다.

 

My Position 에서 Target Position 으로의 방향 벡터를 얻습니다.

Target  = Target Position - My Position

 

Target 벡터와 Direction 벡터를 Cross Product를 해서

Axis 를 얻습니다.

 

Axis 축으로 Direction 벡터를 Theta 만큼 회전하면

Target방향으로 회전된 Homing 벡터를 얻을 수 있습니다.

Homing 벡터를 유도탄의 새로운 방향으로 설정합니다.

 

위 연산을 일정 시간마다 반복하면 됩니다.

 

 

추적 성능의 조절

 Theta의 크기가 크면 클수록 미사일의 추적 성능이 좋게 됩니다.

 TargetPosition 대신 타겟의 예상 이동 지점을 사용해도 추적 성능이 좋아 집니다

Target 벡터와 Direction 벡터 사이의 각이 커지면 타겟을 잃어버리게 하기도 합니다..

 

샘플 소스 코드

 void MissileController::UpdatePositionAndOrientation(float fTime)
{     
 float fDeltaTime = NiAbs(fTime - m_fLastUpdateTime);
 m_fLastUpdateTime = fTime;

 if (fDeltaTime > 1.0f)
    {  
        return;
    }
 
 NiPoint3 kTrans, kTargetVector, kTargetTrans;
 kTrans = m_pkMissileNode->GetTranslate();
 NiMatrix3 kTargetRot;

 NiMatrix3 kRotation = m_pkMissileNode->GetRotate();
 NiPoint3 kHeading;
 kHeading = kRotation * NiPoint3(0.f, -1.f, 0.f);   
 kHeading.Unitize();

 if(m_pkTargetObject)
 {
  kTargetTrans = m_pkTargetObject->GetWorldTranslate();
  kTargetVector = kTargetTrans - kTrans;
  
  if(kTargetVector.Dot(kHeading) > 0.f)
  {  
   float fTheta = 0.2f * fDeltaTime;
   NiPoint3 kAxis = kTargetVector.Cross(kHeading);
   kAxis.Unitize();
   NiMatrix3 kChangeRot;
   kChangeRot.MakeRotation(fTheta, kAxis);

   kRotation = kChangeRot * kRotation;
   m_pkMissileNode->SetRotate(kRotation);
   kHeading = kRotation * NiPoint3(0.f, -1.f, 0.f);
   kHeading.Unitize();
  }
 }

    kHeading = MISSILE_SPEED * fDeltaTime * kHeading;
    m_pkMissileNode->SetTranslate(kHeading + kTrans);
}