bool IsSectorIntersectCircle(const UObject* WorldContextObject,const FVector& FanOrigin, const FVector& FanForward, float R,
float HalfAngleRad, const FVector& CirclePos, float r)
{
FTransform StartTransform = FTransform(FanForward.Rotation());
StartTransform.SetLocation(FanOrigin);
//绘制扇形
DrawSector(WorldContextObject,StartTransform,R,FMath::RadiansToDegrees(HalfAngleRad*2));
//绘制大圆
UKismetSystemLibrary::DrawDebugSphere(WorldContextObject,CirclePos, r, 32, FLinearColor::Yellow, 15);
const FVector Oc = CirclePos - FanOrigin;
const float d = Oc.Size();
// 1) 快速排斥:两圆不相交
if (d > R + r || d + R < r) return false;
// 2) 圆心在扇形角内?
const float CosTheta = FVector::DotProduct(FanForward, Oc) / d;
if (CosTheta >= FMath::Cos(HalfAngleRad))
{
return true;
}
//计算2条边和圆是否有交集
// 左右方向
FVector LeftDir = FanForward.RotateAngleAxis( FMath::RadiansToDegrees( HalfAngleRad), FVector::UpVector);
FVector RightDir = FanForward.RotateAngleAxis(-FMath::RadiansToDegrees( HalfAngleRad), FVector::UpVector);
FVector LeftPoint = FanOrigin + LeftDir*R;
FVector RightPoint = FanOrigin + RightDir*R;
UKismetSystemLibrary::DrawDebugPoint(WorldContextObject, LeftPoint, 25.0f, FLinearColor::Yellow, 5);
UKismetSystemLibrary::DrawDebugPoint(WorldContextObject, RightPoint, 25.0f, FLinearColor::Yellow, 5);
FVector CLoseLeftPoint = FMath::ClosestPointOnSegment(CirclePos,FanOrigin,LeftPoint);
FVector CLoseRightPoint = FMath::ClosestPointOnSegment(CirclePos,FanOrigin,RightPoint);
UKismetSystemLibrary::DrawDebugPoint(WorldContextObject, CLoseLeftPoint, 25.0f, FLinearColor::Yellow, 5);
UKismetSystemLibrary::DrawDebugPoint(WorldContextObject, CLoseRightPoint, 25.0f, FLinearColor::Yellow, 5);
UKismetSystemLibrary::DrawDebugLine(WorldContextObject, CirclePos, CLoseLeftPoint, FLinearColor::Green, 5, 2);
UKismetSystemLibrary::DrawDebugLine(WorldContextObject, CirclePos, CLoseRightPoint, FLinearColor::Green, 5, 2);
float fCLoseLeftDis = FMath::PointDistToSegment(CirclePos,FanOrigin,LeftPoint);
float fCLoseRightDis = FMath::PointDistToSegment(CirclePos,FanOrigin,RightPoint);
if (fCLoseLeftDis<= r || fCLoseRightDis <= r)
{
return true;
}
else
{
return false;
}
}
bool DrawSector(const UObject* WorldContextObject, const FTransform& StartTransform,float fRadius, float fAngle, float Segments)
{
TArray<FVector> FanPoints;
float fAngleStep = fAngle / (Segments-1);
FRotator ActorStartRotation = StartTransform.GetRotation().Rotator();
FVector ActorStartLocation = StartTransform.GetLocation();
FanPoints.Add(ActorStartLocation);
for (int32 i = 0; i < Segments; i++)
{
FRotator ActorRotation = ActorStartRotation;
ActorRotation.Yaw += (i-Segments*0.5)*fAngleStep;
FVector TempVector = ActorStartLocation + ActorRotation.Vector()*fRadius;
FanPoints.Add(TempVector);
}
FanPoints.Add(ActorStartLocation);
if (FanPoints.Num()<=3)
{
return false;
}
//绘制形状
for (int32 i = 0; i < FanPoints.Num()-1; i++)
{
FVector Start = FanPoints[i];
FVector End = FanPoints[i + 1];
UKismetSystemLibrary::DrawDebugLine(WorldContextObject, Start, End, FLinearColor::Red, 1, 2);
}
return true;
}