충돌감지
2023. 6. 14. 13:33ㆍ개인공부/Direct2D
1. AABB
1
2
3
4
5
6
7
8
9
10
11
12
13
|
// AABB 충돌
else
{
Vector2 leftMin = leftPosition - leftScale * 0.5f;
Vector2 leftMax = leftPosition + leftScale * 0.5f;
Vector2 rightMin = rightPosition - rightScale * 0.5f;
Vector2 rightMax = rightPosition + rightScale * 0.5f;
if (leftMin.x <= rightMax.x && leftMax.x >= rightMin.x
&& leftMin.y <= rightMax.y && leftMax.y >= rightMin.y)
return true;
}
return false;
|
cs |
2. OBB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
// OBB 충돌처리
if (_leftBox->IsRotatable() || _rightBox->IsRotatable())
{
// 회전각도
float leftRotation = _leftBox->GetRotation();
float rightRotation = _rightBox->GetRotation();
Vector2 boxToBox = rightPosition - leftPosition;
// 각각의 가로세로 벡터를 구한다.
Vector2 leftWidth = Vector2::RotateRadian(Vector2(leftScale.x *0.5f, 0.f), Vector2::Zero, leftRotation);
Vector2 leftHeight = Vector2::RotateRadian(Vector2(0.f, leftScale.y *0.5f), Vector2::Zero, leftRotation);
Vector2 rightWidth = Vector2::RotateRadian(Vector2(rightScale.x *0.5f, 0.f), Vector2::Zero, rightRotation);
Vector2 rightHeight = Vector2::RotateRadian(Vector2(0.f, rightScale.y *0.5f), Vector2::Zero, rightRotation);
vector<Vector2> basis{ leftWidth,leftHeight,rightWidth,rightHeight };
for (int i = 0; i < 4; ++i)
{
float sum = 0.f;
Vector2 normal = basis[i].GetNormalize();
for (int j = 0; j < 4; ++j)
{
sum += abs(normal.Dot(basis[j]));
}
float distance = abs(boxToBox.Dot(normal));
if (distance >= sum)
{
return false;
}
}
return true;
|
cs |
3. 원과 원의 충돌
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
// 원과 원의 충돌
Vector2 leftPosition = _leftCircle->GetPosition();
float leftRadius = _leftCircle->GetRadius();
Vector2 rightPosition = _rightCircle->GetPosition();
float rightRaius = _rightCircle->GetRadius();
float distance = (leftPosition - rightPosition).Size();
if (distance <= rightRaius + leftRadius)
{
return true;
}
return false;
|
cs |
4. 원과 박의 충돌
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | // 박스 Vector2 boxPosition = _leftBox->GetPosition(); Vector2 boxHalfScale = _leftBox->GetScale() * 0.5f; // 원 Vector2 circlePoisiton = _rightCircle->GetPosition(); float radius = _rightCircle->GetRadius(); // 회전된 사각형과 원의 충돌 -> 역으로 원을 돌려서 계산함 if (_leftBox->IsRotatable()) { float rotation = _leftBox->GetRotation(); circlePoisiton = Vector2::RotateRadian(circlePoisiton, boxPosition, -rotation); } float minBoxX = boxPosition.x - boxHalfScale.x; float maxBoxX = boxPosition.x + boxHalfScale.x; float minBoxY = boxPosition.y - boxHalfScale.y; float maxBoxY = boxPosition.y + boxHalfScale.y; // 1. 먼저 사각형의 변들을 반지름만큼 확장해서 원의 중심좌표와 비교해서 판단 if ((minBoxX - radius <= circlePoisiton.x && maxBoxX + radius >= circlePoisiton.x && minBoxY <= circlePoisiton.y && maxBoxY >= circlePoisiton.y) || (minBoxX <= circlePoisiton.x && maxBoxX >= circlePoisiton.x && maxBoxY + radius >= circlePoisiton.y && minBoxY - radius <= circlePoisiton.y)) { return true; } // 2. 가장 가까운 사각형의 꼭지점 좌표를 계산해서 원과의 거리를 계산 Vector2 boxVertex{}; boxVertex.x = (boxPosition.x < circlePoisiton.x) ? maxBoxX : minBoxX; boxVertex.y = (boxPosition.y < circlePoisiton.y) ? maxBoxY : minBoxY; float distanceSquared = (boxVertex - circlePoisiton).SizeSquared(); if (distanceSquared <= radius*radius) { return true; } // 충돌하지 않음 return false; | cs |
'개인공부 > Direct2D' 카테고리의 다른 글
스타크래프트 기능 구현 2 (0) | 2023.07.14 |
---|---|
충돌 연산 최적화 (0) | 2023.07.12 |
스타크래프트 기능 구현 1 (0) | 2023.07.10 |
카메라 (0) | 2023.07.06 |
계층구조 설계 (0) | 2023.07.05 |