DirectX Texture Tool 이용 CubeMap 제작

 

 

DirectX에서 제공하는 Texture Tool을 이용하면 SkyBox를 만들기 위한 .dds(Direct Draw Surface)포맷의 파일을 쉽게 만들 수 있다. 

 

 

 

◎ 큐브맵이란? 

큐브맵은 환경에 대한 반사를 나타내는 여섯 개의 사각형 텍스쳐 컬렉션을 말한다. 여섯 개의 사각형은 오브젝트를 둘러싸는 가상 큐브면을 형성하며 각각의 면은 월드 축의 방향을 따른 뷰를 나타낸다. (위,아래, 좌,우, 앞, 뒤)

 

출처 ; Unity Document > 그래픽스 > 렌더링 컴포넌트 > 큐브맵 

 

 

 

 

◎ Direct Texture Tool은 어디에 있는가!? 

 

C드라이브의 Program Files(x86)에 들어가보면 Microsoft DirectX SDK 폴더가 있고 

그 안에 Utilities\bin\x86(혹은 x64)를 열어보면 DxTex.exe 파일이 있다.

 

 

 

만약 이 폴더의 존재를 찾아볼 수 없다면? 깔아야 한다. 

 

 

https://www.microsoft.com/en-us/download/details.aspx?id=6812

 

DirectX SDK - (June 2010)

Download the complete DirectX SDK, which contains the DirectX Runtime and all DirectX software required to create DirectX compliant applications.

www.microsoft.com

이곳에 들어가서 DownLoad를 눌러서 설치하면 된다. 

 

 

 

 

◎ 큐브맵 만들기 

 

 

이제 큐브맵을 만들 수 있다!

 

 

파일에서 New Texture를 누르면 이제 생성할 수 있는데 가로, 세로, 그리고 밉맵 레벨을 설정해 주고 확인을 누른다. 

 

그러면 View->CubeMapFace에서 +x, -x, +y, -y, +z, -z 이렇게 6개의 축을 선택할 수 있다.

각각의 축을 선택해서 이제 하나씩 채워줄 것이다.

 

 

CubeMapFace를 지금 +X 축으로 설정해 놨으니 Open Onto This Cubemap Face를 눌러 해당 축에 맞는 이미지를 찾아서 넣어준다.

여섯 면을 다 채워줬으면 .dds 포맷으로 Save를 해준다. 그러면 완성이다. 

 

 

 

 

 

 

 

참고 자료;

 

https://docs.unity3d.com/kr/2018.4/Manual/class-Cubemap.html

 

큐브맵 - Unity 매뉴얼

큐브맵(Cubemap) 은 환경에 대한 반사를 나타내는 여섯 개의 사각형 텍스처 컬렉션입니다. 여섯 개의 사각형은 오브젝트를 둘러싸는 가상 큐브면을 형성합니다. 각각의 면은 월드 축의 방향을 따��

docs.unity3d.com

 

 

요즘 Direct를 공부해서 거의 반년만에 유니티를 처음 켜봤더니 어떻게 쓰는지 까먹을 것 같아서 뭐라도 하기로 했다.

내 입맛에 맞는 공부 시간 측정 타이머가 필요하기도 했고 쉽게 만들고 싶으면서도 유니티 내용을 기본부터 포스팅하고 싶어서 타이머로 결정하게 되었다.  


 

타이머의 크기는 300x500 정도가 적당할 것 같아서 300x500으로 결정했다.

 

기본 화면에 300x500 사이즈에 맞는 Image(흰색)를 깔아놓은 상태

 

더보기

Text UI 추가 방법

Hierarchy 창에서 오른쪽 클릭 후 UI->Text를 추가하면 Canvas안에 text가 생성 된다. 

 

우선 기본적으로 Text를 추가해서 다음과 같이 설정해두었다. 

시, 분, 초로 Text를 나누고 다운받아놨던 글씨체도 추가해두었다. 

 

 

이제 기본 세팅을 끝냈으니 버튼을 누르면 시간을 계산하는 기능을 추가할 것이다.

버튼은 Text를 추가하는 방법과 동일하게 Hierarchy 창을 오른쪽 클릭해서 UI->Button을 눌러 생성하거나 상단바의 GameObject->UI->Button으로 추가해도 된다.

 

 

 

 

버튼을 추가하면 위와 같은 기본 버튼이 하나 생성된다. 개인적으로 유니티는 UI 중 버튼이 너무 유용하다는 생각을 했었다. 사용방법이 무궁무진하기 때문이다. 

 

 

그 이유는 위 사진을 보면 알 수 있는데 가장 기본적인 사용방법으로는 마우스가 버튼 위에 있는지 아닌지에 따라서 Color도 쉽게 바꿀 수 있고 Color Tint를 Sprite Swap으로 바꾸면 버튼의 이미지를 바꿀 수도 있고 Animation으로 설정하면 Animation 효과도 넣을 수 있기 때문이다. 참 좋은 기능이다.

 

 

이제 Button 기능과 Script를 연결해야 한다.

우선 Script를 하나 만들어서 함수를 만들어준다. 나중에 추가할 기능들을 위해서 시간을 Manager로 관리해주긴 할 거지만 버튼이 눌렸는지 확인하는 '버튼'용 스크립트를 만든다. 들어가야 하는 기능은 Button을 누르면 Start가 되고 한 번 더 누르면 Stop(멈춤) 상태가 되어야 한다. 

그 스크립트를 끌어다 Button에 넣어주고 아래와 같은 함수를 추가해준다.

 

bool ButtonActive; // 버튼이 눌렸는지 안눌렸는지 확인하는 상태

public void ClickButton()
{
	if(!ButtonActive)
    {
    	ButtonActive = true;
    }
    else
    {
    	ButtonActive = false;
    }
}

 

 

Button의 OnClick() 은 처음에는 List is Empty 상태, 즉 비어있지만 + 를 누르게 되면 아래와 같이 변한다.

 

 

 

이렇게 바뀐 부분의 None(Object)에 hierarchy창의 해당 버튼 오브젝트를 드래그해서 넣어준다. 그러면 Function 부분을 선택할 수 있게 되고 눌러보면 아래와 같이 내가 추가한 스크립트가 나온다. 그 안에 함수의 목록들도 나오게 되는데 그 중 ClickButton()을 눌러주면 버튼의 클릭과 해당 함수가 연결 된다. 

 

 

 

버튼을 연결했으니 이제 시간초만 계산해주면 된다. 타이머 매니저를 만들기 위해 빈 오브젝트를 하나 추가해 주고 매니저용 스크립트도 하나 만들어 준다. 

 

public class TimerCountManager : MonoBehaviour
{

    bool TimerOn; // Timer가 돌아가고 있는지 

    void Start()
    {
        TimerOn = false;
    }

    void Update()
    {

    }

    public void SetTimerOn()
    {
        TimerOn = true;
    }

    public void SetTimerStop()
    {
        TimerOn = false;
    }


}

 

 

위의 스크립트는 추가한 매니저에 넣고 버튼이 눌렸을 때 Manager에 전달해 주기 위해서 Button 스크립트도 아래와 같이 수정한다.

 

 

public class TimerCtrlButton : MonoBehaviour
{
    bool ButtonActive; // 지금 숫자 세고 있는지
    public GameObject TimerManager;
    TimerCountManager Tm;

    void Start()
    {
        ButtonActive = false;
        Tm = TimerManager.GetComponent<TimerCountManager>();
    }

    void Update()
    {
        
    }

    public void ClickButton()
    {
        if(!ButtonActive)
        {
            // 시작해야 되는 부분
            Tm.SetTimerOn();
            ButtonActive = true;
        }
        else
        {
            // STop
            Tm.SetTimerStop();
            ButtonActive = false;
        }
    }
}
더보기

 혹시몰라서 설명

TimerManager를 직접 Button의 해당 스크립트로 드래그해서 가져다 놓으면 해당 오브젝트의 스크립트(위 코드의 Tm부분)를 찾아서 쓰기 위해 Start에서 처음 시작할 때 스크립트를 찾아 놓는 것이다. 

 

 

보통 Find를 많이 쓰는데 성능 저하가 심한 대표적 기능이라고 해서 안쓰게 된 이후로 간단한 것들은 Find를 안하고 직접 메타를 연결해 주고 있다. 그러니까 Hierarchy창에 있는 TimerManager를 Button에 드래그로 연결해 준다.

 

 

 

 

이렇게 하면 이제 Button을 클릭할 때 마다 Button이 눌렸다고 Manager에게 전달하게 된다. 

전달이 됐으면 이제 시간 계산이 남아있다.

 

 

시간 계산을 위해서 Text를 연결해야 한다.

Text는 time을 Manager가 가지고 있게 할 거라서 시간을 바로 계산해서 한번에 하려고 Manager에서 같이 관리하도록 할 것이다. 

 

 

Text 추가를 위해서 우선 해야 할 것이 있다. 스크립트에서 UI 관련한 부분을 사용할 것이라고 알려주기 위해

 

using UnityEngine.UI;

 

이것을 위에 추가해주어야 한다. 그래야 text를 비롯한 image, sprite 등 UI와 관련한 부분을 스크립트에서 변경할 수 있다. 

 

 

 

이것을 추가했으면 Manager에 text와 time을 추가해 준다.

   public Text[] ClockText; // Text
    float time;  // 시간 계산 

 

Text는 text component를 연결하는 형식이고 hour, minute, second 이 세 개를 배열로 관리하려고 배열 형식으로 선언해 놨다. 

 

이렇게 선언해 놨으면 이제 Manager의 해당 스크립트 부분으로 가서 0으로 되어 있는 size를 3으로 변경해 주고 0번 부터 text인 hour, minute, second 순으로 넣어준다.

 

 

 

이제 이 연결된 text로 계산만 하면 된다. 

 

Manager의 Update부분에 타이머가 눌렸으면 시간이 추가 되게 하고 추가된 시간을 기준으로 시간, 분, 초를 계산해 낸다. 

 

더보기

혹시 몰라서 시간 계산

1 시간은 3600초 이므로 time 을 3600으로 나누고

1 분은 60초 이므로 time을 60으로 나눈 몫의 값이다. 근데 1시간이 됐을 때 60이상으로 넘어가면 안되니까 60으로 한 번 더 나머지 계산을 해준다. 

1 초는 60초가 모이면 1분이 되어야 하므로 time을 60으로 나눴을 때 나머지 값이 된다. 

 

    void Update()
    {
        if (TimerOn)
        {
            time += Time.deltaTime;
            ClockText[0].text = ((int)time / 3600).ToString();
            ClockText[1].text = (((int)time / 60 % 60)).ToString();
            ClockText[2].text = ((int)time % 60).ToString();
        }
    }

 

 

이렇게 추가하고 play를 눌러보면 Button을 눌렀을 때 시간 계산이 잘 되고 있는 것을 볼 수 있다.

 

 

 

 

 

 

https://programmers.co.kr/learn/courses/30/lessons/42626

 

코딩테스트 연습 - 더 맵게

매운 것을 좋아하는 Leo는 모든 음식의 스코빌 지수를 K 이상으로 만들고 싶습니다. 모든 음식의 스코빌 지수를 K 이상으로 만들기 위해 Leo는 스코빌 지수가 가장 낮은 두 개의 음식을 아래와 같��

programmers.co.kr

 

처음에는 아무생각없이 vector sort를 이용해서 풀었다.

정확성 테스트는 통과했지만 효율성 테스트에서 빨간색 잔치가 열려서 당황했다가 이 문제가 heap 문제라는 것을 깨닫고 priority_queue를 이용해서 풀었다.

 

priority_queue를 이용하면서 뒤에 compare 조건으로 greater를 이용해 오름차순으로 정렬되게 만들었다.

그렇게 해서 top을 했을 때 작은 숫자가 나오는 것을 이용했다.

 

 

int solution(vector<int> scoville, int K)
{
	int answer = 0;
	int scoville_size = scoville.size();

	priority_queue<int, vector<int>, greater<int>> t_scoville;

	for (int i = 0; i < scoville_size ; ++i)
	{
		t_scoville.push(scoville[i]);
	}

	while (1)
	{
		if (t_scoville.empty())
			return -1;

		if (t_scoville.size() == 1)
		{ 
			// 혹시 처음 조건 자체가 어떻게 될 지 모르니까 추가해 놓은 조건

			//음식이 하나인데 그 음식의 스코빌 지수가 K보다 작으면 -1
			if (t_scoville.top() < K)
				return -1;
		}

		// 가장 안 매운것 (temp_food1)과 그 다음으로 안 매운것(temp_food2)를 뽑아 스코빌 지수를 계산한다.
		auto temp_food1 = t_scoville.top();
		t_scoville.pop();
		auto temp_food2 = t_scoville.top();
		t_scoville.pop();

		int temp_scoville = temp_food1 + (temp_food2 * 2);

		t_scoville.push(temp_scoville);

		answer += 1;

		// 정렬된 상태의 scoville 지수. 만약 top의 값이 K보다 크다면 뒤의 것들은 당연히 더 클 것이므로 break한다.
		if (t_scoville.top() > K)
			break;
	}
	return answer;
}

 

 

행렬 下

행렬식, 역행렬, 딸림행렬

 

 

 

 

◎ 행렬식

행렬식(=determinant)는 정사각행렬에 수를 대응시키는 하나의 함수이다. 이 행렬식은 정사각행렬에서만 정의되는 값으로 행렬의 역행렬 존재여부를 결정한다.

 

따라서 이 행렬식의 명제,

"정방행렬 A는 오직 det A 가 0이 아닐 때에만 역행렬이 존재한다"

를 이용하면 주어진 행렬의 역을 구할 수 있는지 없는지를 쉽게 판단할 수 있다.

 

 

 

정사각행렬(=정방행렬) A의 행렬식을 흔히 detA라고 표기한다.

A가 2x2의 정방행렬이라고 가정했을 때 역행렬을 표현하는 방법은 다음과 같다. 

 

 

행렬식을 구하는 방법은 2x2일 때는 굉장히 간단하다.

detA = a*d - b*c를 구하면 된다. 

그런데 행렬은 2x2만 있는 것이 아니다. 그 이상의 행렬의 행렬식은 어떻게 구할까?

 

한 행렬의 행렬식은 재귀적으로 정의된다. 

예를 들어 4x4 행렬의 행렬식은 3x3 행렬의 행렬식을 항으로 해 정의되고 3x3 행렬의 행렬식은 2x2 행렬의 행렬식으로, 2x2는 1x1 행렬의 행렬식으로 정의된다. 이 2x2 행렬의 1x1 행렬식이 바로 위의 ad-bc인 것이다. 

 

그러면 A가 nxn 행렬이라고 할 때, n > 1 에 대해 A의 행렬식은 다음과 같이 정의된다.

3x3행렬의 소행렬 정의를 이용하면 3x3 행렬의 행렬식의 정의는 아래와 같다.

소행렬?

더보기

n x n 행렬 A가 주어졌을 때, 그 소행렬은 A의 i번째 행과 j번째 열을 삭제한 결과로 생긴 (n - 1) x (n - 1)행렬이다.

소행렬

 

 

 

 

 

◎ 딸림행렬

딸림행렬은 이해하기 앞서 여인수에 대한 정의가 필요하다.

여인수라는 것은 A가 n x n 행렬이라고 할 때, 아래의 C를 여인수(confactor)라고 부른다.

A의 여인수행렬이란 것은 A의 각 성분에 여인수 C를 해당 ij번째의 위치에 넣어서 만든 행렬을 뜻한다.

그리고 이 여인수행렬의 전치행렬을 A의 딸림행렬(adjoint matrix)라고 부르는 것이다.

 

 

 

 

◎ 행렬의 역

역행렬은 n차의 정방 행렬 A가 있고 단위행렬을 E라고 할 때 AX = E가 되는 n차의 정방 행렬 X를 뜻한다. 

즉 교환법칙이 성립되지 않는 행렬의 곱셈에서 A에 곱했을 때 단위행렬이 되는 특정 행렬을 말하는 것이다. 

 

행렬 대수는 나눗셈 연산은 정의하지 않지만 곱셈에 대한 역인 역행렬에 대한 정의는 존재한다. 

행렬 A에 대한 역행렬은 다음과 같이 표현한다.

 

위의 행렬식의 명제를 통해 본것 같이 모든 행렬이 역행렬을 갖는 것은 아니다. 우선 정방행렬(n x n)이어야 하며 행렬식이 0이되어서는 안된다

이처럼 역행렬이 있는 행렬을 가역행렬이라고 하고 역행렬이 없는 행렬은 특이행렬이라 부른다. 

 

역행렬을 구하는 방법은 간단하다. 

행렬의 앞에 앞서 구한 행렬식을 곱해주면 된다

 

 

 

 

 

참고 자료;

https://namu.wiki/w/%ED%96%89%EB%A0%AC%EC%8B%9D

 

행렬식 - 나무위키

우선, 열벡터 각각을 하나의 인수로 보자. 그러면 다음과 같이 생각할 수 있다. n=2n=2n=2이면 det⁡:(F2)2→F\det :\left(F^2\right)^2\rightarrow Fdet:(F2)2→F 이 관점에서 행렬식은 다중선형(multi-linear), 교대(alternating) 범함수(functional)[1]이다. 풀어쓰면 다음과 같다. 다중 선형성[2]각 열벡터 vi\mathbf v_ivi​, u∈Fn\mathbf u \in F^nu

namu.wiki

 


Direct11을 이용한 3D게임프로그래밍 (저; 프랭크 D. 루나, 역; 류광, 출판사; 한빛미디어)

 

 

 

행렬 上

행렬과 단위행렬, 전치

 

 

 

 

◎ 행렬

m x n 행렬 M은 m개의 행과 n개의 열로 이루어진 실수들의 정사각 배열이다.

행(row)들의 개수와 열(column)들의 개수를 곱한 것을 행렬의 차원이라고 부르고 행렬을 구성하는 수들을 원소(element) 도는 성분(entry)라고 부른다. 

 

A는 행이 3, 열이 3인 3x3 행렬이다.

종종 한 행렬의 행들을 벡터로 간주하는 것이 편할 때가 있다. 예를 들면 A 행렬의 A1* 는 A11, A12, A13으로 하나의 행벡터를 뜻하게 된다. 이 때 *는 하나의 행벡터 전체를 뜻하게 된다.

열벡터도 마찬가지로 A*1는 A11, A21, A31을 뜻하며 여기서의 *는 하나의 열벡터 전체를 뜻한다.

행렬의 한 성분을 지칭할 때에는 그 성분의 행과 열 번호를 이중 아래첨자(색인)로 지정하는 형태의 표기법을 사용한다.

여기서 첫 아래첨자 i가 행, 둘째 아래첨자 j가 열

 

 

 

 

 

◎ 행렬의 연산

행렬의 상등, 덧셈, 스칼라 곱셈, 뺄셈을 정의해 보면

 

1. 두 행렬은 오직 대응되는 성분들이 상등일 때에만 상등이다. 따라서, 두 행렬의 상등을 비교하려면 두 행렬의 행 수와 열 수가 동일해야 한다.

2. 두 행렬을 더할 때에는 대응되는 성분들을 더한다. 따라서 행 수와 열 수가 같은 행렬들만 덧셈이 가능하다.

3. 행렬에 하나의 스칼라를 곱할 때는 행렬의 모든 성분에 그 스칼라를 곱한다.

4. 행렬의 뺄셈은 스칼라 곱셈과 행렬 덧셈으로 정의한다. 즉, A - B = A + (-1 x B) = A + (-B)이다.

 

 

덧셈과 스칼라 곱셈이 성분별로 이루어지기 때문에 행렬의 덧셈과 스칼라 곱셈도 실수의 덧셈 및 곱셈의 다음과 같은 속성들을 만족한다.

 

A + B = B + A 덧셈의 교환법칙
( A + B ) + C = A + ( B + C ) 덧셈의 결합법칙
r ( A + B ) = rA + rB 행렬들에 대한 스칼라의 분배법칙
( r + s ) A = rA + sA 스칼라들에 대한 행렬의 분배법칙

 

 

◑ 행렬의 곱셈 

 

위에서 덧셈은 행렬의 열 수와 행 수가 동일해야 했는데 곱셈은 조금 다르다.

교환법칙이 성립하지 않는 행렬의 곱셈은 앞의 행렬의 열과 뒤에 곱할 행렬의 행의 수가 같아야 한다.

 

즉, A(앞에 곱하는 행렬)의 행벡터 차원과 B(뒤에 곱하는 행렬)의 열벡터 차원을 일치시켜야 한다. 

만일 A가 m x n 행렬이고 B가 n x p 행렬이면 둘의 곱 AB가 정의된다. 곱 AB는 하나의 m x p 행렬이 된다.

 

행렬 A와 B를 곱한 결과가 C라고 할 때 C의 ij번째 성분은 A의 i번째 행벡터와 B의 j번째 열벡터의 내적이 된다.

 

2x2 행렬과 2x3 행렬을 곱해서 2x3 행렬이 나왔다.

 

 

◑ 행렬의 전치

행렬의 전치, 즉 전치행렬 주어진 행렬의 행들과 열들을 맞바꾼 것을 말한다.

따라서 m x n 행렬의 전치는 n x m 행렬이다. 

행렬 M의 전치행렬은 다음과 같이 표기한다.

 

 

◑ 단위행렬

행렬에는 단위행렬이라고 부르는 특별한 행렬이 있다. 주대각 성분, 즉 좌상에서 우하로의 주된 대각선에 있는 성분들만 1이고 나머지는 모두 0인 정방행렬(정사각형 행렬, 즉 열 수와 행 수가 같은 행렬)이다. 

2x2와 3x3 의 단위행렬 

이 단위행렬은 곱셈의 항등원 역할을 한다.

항등원?

더보기

연산(演算)에서 임의의 원소 a에 대하여 ae=ea=a를 만족하는 원소 e를 가리키는 말. 이를테면, a+0=a, a·1=a이므로 이 때 0을 덧셈의 항등원, 1을 곱셈의 항등원이라 함. 

 

즉, 만일 A가 m x n 행렬이고 B가 n x p 행렬 그리고 I 가 n x n 행렬이면 AI = A, IB = B.

그러니까 어떤 행렬에 단위행렬을 곱해도 그 행렬은 변하지 않는다. 

곱할 행렬 M이 정방행렬이라면 단위행렬과의 곱셈은 교환법칙을 만족한다. 

 

 

 

 

 

 

 

참고 자료;

- Direct11을 이용한 3D게임프로그래밍 (저; 프랭크 D. 루나, 역; 류광, 출판사; 한빛미디어)

 

 

포물선과 원 

 

 

 

 

◎ 포물선

 

포물선은 대칭 꼴의 굴곡, 또는 호를 나타내는 용어이다.

위아래 또는 옆으로 그려질 수도 있고 어느 경우에나 좌우 대칭의 형상을 가진다. 

 

포물선의 방정식은 두 가지 형태가 있다.

 

1. 수직 대칭축을 가지는 상하로 뻗는 포물선의 방정식

 

꼭짓점의 좌표가 (h, k) 대칭축이 x = h인 포물선의 방정식

 

이와 같은 경우 포물선의 형태가 위쪽, 혹은 아래쪽으로 열려있는 형태가 된다. 이 경우 x의 값을 대입해 y의 값을 구할 수 있다.

 

 

 

2. 수평 대칭축을 가지는 좌우로 뻗는 포물선의 방정식

 

꼭짓점의 좌표가 (h,k) 대칭축이 y = h인 포물선의 방정식

 

이 경우에는 오른쪽, 혹은 왼쪽으로 열려있는 포물선이 된다. 이 때는 y값을 대입해 x의 값을 구한다. 

 

 

 

 

 

◎ 원과 구

평면상에서 원은 주어진 고정된 한 점으로부터 반지름에 해당하는 일정한 거리만큼 떨어진 모든 점의 집합을 나타내는 용어이다.

그러므로 원의 방정식은 중심과 반지름 만으로 결정할 수 있다. 

여기서도 원의 중심으로부터 원 위의 한 점까지의 거리를 구하기 위해서 피타고라스의 정리가 사용된다.

 

중심의 위치가 (h,k)이고 반지름이 r인 원의 방정식은 다음과 같다.

 

만약 3차원상에서 구를 그리고 싶으면 중심의 좌표를 2개가 아닌 3개로 표현하면 된다.

중심이 (h,k,l)이고 반지름이 r인 구의 방정식은

 

 

 

 

◎ 응용 (충돌 체크)

원(2차원)과 구(3차원)을 이용하면 게임에서 경계, 즉 충돌 검사를 위해 사용할 수 있다. 체크하려는 점이 구 안에 들어와있는지 아닌지를 확인하면 된다.

 

원과 구와 충돌 되었는지를 확인하는 방법은 간단하다.

두 원이 위의 그림과 같이 붙어있다고 가정했을 때 두 원의 중심 사이의 거리 D는 두 원의 반지름 합인 r1+r2와 같다. 

만약 두 원이 서로 충돌한다면 두 원의 중심사이의 거리는 r1+r2보다 작아질 것이다. 

 

따라서 두 중심점 사이의 거리를 계산한 후 r1+r2가 거리보다 작은지 큰지를 계산해보면 된다.

작으면 두 원은 충돌한 상태일 것이고 크면 충돌하지 않은 상태이다. 

 

각 원이 위와 같이 정의될 때 이 두 원이 
이를 만족하면 충돌이 발생

 

 

그런데 코딩을 하다보면 제곱근 함수는 생각보다 매우 비싼, 프로세서의 처리능력이 많이 필요한 함수라는 것을 알게 될 것이다. 따라서 제곱근 연산을 뺀 계산이 더 효율적이다. 

 

각 원이 위와 같이 정의될 때 두 원이
를 만족하면 충돌이 발생

이렇게 바꿔준다.

 

 

 

 

 

 

참고 자료;

 

게임 프로그래머를 위한 기초 수학과 물리 (저; 웬디 스타일러, 더스틴 클링맨, 카베 카히리쯔 , 역 ; 엄윤섭 , 출판사 ; 제우미디어 )

 

 

 

 

두 점 사이의 거리 구하기

2차원과 3차원

 

 

 

플레이어 사이의 거리 혹은 충돌하려는 두 물체 사이의 거리, 더 나아가서는 사정 거리 안에 들어왔는지 아닌지를 알고 싶을 때가 생기면 어떻게 해야 할까?

가장 간단한 방법은 피타고라스의 정리를 이용하는 것이다.

 

 

 

 

◎ 두 점 사이의 거리

두 점 A와 사이의 거리를 구하고 싶다.

A와 B를 잇는 선분을 하나 그린 후 이를 빗변으로 하는 직각 삼각형을 하나 그린다.

A(x1, y1), B(x2, y2)라 할 때 나머지 하나의 꼭짓점의 좌표는 C(x2, y1)이 된다. 

 

여기서 피타고라스의 정리를 사용하면 A와 B를 잇는 빗변의 거리를 구할 수 있다.

 

 

제곱근은 직접 연산을 통해 계산해도 되지만 <math.h> 헤더를 추가해 sqrt 와 pow를 이용해도 된다. 

 

sqrt(값) 제곱근을 구하는 함수로 제곱근을 반환 

pow(값, 지수) 제곱을 구하는 함수. 

 

 

 

 

◎ 3차원으로의 확장

위의 거리의 공식은 xy축에 추가로 z축을 사용하는 3차원으로도 쉽게 확장할 수 있다.

공식에 z좌표만 추가하면 된다.

 

두 점 A(x1, y1, z1), B(x2, y2, z2) 사이의 거리는 

 

 

 

 

 

 

 

삼각함수

각도와 라디안, 그리고 sin cos tan.

 

 

 

 

 

◎ 각도와 라디안

라디안은 원주율의 단위이다. 호의 길의각도를 나타내기 때문에 호도법이라고도 한다. 

 

xy 좌표계에서 한바퀴를 돌아 제자리로 돌아오는 것은 360˚이다. 그리고 이에 해당하는 라디안 단위의 크기는 2πr이다. 

 

우리는 일상생활에서 각도를 많이 써서 각도가 더 익숙하다.

그러나 라디안을 이용하면 호의 길이와 각도를 구하기가 더 편리하고 깔끔하게 알아보기 쉽기 때문에 이러한 계산이 필요한 곳에서는 호도법을 이용한다. 

 

 

위키백과/ 라디안 

위의 그림같이 원의 반지름과 길이가 같은 호가 대하는 중심각의 크기는 1라디안이다.

 

 

◑ 도→ 라디안

도 단위의 각 * (π/180)

 

모든 C++ 삼각함수 라이브러리, sin()이나 cos(), tan() 등과 같은 것들은 라디안을 사용하고 삼각함수의 역함수 라이브러리의 리턴값 역시 라디안 단위이다. 

 

이런 것들은 미리 PI값을 #define 지시문으로 간편하게 변환을 할 수 있게 매크로로 정의해 놓는 것이 좋다.

 

 

 

 

 

◎ 삼각함수 (sin, cos, tan)

모든 삼각함수는 직각삼각형에 대해 정의된다.

그리고 그 직각삼각형을 통해 sin, cos, tan를 정의할 수 있다. 

삼각함수는 직각 삼각형에서 빗변, 높이, 밑변 사이의 비율을 나타내 흔히 삼각비라고도 한다. 

 

위와 같은 삼각형이 있을 때

  sin Θ cos Θ tan Θ
30˚

45˚
60˚

 

 

 

 

sin의 역함수는 csc(코시컨트), cos의 역함수는 sec(시컨트), tan의 역함수는 cot(코탄젠트)로 정의된다. 

 

csc Θ sec Θ cot Θ

 

이런 역함수들은 사인, 코사인, 탄젠트가 포함된 분수를 없애서 식을 간단하게 만들고자할 때나 여러 방면에서 활용이 가능하다. 

 

 

 

 

 

◎ 삼각함수의 합차공식

삼각함수의 합차공식은 벡터의 회전을 구할 때 사용된다. 

 

 

 

 

 

참고 자료;

 

https://ko.wikipedia.org/wiki/%EB%9D%BC%EB%94%94%EC%95%88

 

라디안 - 위키백과, 우리 모두의 백과사전

위키백과, 우리 모두의 백과사전. 라디안(영어: radian)은 각의 크기를 재는 SI 단위이다. 호도(弧度)라고도 하며, 기호는 rad이다. 단위원의 중심각의 라디안 값은 그 각이 대하는 호의 길이와 같다. 1라디안은 약 57.3도이다. 라디안은 입체각의 단위인 스테라디안과 함께 SI 보조 단위에 속했으나, 1995년에 SI 보조 단위가 폐지되면서 SI 유도 단위가 되었다. 라디안의 표기는 rad 기호가 가장 흔하며, 이는 자주 생략된다. 간혹 c(위첨

ko.wikipedia.org


게임 프로그래머를 위한 기초 수학과 물리 (저; 웬디 스타일러, 더스틴 클링맨, 카베 카히리쯔 , 역 ; 엄윤섭 , 출판사 ; 제우미디어 )

+ Recent posts