我正在尝试解决一个问题,即在可以任意旋转和平移的空间内存在的盒子内找不到点的相对偏移量。
我知道盒子的 WorldSpace 位置(及其 4 个角,图像上的坐标是相对的)及其旋转。这些可以是任意的(它实际上是游戏中的 3D 触发体积,但我们只关心它在自上而下的 2D 平面中)。
看着它与轴对齐,红点相对位置将是
0.25, 0.25
如果要任意旋转盒子,我似乎无法弄清楚如何保持这一点,因为我们对同一点进行采样(它的世界位置将发生变化),即使盒子的世界旋转已经改变,它的相对位置也不会改变。
作为参考,红点表示存在于 Box 所包含的场景中的对象。
bool UPGMapWidget::GetMapMarkerRelativePosition(UPGMapMarkerComponent* MapMarker, FVector2D& OutPosition)
{
bool bResult = false;
if (MapMarker)
{
const FVector MapMarkerLocation = MapMarker->GetOwner()->GetActorLocation();
float RelativeX = FMath::GetMappedRangeValueClamped(
-FVector2D(FMath::Min(GetMapVolume()->GetCornerTopLeftLocation().X, GetMapVolume()->GetCornerBottomRightLocation().X), FMath::Max(GetMapVolume()->GetCornerTopLeftLocation().X, GetMapVolume()->GetCornerBottomRightLocation().X)),
FVector2D(0.f, 1.f),
MapMarkerLocation.X
);
float RelativeY = FMath::GetMappedRangeValueClamped(
-FVector2D(FMath::Min(GetMapVolume()->GetCornerTopLeftLocation().Y, GetMapVolume()->GetCornerBottomRightLocation().Y), FMath::Max(GetMapVolume()->GetCornerTopLeftLocation().Y, GetMapVolume()->GetCornerBottomRightLocation().Y)),
FVector2D(0.f, 1.f),
MapMarkerLocation.Y
);
OutPosition.X = FMath::Abs(RelativeX);
OutPosition.Y = FMath::Abs(RelativeY);
bResult = true;
}
return bResult;
}
目前,您可以通过上面的代码看到我只使用 Box 的左上角和右下角来尝试计算偏移量,我知道这不是一个足够的解决方案,因为这样做不允许旋转(Id 需要也使用其他两个角)但是我一生都无法弄清楚我需要做什么才能达到解决方案。
FMath::GetMappedRangeValueClamped
这会将一个范围转换为另一个范围。例如,(20 - 50) 变为 (0 - 1)。
任何有关如何解决此问题的帮助/建议将不胜感激。
谢谢。
更新
@Voo 的评论帮助我意识到解决方案比预期的要简单得多。
通过知道框的 3 个角的位置,我能够找到这 3 个位置创建的 2 条线上的点,然后简单地将这些点映射到 0-1 范围内,无论框如何被翻译。
bool UPGMapWidget::GetMapMarkerRelativePosition(UPGMapMarkerComponent* MapMarker, FVector2D& OutPosition)
{
bool bResult = false;
if (MapMarker && GetMapVolume())
{
const FVector MapMarkerLocation = MapMarker->GetOwner()->GetActorLocation();
const FVector TopLeftLocation = GetMapVolume()->GetCornerTopLeftLocation();
const FVector TopRightLocation = GetMapVolume()->GetCornerTopRightLocation();
const FVector BottomLeftLocation = GetMapVolume()->GetCornerBottomLeftLocation();
FVector XPlane = FMath::ClosestPointOnLine(TopLeftLocation, TopRightLocation, MapMarkerLocation);
FVector YPlane = FMath::ClosestPointOnLine(TopLeftLocation, BottomLeftLocation, MapMarkerLocation);
// Convert the X axis into a 0-1 range.
float RelativeX = FMath::GetMappedRangeValueUnclamped(
FVector2D(GetMapVolume()->GetCornerTopLeftLocation().X, GetMapVolume()->GetCornerTopRightLocation().X),
FVector2D(0.f, 1.f),
XPlane.X
);
// Convert the Y axis into a 0-1 range.
float RelativeY = FMath::GetMappedRangeValueUnclamped(
FVector2D(GetMapVolume()->GetCornerTopLeftLocation().Y, GetMapVolume()->GetCornerBottomLeftLocation().Y),
FVector2D(0.f, 1.f),
YPlane.Y
);
OutPosition.X = RelativeX;
OutPosition.Y = RelativeY;
bResult = true;
}
return bResult;
}
上面的代码是原始问题的修改代码,具有正确的解决方案。