Math question. finding distance to the edge of a plane in direction from center.

Removed old files, port of both solutions to c++ with fix for return values over my previous upload.

#pragma once

#include "CoreMinimal.h"
#include "Kismet/BlueprintFunctionLibrary.h"

#include "IntersectionUtils.generated.h"


class UWorld;


/**
 * 
 */
UCLASS()
class PEM_V1_API UIntersectionUtils : public UBlueprintFunctionLibrary {
	GENERATED_BODY()

public:

	UFUNCTION(BlueprintCallable, Category = "Utils|Intersection")
	static bool GetIntersectionFromBoxCenterToEdge(const FVector& InPointToTest, const FVector& InBoxExtent3D, const FTransform& InBoxTransform, FVector& OutIntersectionPoint, const UObject* const InDebugWorldContext = nullptr);

	UFUNCTION(BlueprintCallable, Category = "Utils|Intersection")
	static bool GetIntersectionFrom2DPlaneCenterToEdge(const FVector2D& InPointToTest, const FVector2D& InPlaneLocation, const FVector2D& InPlaneExtent, float InPlaneYaw, FVector2D& OutIntersectionPoint, const UObject* const InDebugWorldContext = nullptr);
	
};

#include "IntersectionUtils.h"
#include "Kismet/KismetMathLibrary.h"
#include "Engine/World.h"
#include "DrawDebugHelpers.h"


bool UIntersectionUtils::GetIntersectionFromBoxCenterToEdge(const FVector& InPointToTest, const FVector& InBoxExtent3D, const FTransform& InBoxTransform, FVector& OutIntersectionPoint, const UObject* const InDebugWorldContext) {
	const FVector CenterPoint = InBoxTransform.GetLocation();
	const UWorld* InDebugWorld = IsValid(InDebugWorldContext) ? InDebugWorldContext->GetWorld() : nullptr;
	const FVector TransformedPointToTest = InBoxTransform.Inverse().TransformVector(InPointToTest - CenterPoint) + CenterPoint;
	const bool bInBox = UKismetMathLibrary::IsPointInBox(TransformedPointToTest, CenterPoint, InBoxExtent3D);
	const bool bPersistDebug = false;
	const float DebugLifetime = -1.f;

	if (!bInBox) {
		FVector HitLocation = FVector::ZeroVector;;
		// FBox do not rotate so we rotate the CenterPoint.
		const FVector BoxSweepExtent = FVector::ZeroVector;
		const FBox Box = FBox::BuildAABB(CenterPoint, InBoxExtent3D);
		FVector HitNormal;
		float HitTime;
		// Get edge intersection.
		FMath::LineExtentBoxIntersection(Box, TransformedPointToTest, CenterPoint, BoxSweepExtent, HitLocation, HitNormal, HitTime);

		// Location on bounds with rotation.
		OutIntersectionPoint = InBoxTransform.TransformVector(HitLocation - CenterPoint) + CenterPoint;

		if (IsValid(InDebugWorld)) {
			// Hit location aligned with the FBox used for bounds.
			DrawDebugSphere(InDebugWorld, HitLocation, 30, 16, FColor::Orange, bPersistDebug, DebugLifetime, 0, 15.f);
			// Hit location projected on rotated box.
			DrawDebugSphere(InDebugWorld, OutIntersectionPoint, 30.f, 16, FColor::Red, bPersistDebug, DebugLifetime, 0, 15.f);
		}
	}

	if (IsValid(InDebugWorld)) {
		// FBox with no rotation.
		DrawDebugBox(InDebugWorld, CenterPoint, InBoxExtent3D, FColor::White, bPersistDebug, DebugLifetime, 0, 4.f);
		// Box with rotation
		DrawDebugBox(InDebugWorld, CenterPoint, InBoxExtent3D, InBoxTransform.GetRotation(), FColor::Yellow, bPersistDebug, DebugLifetime, 0, 4.f);
		// CenterPoint
		DrawDebugSphere(InDebugWorld, CenterPoint, 30.f, 16, FColor::White, bPersistDebug, DebugLifetime, 0, 30.f);
		if (bInBox) {
			// TransformedPointToTest
			DrawDebugSphere(InDebugWorld, TransformedPointToTest, 30.f, 16, FColor::Cyan, bPersistDebug, DebugLifetime, 0, 30.f);
		}
	}

	return bInBox == false;
}


bool UIntersectionUtils::GetIntersectionFrom2DPlaneCenterToEdge(const FVector2D& InPointToTest, const FVector2D& InPlaneLocation, const FVector2D& InPlaneExtent, float InPlaneYaw, FVector2D& OutIntersectionPoint, const UObject* const InDebugWorldContext) {
	const bool bPersistDebug = false;
	const float DebugLifetime = 3.f;
	const float DCosYaw = UKismetMathLibrary::DegCos(InPlaneYaw);
	const float DSinYaw = UKismetMathLibrary::DegSin(InPlaneYaw);

	// Add the location offset of the plane.
	const FVector2D MovedPointToTest = InPointToTest - InPlaneLocation;
	// Rotate to the planes rotation.
	const FVector2D TransformedPointToTest = FVector2D(
		(DCosYaw * MovedPointToTest.X) + (DSinYaw * MovedPointToTest.Y)
		, (DCosYaw * MovedPointToTest.Y) - (DSinYaw * MovedPointToTest.X)
	);
	
	// If within bounds, we dont get an intersection. Then we should return.
	if (FMath::Abs(TransformedPointToTest.X) <= InPlaneExtent.X
		&& FMath::Abs(TransformedPointToTest.Y) <= InPlaneExtent.Y
		) {
		OutIntersectionPoint = FVector2D::ZeroVector;
		return false;
	}

	const FVector2D TransformedPointWithinBounds = TransformedPointToTest / (
		// Check if inside bounds.
		FMath::Abs((TransformedPointToTest / (FMath::Abs(TransformedPointToTest.X) / InPlaneExtent.X)).Y) <= InPlaneExtent.Y
		? FMath::Abs(TransformedPointToTest.X) / InPlaneExtent.X
		: FMath::Abs(TransformedPointToTest.Y) / InPlaneExtent.Y
	);

	OutIntersectionPoint = FVector2D(
		(UKismetMathLibrary::DegCos(InPlaneYaw * -1) * TransformedPointWithinBounds.X) + (UKismetMathLibrary::DegSin(InPlaneYaw * -1) * TransformedPointWithinBounds.Y)
		, (UKismetMathLibrary::DegCos(InPlaneYaw * -1) * TransformedPointWithinBounds.Y) - (UKismetMathLibrary::DegSin(InPlaneYaw * -1) * TransformedPointWithinBounds.X)
	) + InPlaneLocation;

	const UWorld* InDebugWorld = IsValid(InDebugWorldContext) ? InDebugWorldContext->GetWorld() : nullptr;
	if (IsValid(InDebugWorld)) {
		// Line from plane center to point to test (original)
		DrawDebugLine(InDebugWorld, FVector(InPlaneLocation, 0.f), FVector(InPointToTest, 0.f), FColor::White, bPersistDebug, DebugLifetime, 0, 10.f);
		// Box with rotation
		DrawDebugBox(InDebugWorld, FVector(InPlaneLocation, 0.f), FVector(InPlaneExtent, 1.f), FRotator(0.f, InPlaneYaw, 0.f).Quaternion(), FColor::Yellow, bPersistDebug, DebugLifetime, 0, 15.f);
		// Transformed intersect point
		DrawDebugSphere(InDebugWorld, FVector(OutIntersectionPoint, 0.f), 50.f, 16, FColor::Red, bPersistDebug, DebugLifetime, 0, 20.f);
	}

	return true;
}

*Edit Fixed bug where UKismetMathLibrary::IsPointInBox did not use the transformed InPointToTest, basically causing the check to be done on the unrotated box.