[게임 수학] 벡터 정규화(Normalize Vector)

Tony Kim·2023년 2월 14일
0

게임 수학

목록 보기
1/1
post-thumbnail

단위 벡터

단위 벡터(unit vector)란 방향을 가지는 크기가 1인 벡터입니다. 그리고 어떠한 벡터를 단위 벡터로 만드는 것을 정규화(Normalization)라고 합니다.

벡터를 정규화하는 방법은 아래와 같습니다.

3차원 벡터 u 를 아래와 같이 정의하겠습니다.

이 때, 벡터 u 의 크기는 ||u|| 라고 표시합니다.

벡터 u 를 정규화하여 단위 벡터 û 로 만드는 방법은 벡터의 각 성분을 벡터의 크기로 나누는 것입니다.

û 의 크기를 거꾸로 구하면

즉, 1입니다. 단위 벡터의 크기는 1이기 때문입니다.



예시

언리얼 엔진 5.1에서 AI가 시야 각도 안에 타겟이 있는 지를 판단할 때 쓰는 함수입니다.

1	//----------------------------------------------------------------------//
2	// CheckIsTargetInSightCone
3	//                     F
4	//                   *****  
5	//              *             *
6	//          *                     *
7	//       *                           *
8	//     *                               *
9	//   *                                   * 
10	//    \                                 /
11	//     \                               /
12	//      \                             /
13	//       \             X             /
14	//        \                         /
15	//         \          ***          /
16	//          \     *    N    *     /
17	//           \ *               * /
18	//            N                 N
19	//            
20	//           
21	//           
22	//           
23	//
24	// 
25	//                     B 
26	//
27	// X = StartLocation
28	// B = Backward offset
29	// N = Near Clipping Radius (from the StartLocation adjusted by Backward offset)
30	// F = Far Clipping Radius (from the StartLocation adjusted by Backward offset)
31	//----------------------------------------------------------------------//
32	bool CheckIsTargetInSightCone(const FVector& StartLocation, const FVector& ConeDirectionNormal, float PeripheralVisionAngleCos,
33		float ConeDirectionBackwardOffset, float NearClippingRadiusSq, float const FarClippingRadiusSq, const FVector& TargetLocation)
34	{
35		const FVector BaseLocation = FMath::IsNearlyZero(ConeDirectionBackwardOffset) ? StartLocation : StartLocation - ConeDirectionNormal * ConeDirectionBackwardOffset;
36		const FVector ActorToTarget = TargetLocation - BaseLocation;
37		const FVector::FReal DistToTargetSq = ActorToTarget.SizeSquared();
38		if (DistToTargetSq <= FarClippingRadiusSq && DistToTargetSq >= NearClippingRadiusSq)
39		{
40			// Will return true if squared distance to Target is smaller than SMALL_NUMBER
41			if (DistToTargetSq < SMALL_NUMBER)
42			{
43				return true;
44			}
45			
46			// Calculate the normal here instead of calling GetUnsafeNormal as we already have the DistToTargetSq (optim)
47			const FVector DirectionToTargetNormal = ActorToTarget * FMath::InvSqrt(DistToTargetSq);
48
49			return FVector::DotProduct(DirectionToTargetNormal, ConeDirectionNormal) > PeripheralVisionAngleCos;
50		}
51
52		return false;
53	}

36번째 줄의 ActorToTarget의 단위 벡터를 구하는 과정이 보입니다.

37번째 줄의 DisToTargetSq이 ActorToTarget의 x,y,z를 각각 제곱한 후 더한 값입니다.

47번째 줄의 DirectionToTargetNormal를 잘 보시면 ActorToTarget에 DistToTargetSq의 역제곱근을 곱하여 ActorToTarget의 단위 벡터를 구하는 것을 보실 수 있습니다.

profile
게임 테크니컬 아티스트

0개의 댓글