圆周运动
贝塞尔曲线路径运动
蓝图函数库创建贝塞尔曲线点
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "MyBlueprintFunctionLibrary.generated.h"
/**
*
*/
UCLASS()
class CARTEST_API UMyBlueprintFunctionLibrary : public UBlueprintFunctionLibrary
{
GENERATED_BODY()
public:
UFUNCTION(BlueprintCallable, Category = "BezierCurve")
static TArray<FVector> GenerateBezierCurvePoints(const FVector& P0, const FVector& P1, const FVector& P2, int32 NumPoints);
};
// Fill out your copyright notice in the Description page of Project Settings.
#include "MyBlueprintFunctionLibrary.h"
TArray<FVector> UMyBlueprintFunctionLibrary::GenerateBezierCurvePoints(const FVector& P0, const FVector& P1,
const FVector& P2, int32 NumPoints)
{
TArray<FVector> CurvePoints;
// 确保 NumPoints 大于 1,否则没有足够的点来生成曲线
if (NumPoints < 2)
{
UE_LOG(LogTemp, Warning, TEXT("NumPoints 必须大于 1"));
return CurvePoints;
}
// 创建临时点数组用于曲线生成
TArray<FVector> TempPoints;
for (int32 i = 0; i < NumPoints; i++)
{
float t = static_cast<float>(i) / (NumPoints - 1);
FVector Point = FMath::Lerp(FMath::Lerp(P0, P1, t), FMath::Lerp(P1, P2, t), t);
TempPoints.Add(Point);
}
// 计算曲线总长度和各段长度
float TotalLength = 0.0f;
TArray<float> SegmentLengths;
for (int32 i = 1; i < TempPoints.Num(); i++)
{
float SegmentLength = FVector::Dist(TempPoints[i - 1], TempPoints[i]);
SegmentLengths.Add(SegmentLength);
TotalLength += SegmentLength;
}
// 防止 TotalLength 为 0
if (TotalLength <= KINDA_SMALL_NUMBER)
{
UE_LOG(LogTemp, Warning, TEXT("曲线总长度为 0"));
CurvePoints.Add(P0); // 添加起点
CurvePoints.Add(P2); // 添加终点
return CurvePoints;
}
// 计算等距点
CurvePoints.Add(P0); // 起点
float SegmentTarget = TotalLength / (NumPoints - 1);
float DistanceAccumulated = 0.0f;
for (int32 i = 1; i < TempPoints.Num(); i++)
{
DistanceAccumulated += SegmentLengths[i - 1];
while (DistanceAccumulated >= SegmentTarget)
{
float LerpAlpha = (SegmentTarget - (DistanceAccumulated - SegmentLengths[i - 1])) / SegmentLengths[i - 1];
FVector Point = FMath::Lerp(TempPoints[i - 1], TempPoints[i], LerpAlpha);
CurvePoints.Add(Point);
DistanceAccumulated -= SegmentTarget;
}
}
CurvePoints.Add(P2); // 终点
return CurvePoints;
}