keywords：UE4、Linear Algebra、Plane Geometry、线性代数、解析几何

### 范围判定

``````FBox2D::IsInside(const FVector2D& TestPoint)
FBox::IsInside(const FVector& TestPoint)
FIntRect::Contains( FIntPoint P )
``````

### 角度计算

``````float AimAtAngle = FMath::RadiansToDegrees(acosf(FVector::DotProduct(PlayerDirection, MouseDirection)));
``````

``````FRotator Rot = UKismetMathLibrary::MakeRotFromX(TestVector);
float Angle = Rot.Yaw;  //(-180, 180)
``````

``````//-180到0表示 ActorA 在 ActorB 左边，0到180表示 ActorA 在 ActorB 右边
float CalculateDirecton(const AActor* ActorA, const AActor* ActorB)
{
FVector TestDire = ActorA->GetActorLocation() - ActorB->GetActorLocation();

FMatrix RotMatrix = FRotationMatrix(ActorB->GetActorRotation());
FVector ForwardVector = RotMatrix.GetScaledAxis(EAxis::X);
FVector RightVector = RotMatrix.GetScaledAxis(EAxis::Y);
FVector NormalizedVel = TestDire.GetSafeNormal2D();

// get a cos(alpha) of forward vector vs velocity
float ForwardCosAngle = FVector::DotProduct(ForwardVector, NormalizedVel);
// now get the alpha and convert to degree

// depending on where right vector is, flip it
float RightCosAngle = FVector::DotProduct(RightVector, NormalizedVel);
if (RightCosAngle < 0)
{
}

}
``````

``````void UKismetMathLibrary::GetAzimuthAndElevation(FVector InDirection, const FTransform& ReferenceFrame, float& Azimuth, float& Elevation);
``````

``````FVector FMath::GetReflectionVector(const FVector& Direction, const FVector& SurfaceNormal);
``````

``````void UKismetMathLibrary::GetSlopeDegreeAngles(const FVector& MyRightYAxis, const FVector& FloorNormal, const FVector& UpVector,
float& OutSlopePitchDegreeAngle, float& OutSlopeRollDegreeAngle);
``````

### 点坐标计算

``````FVector UKismetMathLibrary::FindClosestPointOnLine(FVector Point, FVector LineOrigin, FVector LineDirection);
``````

``````bool UKismetMathLibrary::LinePlaneIntersection(const FVector& LineStart, const FVector& LineEnd,
const FPlane& APlane, float& T, FVector& Intersection);
``````

``````FVector UKismetMathLibrary::ProjectPointOnToPlane(FVector Point, FVector PlaneBase, FVector PlaneNormal);
``````

### 向量（矢量）计算

``````/**
* Projects 2D components of vector based on Z.
*
* @return Projected version of vector based on Z.
*/
FVector Projection() const;
``````

``````FVector UKismetMathLibrary::ProjectVectorOnToPlane(FVector V, FVector PlaneNormal);

static FVector VectorPlaneProject(const FVector& V, const FVector& PlaneNormal);
``````

``````void UKismetMathLibrary::GetAxes(FRotator A, FVector& X, FVector& Y, FVector& Z);
``````

``````FVector UKismetMathLibrary::GetForwardVector(FRotator InRot);
FVector UKismetMathLibrary::GetRightVector(FRotator InRot);
FVector UKismetMathLibrary::GetUpVector(FRotator InRot);
``````

``````FVector GetVectorArrayAverage(const TArray<FVector>& Vectors);
``````

``````/**
* Given a direction vector and a surface normal, returns the vector reflected across the surface normal.
* Produces a result like shining a laser at a mirror!
*
* @param Direction Direction vector the ray is coming from.
* @param SurfaceNormal A normal of the surface the ray should be reflected on.
*
* @returns Reflected vector.
*/
static CORE_API FVector GetReflectionVector(const FVector& Direction, const FVector& SurfaceNormal);
``````

``````FMatrix RotMatrix = FRotationMatrix(ActorB->GetActorRotation());
FVector ForwardVector = RotMatrix.GetScaledAxis(EAxis::X);
FVector RightVector = RotMatrix.GetScaledAxis(EAxis::Y);
FVector TopVector = RotMatrix.GetScaledAxis(EAxis::Z);
``````

Local space (Position, Direction or rotation) to world space:

``````/**
*  Transform a position by the supplied transform.
*  For example, if T was an object's transform, this would transform a position from local space to world space.
*/
UFUNCTION(BlueprintPure, Category="Math|Transform", meta=(Keywords="location"))
static FVector UKismetMathLibrary::TransformLocation(const FTransform& T, FVector Location);

/**
*  Transform a direction vector by the supplied transform - will not change its length.
*  For example, if T was an object's transform, this would transform a direction from local space to world space.
*/
UFUNCTION(BlueprintPure, Category="Math|Transform")
static FVector UKismetMathLibrary::TransformDirection(const FTransform& T, FVector Direction);

/**
*  Transform a rotator by the supplied transform.
*  For example, if T was an object's transform, this would transform a rotation from local space to world space.
*/
UFUNCTION(BlueprintPure, Category="Math|Transform")
static FRotator UKismetMathLibrary::TransformRotation(const FTransform& T, FRotator Rotation);
``````

World space (Position, Direction or rotation) to local space:

``````/**
*  Transform a position by the inverse of the supplied transform.
*  For example, if T was an object's transform, this would transform a position from world space to local space.
*/
UFUNCTION(BlueprintPure, Category="Math|Transform", meta=(Keywords="location"))
static FVector UKismetMathLibrary::InverseTransformLocation(const FTransform& T, FVector Location);

/**
*  Transform a direction vector by the inverse of the supplied transform - will not change its length.
*  For example, if T was an object's transform, this would transform a direction from world space to local space.
*/
UFUNCTION(BlueprintPure, Category="Math|Transform")
static FVector UKismetMathLibrary::InverseTransformDirection(const FTransform& T, FVector Direction);

/**
*  Transform a rotator by the inverse of the supplied transform.
*  For example, if T was an object's transform, this would transform a rotation from world space to local space.
*/
UFUNCTION(BlueprintPure, Category="Math|Transform")
static FRotator UKismetMathLibrary::InverseTransformRotation(const FTransform& T, FRotator Rotation);
``````

### 插值相关

``````float UKismetMathLibrary::FloatSpringInterp(float Current, float Target, UPARAM(ref) FFloatSpringState& SpringState,
float Stiffness, float CriticalDampingFactor, float DeltaTime, float Mass = 1.f);
``````

``````FVector UKismetMathLibrary::VectorSpringInterp(FVector Current, FVector Target, UPARAM(ref) FVectorSpringState& SpringState, float Stiffness, float CriticalDampingFactor, float DeltaTime, float Mass = 1.f);
``````

Transform 插值计算：

``````FTransform UKismetMathLibrary::TInterpTo(const FTransform& Current, const FTransform& Target, float DeltaTime, float InterpSpeed);
``````
##### Rotation Transform

Transform rotation from World Space to Local Space:

``````FORCEINLINE FQuat FTransform::InverseTransformRotation(const FQuat& Q) const;
``````

example:

``````FRotator DestWorldRot(100.f, 100.f, 0.f);
FQuat QuatWorld = DestWorldRot.Quaternion();
FQuat QuatLocal = MyActor->GetComponentTransform().InverseTransformRotation(QuatWorld);
FRotator RotOffset = QuatLocal.Rotator();
``````

Transform rotation from Local Space to World Space:

``````FORCEINLINE FQuat FTransform::TransformRotation(const FQuat& Q) const;
``````

example:

``````FRotator DestRotOffset(100.f, 100.f, 0.f);
FRotator DestRotInWorld = FTransform(CameraRotInWorld).TransformRotation(DestRotOffset.Quaternion()).Rotator();
``````
##### Location Transform

World Space To Local Space:

``````FORCEINLINE FVector FTransform::InverseTransformPositionNoScale(const FVector &V) const;
``````

Blueprint Node:

``````InverseTransformLocation
``````

Local Space To World Space:

``````FORCEINLINE FVector FTransform::TransformPositionNoScale(const FVector& V) const;
``````

If you want only to calculate the Position Offset between two points, Rotation and Scale must be set to Zero. Otherwise the offset Vector would take account of direction. e.g. use `FTransform(Comp1->GetComponentLocation()).InverseTransformPosition(Loc2);` rather than `Comp1->GetComponentTransform().InverseTransformPosition(Loc2);`

##### Direction Transform

World To Local:

``````FORCEINLINE FVector FTransform::InverseTransformVectorNoScale(const FVector &V) const
``````

example:

``````//return the offset from Camera's World Rotation to Character's World Rotation.
FRotator ASBaseCharacter::GetAimOffsets() const
{
const FVector AimDirWS = GetBaseAimRotation().Vector();
const FVector AimDirLS = ActorToWorld().InverseTransformVectorNoScale(AimDirWS);
const FRotator AimRotLS = AimDirLS.Rotation();

return AimRotLS;
}
``````

Local To World:

``````FORCEINLINE FVector FTransform::TransformVectorNoScale(const FVector& V) const
``````

If you want to calculate the Offset only between two Rotation (take no account of Location and Scale), the simplest way is to minus:`FRotator Offset = R2 - R1;`, but the result need to be corrected, because degrees may less than -180 or larger than 180.

Bezier Cruve

``````/**
* Generates a list of sample points on a Bezier curve defined by 2 points.
*
* @param ControlPoints Array of 4 FVectors (vert1, controlpoint1, controlpoint2, vert2).
* @param NumPoints Number of samples.
* @param OutPoints Receives the output samples.
* @return The path length.
*/
static CORE_API float FVector::EvaluateBezier(const FVector* ControlPoints, int32 NumPoints, TArray<FVector>& OutPoints);
``````

Example:

``````FVector MyControlPoints[4];

// Fill out your control points.

TArray<FVector> OutPoints;
FVector::EvaluateBezier(MyControlPoints, 2, OutPoints);
``````

`无欲则刚，关心则乱。----《论语》`