본문 바로가기

programming/C++

보간법


보간법 (interpolation) – 하나의 값으로부터 다른 값으로 점진적으로 (매끄럽게) 이동해 나갈 수 있게 하는 방법!!

Ex) 벡터를 보간할 때에는 벡터의 각각의 성분들에 개별적으로 보간법 알고리즘을 적용하면 된다.

è  부동소수점 연산을 통한 프레임을 의존적인 감속 보간

@ 프레임율에 의존적인 방식으로 작동한다. 즉 초당 10 프레임에서의 결과와 초당 20프레임에서의 결과가 다르다. 따라서 이 방법은 정확도가 주된 요건이 아닌 경우에만 사용하는 것이다.

@ 이 방법에 깔린 개념은 현재 값과 목표 값의 가중 평균을 계산하되 현재 값에 더 큰 무게를 둔다는 것이다.

@ x = (xo*(weight -1)+xf)/weight

è  정수 연산을 통한 프레임율 의존적인 감속 보간

@ 이 보간법은 나누기를 수행하지 않으므로 속도가 매우 빠르다. 또한 부동소수점에 대한 지원이 제한된 콘솔 시스템이나 구식 컴퓨터에 적합하다. 대신 속도가 좀 떨어진다.

@ x=(x0*2n-1)+xf)>>n

@ x=(x0 *7=xf)>>n

è  프레임율 독립적인 선형 보간(linear interpolation)

@ 선형 보간의 경우에는 운동의 시작에서 속도를 얻고 매 프레임마다 그 속도대로 계속 움직이기만 하면 된다.

@ x =x0+tf*v

è  프레임율 독립적인 가속(ease-in)과 감속

@ 선형 보간이라는 것은 물리에서 생각하자면 속도가 일정한, 즉 가속도가 0인 등속 운동에 해당한다. 감속 현상과 가속 현상을 얻으려면, 가속도, 즉 속도의 변화율을 도입해야 한다. 그럼 속도가 0으로부터 시작해서 점점 증가하다가, 중간 이후부터는 점점 감속하는 운동 방식

@ x = x0 + v0t + 2/1at2

@ a= 2(x –x0) / t2

CEaseoutDivideInterpolation() 정의

class CEaseOutDivideInterpolation : CEaseOutShiftInterpolation

{

       public SetUP(float from, float to, float divisor)

       {

             If(divisor <= 0)

             {

                    return false;

             }

             _value = from;

             _target = to;

             _divisor = divisor;

             return true;

       }

       bool Interpolate() //참고: 시간에의존적이지않음

       {

             float oldValue = _value;

             if(_divisor > 0)

             {

                    _value = (_value * (_divisor -1.0f) + _target)/_divisor;

             }

             //true가되기까지는시간이걸린다.

             return (_value == oldValue);

       }

       float GetValue()

       {

             return _value;

       }

private:

       float _value;

       float _target;

       float _divisor;

};

 

 

CEaseOutShiftInterpolation() 정의

class CEaseOutShiftInterpolation

{

public:

       bool Setup(int from, int to, int shift)

       {

             if(shift <=0)

             {

                    return false;

             }

             _value = from;

             _target = to;

             _shift = shift;

             return true;

       }

       bool Interpolate() //참고: 시간에의존적이지않ㅇ므

       {

             int oldValue= _value;

             if(_shift > 0)

             {

                    _value = (_value * ((1 << _shift) -1) + _target) >> _shift;

             }

             //부동소수점버전보다는훨씬빨리TRUE

             return (_value == oldValue);

       }

       int GetValue()

       {

             return _value;

       }

private:

       int _value;

       int _target;

       int _shift;

};


CLinearInterpolation 정의

class CLinearInterpolation

{

public:

       bool Setup(float from, float to, float time)

       {

             if(time <0)

             {

                    return false;

             }

             _remainingTIme = time;

             _value = from;

             _step = (to - from)/time; //초당거리를계산한다.

       }

       //목표에도달했거나지나쳤으면TRUE를돌려준다.

       bool Interpolate(float deltaTime)

       {

             _remainingTIme -= deltaTime;

             _value += _step*deltaTime;

             return (_remainingTime <=0);

       }

       float GetValue()

       {

             return _value;

       }

private:

       float _value;

       float _step;

       float _remainingTime;

 

};

CEaseInOutInterpolation() 정의

class CEaseInOutInterpolation

{

public:

       bool Setup(float from, float to, float time)

       {

             if(time <= 0)

             {

                    return false;

             }

             _value = from;

             _target = to;

             _speed = 0.0f;

             //x=x0 * v0*t + a*t*t/2에서유도한공식

             _acceleration = (to-from)/(time*time/4);

             _remainingTime = _totalTime = time;

             return true;

       }

 

       bool Interpolate(float deltaTime)

       {

             _remainingTime -= deltaTime;

             if(_remainingTime < _totalTime/2)

             {

                    //감속

                    _speed -= _acceleration * deltaTime;

              }

             else

             {

                    //가속

                    _speed += _acceleration * deltaTime;

             }

             _value += _speed * deltaTime;

             return (_remainingTime <= 0);

       }

       float GetValue()

       {

             return _value;

       }

private:

       float _value;

       float _target;

       float _remainingTime;

       float _totalTime;

       float _speed;

       float _acceleration;

}

'programming > C++' 카테고리의 다른 글

[Visual Studio 6.0 - Workspace] 사용법 및 관리, 동적링크라이브러리  (0) 2011.03.31
Visual Studio 2010 C++ 단축키  (0) 2011.03.08
객체출력자  (0) 2009.11.24
MyVector!!!  (0) 2009.11.19
1. 순차보관  (0) 2009.11.19