抛物线、导弹线轨迹计算

转自:https://www.cnblogs.com/sevenyuan/p/8444109.html

算法思想

在这里插入图片描述

三、代码示例
void UParabolicMovementComponent::InitComputeParams()  
{  
//无目标时  
    if (!bHasTarget)  
    {  
//      指定出射角度时计算方法  
//      FQuat quat = UpdatedComponent->GetComponentQuat() * FQuat(Rotation);  
//      DirHorz = quat.Rotator().Vector();  
//      float Theta = DirHorz.Z / DirHorz.Size2D();  
//      VerticalSpeed = HorzSpeed * tan(Theta);  
//      DirHorz.Z = 0;  
        //指定最大高度时计算方法  
DirHorz = UpdatedComponent->GetComponentRotation().Vector();  
        DirHorz.Z = 0;  
        DirHorz.Normalize();  
//若无目标则默认G=980.0f  
        VerticalSpeed = FMath::Sqrt(2 * Gravity * MaxHeight);  
    }  
//有目标时  
    else  
    {  
        DirHorz = GetTargetPosition() - GetHostPosition();  
        float HeightDist = DirHorz.Z;  
        DirHorz.Z = 0;  
        float Dist = DirHorz.Size();  
        DirHorz.Normalize();  
        TotalTime = Dist / HorzSpeed;  
        VerticalSpeed = (2.0f * (MaxHeight + FMath::Sqrt(MaxHeight*MaxHeight - MaxHeight*HeightDist))) / TotalTime;  
        Gravity = VerticalSpeed * VerticalSpeed / (2.0f * MaxHeight);  
        //VerticalSpeed = HeightDist / TotalTime + .5f * Gravity * TotalTime;  
    }  
    CurrentTime = 0;  
    StartPos = GetHostPosition();  
    Velocity = DirHorz * HorzSpeed + FVector::UpVector * VerticalSpeed;  
    UpdateComponentVelocity();  
}  
  
//计算当前时刻所在位置  
void UParabolicMovementComponent::ComputeMovement(float DeltaTime, FVector& OutMoveDelta)  
{  
    CurrentTime += DeltaTime;  
    if(bHasTarget)  
    {  
        if (CurrentTime >= TotalTime)  
        {  
            CurrentTime = TotalTime;  
            bStop = true;  
        }  
    }  
      
    float CurrentVertSpeed = VerticalSpeed - Gravity * CurrentTime;  
    float fVertDist = .5f * (VerticalSpeed + CurrentVertSpeed) * CurrentTime;  
    OutMoveDelta = StartPos + CurrentTime * HorzSpeed * DirHorz + fVertDist * FVector::UpVector - GetHostPosition();  
    Velocity = DirHorz * HorzSpeed + FVector::UpVector * CurrentVertSpeed;  
    //OutNewRotation = Velocity.Rotation().Quaternion();  
}

导弹线轨迹计算

物体以某个初速度方向出发后,先保持稳定线性速度,以一定角速度向目标点旋转,当速度方向和自身-目标方向的夹角小于一定角度后,速度方向立刻改为自身-目标方向,进行直线加速。
在这里插入图片描述

一、示例代码
void UMissleMovementComponent::InitComputeParams()  
{  
    Dir = (UpdatedComponent->GetComponentQuat() * Rotation.Quaternion()).Rotator().Vector();  
    Dir.Normalize();  
    Velocity = Dir * StartSpeed;  
    CurrentSpeed = StartSpeed;  
    UpdateComponentVelocity();  
}  
  
void UMissleMovementComponent::ComputeMovement(float DeltaTime, FVector& OutMoveDelta)  
{  
    float MinDist = GetMinimalDistance();  
    static const float fLimit = (float)cos(FMath::DegreesToRadians(LimitDegree));  
    FVector vDir;  
    vDir = GetTargetPosition() - GetHostPosition();  
          
    float fLeft = vDir.Size();  
    vDir.Normalize();  
    float fDist = CurrentSpeed * DeltaTime;       
    if (fDist >= fLeft)  
    {  
        fDist = fLeft;  
        bStop = true;  
    }  
  
    float fAngle = Velocity.GetSafeNormal() | vDir;  
    //如果小于最小距离;或者角度相近,使用直线  
    if (fLeft < MinDist || fAngle > fLimit)  
    {  
        CurrentSpeed += LinearAcc * DeltaTime;  
        OutMoveDelta = vDir * fDist;  
        Velocity = vDir * CurrentSpeed;  
    }  
    else  
    {  
        OutMoveDelta = Velocity * DeltaTime;  
        FVector vUp = Velocity ^ vDir;  
        vUp.Normalize();  
        FQuat q(vUp, RotationSpeed * DeltaTime);  
        Velocity = q.RotateVector(Velocity);  
    }  
    //OutNewRotation = Velocity.ToOrientationQuat();  
    //OutNewRotation = Velocity.Rotation().Quaternion();  
}  
float UMissleMovementComponent::GetMinimalDistance()  
{  
    float d = 2.0f * StartSpeed / RotationSpeed;  
    return d;  
}

  • 2
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值