수업/TA

TA 4강 / 각도와 삼각함수 기초

jh009 2026. 7. 2. 10:45

도, 라디안

도: 원을 360등분한 것

1 라디안: 원의 반지름 길이와 호의 길이가 같아지는 중심각

 

프로그래밍에서는 라디안을 주로 많이 사용함

예시: FMath::Acos()는 라디안 값을 반환

사람이 읽기 쉬운 도 단위로 바꾸려면 다음 함수를 사용

float AngleDegrees = FMath::RadiansToDegrees(AngleRadians);

cos와 내적의 관계

정규화된 두 방향 벡터를 내적하면, 그 결과는 두 방향 사이 각도의 cos 값과 연결됨

각도 cos 값 Dot 의미
0도 1 완전히 같은 방향
90도 0 서로 옆 방향
180도 -1 완전히 반대 방향

내적

두 벡터가 얼마나 같은 방향을 향하고 있는지 판단하는 계산

Dot 결과 의미
1 두 방향이 완전히 같음
0 두 방향이 서로 90도
-1 두 방향이 완전히 반대
0보다 큼 대상이 앞쪽 방향에 있음
0보다 작음 대상이 뒤쪽 방향에 있음

예제

Target이 앞에 있는지 뒤에 있는지 내적으로 확인하기

if (TargetActor == nullptr)
{
    return;
}

FVector Forward = GetActorForwardVector();
FVector ToTarget = TargetActor->GetActorLocation() - GetActorLocation();
FVector DirectionToTarget = ToTarget.GetSafeNormal();

float Dot = FVector::DotProduct(Forward, DirectionToTarget);

if (Dot > 0.0f)
{
    UE_LOG(LogTemp, Log, TEXT("Target is in front"));
}
else if (Dot < 0.0f)
{
    UE_LOG(LogTemp, Log, TEXT("Target is behind"));
}
else
{
    UE_LOG(LogTemp, Log, TEXT("Target is on the side"));
}

 

캐릭터의 시야각을 내적으로 확인하기

UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "View Test")
AActor* TargetActor;

UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "View Test")
float ViewAngle = 90.0f;

void ADirectionTestActor::Tick(float DeltaTime)
{
    Super::Tick(DeltaTime);

    if (TargetActor == nullptr)
    {
        return;
    }

    FVector Forward = GetActorForwardVector();
    FVector ToTarget = TargetActor->GetActorLocation() - GetActorLocation();
    FVector DirectionToTarget = ToTarget.GetSafeNormal();

    float Dot = FVector::DotProduct(Forward, DirectionToTarget);
   
    // Clamp로 시야각을 -1.0 ~ 1.0로 막음
    Dot = FMath::Clamp(Dot, -1.0f, 1.0f);

    float AngleRadians = FMath::Acos(Dot);
    float AngleDegrees = FMath::RadiansToDegrees(AngleRadians);

    if (AngleDegrees <= ViewAngle * 0.5f)
    {
        UE_LOG(LogTemp, Log, TEXT("Target is inside view angle. Angle: %f"), AngleDegrees);
    }
    else
    {
        UE_LOG(LogTemp, Log, TEXT("Target is outside view angle. Angle: %f"), AngleDegrees);
    }
}

외적

두 벡터에 수직인 방향을 구하는 계산


Normal Vector와 표면 방향 판정

 

예시 코드

FVector HitNormal = HitResult.ImpactNormal;
// 두 단위 벡터를 내적하여 cos(theta) 값을 구함
float UpDot = FVector::DotProduct(HitNormal, FVector::UpVector);

// 기준 스펙: 걸어 올라갈 수 있는 최대 경사각 (예: 45도)
// cos(45도) 값은 약 0.707
const float WalkableFloorThreshold = FMath::Cos(FMath::DegreesToRadians(45.0f)); 

if (UpDot >= WalkableFloorThreshold)
{
    // UpDot이 0.707에서 1.0 사이면 '바닥'으로 판단
    UE_LOG(LogTemp, Log, TEXT("결과: 바닥 (캐릭터 이동 가능)"));
}
else if (UpDot > -0.1f && UpDot < WalkableFloorThreshold)
{
    // UpDot이 0 근처면 '벽'으로 판단
    UE_LOG(LogTemp, Log, TEXT("결과: 벽 (이동 차단 또는 벽타기 가능)"));
}
else
{
    // UpDot이 음수면 '천장'
    UE_LOG(LogTemp, Log, TEXT("결과: 천장"));
}

'수업 > TA' 카테고리의 다른 글

TA 6강 / 디자인 기초 1, 2  (0) 2026.07.10
TA 5강 / 기초 물리  (0) 2026.07.02
TA 3강 / 좌표계, Transform, 이동, 회전, 스케일  (0) 2026.06.25
TA 2강 / Vector  (0) 2026.06.19
TA 1강 / TA이해하기  (0) 2026.06.11