Intersect ray Math Function
1. 함수 소개 : Projection Vector
: Vector3 CMath.ProjectionVector(Vector3 v3DirVelocity, Vector3 v3DirNormal)
.개요: 일반적으로 다 알고 있는 투영벡터이지만 어떻게 활용하는지에 따라 그 유용성을 재 확인
.어떻게 활용 : Gizmo, UnitWalking
.함수 위치 : MATH.ProjectionVector
.수식 : Position Projection = PosObj + (DirN(Normalized) * Dot(DirN, DirDistanceA))
.유의점 : Normalize연산
참고1.
//@ Projection vector Src to Dst, return Vector has Dir & Distance.
public static void ProjectionVector(
Vector3 v3DirDistance,
Vector3 v3DirProjectionBase,
out Vector3 v3DirDistancePrj)
{
v3DirDistancePrj = v3DirProjectionBase * Vector3.Dot(v3DirDistance, v3DirProjectionBase);
}
참고2. 일반적으로 Sliding vector로 불리우는 공식 또한 Projection Vector와 동일
2. 함수 소개 : Ray-Plane Intersect
: public static bool IntersectRayPlane( Vector3 v3PosRay,
Vector3 v3DirRay,
float fDistanceRay,
Vector3 v3PosPlane,
Vector3 v3DirNormalPlane,
ref Vector3 v3PosIntersected)
.개요: Ray-Plane 충돌점은 비슷한 함수가 Engine내 제공되나 공간자료구조검색 + 면충돌 여부판별+충돌점계산 연산으로
면충돌 여부판별과 충돌점 계산을 완료.
.어떻게 활용 : 추후 UnitWalking에 활용 예정
.함수 위치 : MATH. IntersectRayPlane
.수식 :
Ray => PosRay + (distance)DirRay;
Plane => -Dot(PosPlane,DirPlane) = d
PosPlane에 PositionRay 대입 => Dot((PosRay+( distance)DirDistanceRay), DirPlane) + d = 0
.유의점 : 함수는 꼭지점을 가진 면 내부 충돌 여부 판정이 아님.
참고3.
참고4.
//@ Ray-Plane Intersect
public static bool IntersectRayPlane( Vector3 v3PosRay,
Vector3 v3DirRay,
Vector3 v3PosPlane,
Vector3 v3DirNormalPlane,
ref Vector3 v3PosIntersected)
{
float fD = -Vector3.Dot(v3PosPlane, v3DirNormalPlane);
float fVdotN = Vector3.Dot(v3DirRay,v3DirNormalPlane);
if(0==fVdotN)
{
return false;
}
float fSDotN = Vector3.Dot(v3PosRay, v3DirNormalPlane);
float fT = -(fSDotN + fD) / fVdotN;
if (0 == fT)
{
return false;
}
v3PosIntersected = v3PosRay + (v3DirRay * fT);
return true;
} // public static bool IntersectRayPlane
3. 함수 소개 : 2D Line cross
:
bool doesLineCross2D_est_test( Vector3 v3Pos01_start,
Vector3 v3Pos01_end,
Vector3 v3Pos02_start,
Vector3 v3Pos02_end )
.개요 : Navigation mesh3D상에 가시성 검사 같은 무수히 많은 Intersect ray검사는 과연산량으로 이에 대한 방안으로
2D Line cross를 이용한 유닛이 특정 위치점에 갈 수 있는지 여부 판단.
.어떻게 활용 : 가시성을 고려한 최단거리 유닛 이동처리.
.함수 위치 : CMath.doesLineCross2D_est_test
.유의점 : Navigation mesh가 복층 같이 겹친곳에서 연산 중복
참고5.
public bool DoesCrossEdge2D(Vector3 v3Pnt0_, Vector3 v3Pnt1_)
{
Vector2 v2Pnt0_ = new Vector2(v3Pnt0_.x, v3Pnt0_.z);
Vector2 v2Pnt1_ = new Vector2(v3Pnt1_.x, v3Pnt1_.z);
return CMATH.doesLineCross2D_est_test(_v2Pnt0, _v2Pnt1, v2Pnt0_, v2Pnt1_);
}
public static bool doesLineCross2D_est_test(Vector2 v2Pos0_start,
Vector2 v2Pos0_end,
Vector2 v2Pos1_start,
Vector2 v2Pos1_end)
{
// Denominator for ua and ub are the same, so store this calculation
float d =
(v2Pos1_end.y - v2Pos1_start.y) * (v2Pos0_end.x - v2Pos0_start.x)
-
(v2Pos1_end.x - v2Pos1_start.x) * (v2Pos0_end.y - v2Pos0_start.y);
//n_a and n_b are calculated as seperate values for readability
float n_a =
(v2Pos1_end.x - v2Pos1_start.x) * (v2Pos0_start.y - v2Pos1_start.y)
-
(v2Pos1_end.y - v2Pos1_start.y) * (v2Pos0_start.x - v2Pos1_start.x);
float n_b =
(v2Pos0_end.x - v2Pos0_start.x) * (v2Pos0_start.y - v2Pos1_start.y)
-
(v2Pos0_end.y - v2Pos0_start.y) * (v2Pos0_start.x - v2Pos1_start.x);
// Make sure there is not a division by zero - this also indicates that
// the lines are parallel.
// If n_a and n_b were both equal to zero the lines would be on top of each
// other (coincidental). This check is not done because it is not
// necessary for this implementation (the parallel check accounts for this).
if (d == 0)
return false;
// Calculate the intermediate fractional point that the lines potentially intersect.
float ua = n_a / d;
float ub = n_b / d;
// The fractional point will be between 0 and 1 inclusive if the lines
// intersect. If the fractional calculation is larger than 1 or smaller
// than 0 the lines would need to be longer to intersect.
if (ua >= 0d && ua <= 1d && ub >= 0d && ub <= 1d)
{
return true;
}
return false;
} // public static bool doesCrossLineEst_test