아핀 공간과 벡터 공간의 차이점에 대해 정리하시오.
1. 아핀 공간이란
- 어떤 점이 원 점이었는지 잊어버린 벡터 공간의 남은 공간.
2. 아핀 공간의 특징
1) 점 + 벡터 = 점
2) 벡터 + 벡터 = 벡터
3) 점 - 점 = 벡터
3. 두 공간의 차이점
벡터 공간에서는 벡터의 위치와 상관없이 크기와 방향만 같다면 같은 벡터로 취급한다. 하지만, 벡터로만 이루어져 있기 때문에 엄연히 다른 벡터임에도 같은 벡터로 취급 되는 경우가 있다.
아핀 공간에서는 이러한 문제들을 극복할 수 있는 점이 존재하며, 이 점을 통해 해당 벡터의 크기, 방향 뿐 아니라 위치까지도 표현할 수 있다.
Transform에서 스케일, 회전, 이동 세 가지 변환을 순서대로 적용할 경우 가장 이상적인 변환 순서를 적고 그 이유를 설명하시오.
Transformation에 존재하는 변환들이다.
가장 이상적인 변환 순서 : 스케일 -> 회전 -> 이동
이유 : 스케일 변환은 회전 변환에 영향을 받고 또한, 회전 변환은 이동 변환에 영향을 받기 때문에.
아래 그림과 같이 이동 변환 후 회전 변환을 하면 객체가 이동 된 지점을 기준으로 회전하기 때문에 위치가 달라진다.
"an affine space is what is left of a vector space after you've forgotten which point is the origin" 에 대한 개인적인 생각을 정리해보시오.
아핀공간은 벡터공간의 일부라고 생각한다.
아핀공간에는 점들이 있으며 그 점들의 시작점이 본인들이 생각하기에 원점이라 생각한다. 하지만 벡터공간을 기준으로 봤을때에는 그렇지 않다. 그렇기 때문에 아핀공간은 원점이 어디인지 잊어버린 벡터공간의 일부라 생각하며, 우리는 아핀공간의 세번째 요소를 이용해서 선형성을 만족하며 2차원 공간을 이동시킬 수 있는 것이다.
수업 복습에 있는 2번 과제를 토대로 Transform 클래스를 완성하시오.
GetModelingMatrix
Matrix3x3 Transform::GetModelingMatrix() const
{
Vector3 transCols(Position._X, Position._Y, 1);
Matrix3x3 translateMatrix(Vector3::UnitX, Vector3::UnitY, transCols);
float rot = Math::Deg2Rad(Rotation);
Vector3 rotX(cosf(rot), sinf(rot), 0);
Vector3 rotY(-sinf(rot), cosf(rot), 0);
Matrix3x3 rotateMatrix(rotX, rotY, Vector3::UnitZ);
Matrix3x3 scaleMatrix(Vector3::UnitX * Scale._X, Vector3::UnitY * Scale._Y, Vector3::UnitZ);
return translateMatrix * rotateMatrix * scaleMatrix;
}
CalculateLocalAxis
void Transform::CalculateLocalAxis()
{
float cos = cosf(Math::Deg2Rad(Rotation));
float sin = sinf(Math::Deg2Rad(Rotation));
Right = Vector2(cos, sin); //right벡터는 x축 c s
Up = Vector2(-sin, cos); // up벡터는 y축 -s c
}
Transform 클래스와 Sinewave를 활용해 변환에 의한 효과를 직접 만들어 보시오.
Update2D and Render2D
// 게임 로직
void SoftRenderer::Update2D(float InDeltaSeconds)
{
// Matrix 쓰면 안됨.
static float _time = 0.f;
static bool isOne, isTwo = false;
float halfPiSin = sinf(_time * Math::HalfPI);
float twoPISin = sinf(_time * Math::TwoPI);
float piSin = sinf(_time * Math::PI);
if(!isOne && !isTwo)
_time += InDeltaSeconds;
if (isOne && !isTwo)
_time -= InDeltaSeconds;
if (isOne && isTwo)
_time += InDeltaSeconds;
if(_time > 4 && !isOne && !isTwo) {
isOne = true;
}
if (_time < 0 && isOne && !isTwo) {
isTwo = true;
}
if (_time > 4 && isOne && isTwo) {
_time = 0; isOne = false; isTwo = false;
}
if (!isOne && !isTwo) {
_Transform.SetPosition(Vector2(_time, halfPiSin));
_CurrentColor = LinearColor::Red;
}
if (isOne && !isTwo) {
_Transform.SetPosition(Vector2(_time, twoPISin));
_CurrentColor = LinearColor::Blue;
}
if (isOne && isTwo) {
_Transform.SetPosition(Vector2(_time, piSin));
_CurrentColor = LinearColor::Black;
}
}
// 렌더링 로직
void SoftRenderer::Render2D()
{
//Matrix 써도 됨.
// 격자 그리기
DrawGrid2D();
// 18도 간격으로 20개의 점을 그린다.
for (int i = 0; i < 20; i++)
{
float rotateRadian = Math::Deg2Rad(i * 18.f);
float sin = sinf(rotateRadian);
float cos = cosf(rotateRadian);
Vector3 newXAxis(cos, sin, 0);
Vector3 newYAxis(-sin, cos, 0);
Matrix3x3 rotateMatrix(newXAxis, newYAxis, Vector3(0.f, 0.f, 1.f));
Vector2 newPosition = (rotateMatrix * _Transform.GetModelingMatrix() * _Transform.GetPosition()) * 10.f;
// 지정된 위치에 지정한 색상으로 점 찍기
_RSI->DrawPoint(newPosition, _CurrentColor);
_RSI->DrawPoint(newPosition + Vector2::UnitX, _CurrentColor);
_RSI->DrawPoint(newPosition - Vector2::UnitX, _CurrentColor);
_RSI->DrawPoint(newPosition + Vector2::UnitY, _CurrentColor);
_RSI->DrawPoint(newPosition - Vector2::UnitY, _CurrentColor);
}
}
결과
GitHub Link
'게임제작기법연구' 카테고리의 다른 글
게임제작기법연구 7주차 (0) | 2020.05.26 |
---|---|
게임제작기법연구 6주차 (0) | 2020.05.19 |
게임제작기법연구 5주차 (0) | 2020.05.12 |
게임제작기법연구 2주차 (0) | 2020.04.09 |
게임제작기법연구 1주차 (0) | 2020.04.07 |