转自:http://www.cnblogs.com/corgi/p/5405450.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; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· [AI/GPT/综述] AI Agent的设计模式综述