• 抛物线、导弹线轨迹计算


    抛物线轨迹计算


    不同输入情况下的抛物线有不同计算方式。为了保证飞行时间的一致,水平初速度和起点两个参数是任何情况下都需要的。


    三、示例代码

    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;
    }
    


  • 相关阅读:
    指针与数组的区别 —— 《C语言深度剖析》读书心得
    console ouput 与 重定向输出 效率对比
    First day in 阿里
    TestNG 使用入门教程
    Spring简单使用简介
    玩转Spring JUnit+mockito+powermock单元测试(使用详解)
    Spring Boot Junit 单元测试详解
    spring @Value注入map、List、Bean、static变量方式及详细使用
    单元测试Junit使用详解
    Mockito & PowerMock详解
  • 原文地址:https://www.cnblogs.com/corgi/p/5405450.html
Copyright © 2020-2023  润新知