프레임에 독립적인 가속(ease-in)과 감속(ease-out) 보간


이 방법은 Game Programing Gems vol 1의 2.1 보간법(Johm Olsan)에서 다루는 방법으로, 

프레임 변화율에 무관하게 가속 감속 보간을 실행한다.

(GPG Gems vol 1 - 2.1 보간 법 : 프레임율 독립적인 가-감속 보간)


아래 사진은 GPG 1권의 Ease In Out Interpolation 그래프이다.









프레임 율에 독립적으로 동작 하면서 가속과 감속 처리를 하기 위해서는 시간 기반(time based) 보간처리를 해야 한다.

(시간 기반 Animation 참조 )

즉, 현재 시간(t_1)에 이전 시간(t_0)를 빼줌으로서 delta time(dT)를 구해야 한다.


또한 가속 - 감속 처리를 위해서 가속도(Acceleration)값을 가중치(weight)로 이용해서 구한다.


우리는 보간 처리를 하기 위해서, 좌표의 변화량(변위)값을 구하는 것이 목적이다.

그럼으로 아래와 같은 물리 방정식을 이용해서 변위 값을 유도해 낼 수 있다.


가속도(acceleration) = 이동속도 / 이동시간 = deltaVelocity / deltaTime = (v_f - v_0) / (t_1 - t_0) = dV / dT

속도(velocity).= 이동거리 / 이동시간 = range / deltaT = (x_f - x_0) / (t_1 - t_0) = dR/ dT

변위(Displacement, range) = 속도 * 이동시간 = (x_f - x_0) = (d_f - d_0) = v * (t_1 - t_0) = v * dT


운동 방정식 1

a = (v_f - v_i) / (t_f- t_i)

v_f = v_i + aT

최종 속도 = 초기속도 + 가속도*시간

시간 = t_f - t_i = T


운동 방정식 2

등가속도 운동일 경우,

avg_v = (v_i + v_f) / 2

평균속도 = (초기속도 + 최종속도) / 2


평균속도는 시간에 따른 변위의 비율 과 등가속도 운동일 경우 식을 통하여 대수적으로 변형할 수 있다.

avg_v = deltaX / t

deltaX / t = (v_i + v_f) / 2

deltaX = (v_i + v_f) * t / 2


운동 방정식 3

dX = (v_i + v_f) * t / 2

변위 = (초기속도 + 최종속도) * 시간 / 2


(운동방정식 1) (운동방적식 3)에 치환하면 다음과 같은 식으로 유도할 수 있다.

deltaX = (v_i + v_i + aT) * T / 2

deltaX = v_i*T + (aT^2) / 2

변위 = 초기속도 * 시간 + 가속도 * 시간^2 / 2



Function 

F = v = a*t = (x_1 - x_0) / (t * t / 4) * t


(운동 방정식 3) 을 이용하여 가속도와 변위를 구한다.


displacement : x = x_0 + (v_0 * t) + a * t * t / 2

acceleration : a = (x_1 - x_0) / (t * t / 2)          <- v_0는 초기속도임으로 0으로 볼수 있다.

velocity : v = acceleration * t 


가속도 식에서 2로 나누는 값을 4로 나눠야 한다. 이는 가-감속식에서

변위의 중간 위치에서 단계가 계속 증가하는 것이 아니라 감속하기 때문이다.

(첨부한 엑셀 interpolation.xlsx에서 확인하도록 하자.)



Pseudo Code

// 보간 처리할 간격 구하기.

// EaseInOut 가-감속 보간 수식.

// 등가속도 운동으로 구한다.


n = 100;

x_final = 600;

time = 10.0f ;

acceleration = (x_final - x0) / (time * time / 4);

velocity = acceleration * deltaT;


deltaT = time / n;

remainingTime = time - deltaT;


do {

if (remainingTime > time/2) {

// 가속 처리

velocity += (acceleration * deltaT);

} else {

// 감속 처리

velocity -= (acceleration * deltaT);

}

x1 += (velocity * deltaT);

interpolation_values[interpolation_index++] = (x1 - x0);  // x 의 변화량을 보간 값으로 저장한다.

x0 = x1;


remainingTime -= deltaT;

} while(remainingTime > 0.0f);


Evaluation

range : i = 0, n = 600

time = 10.0f



Result

EaseInOut 가-감속 보간 결과


EaseInOut 가-감속을 위한 변화량 결과 ; (x_1 - x_0)

(변화량은 등가속도 운동을 함으로 일정한 간격으로 상승했다가 하강한다.)





http://www.gizma.com/easing/  <-- 여기 보면 Ease in / out 를 직접 확인해볼수있다.


'그래픽스' 카테고리의 다른 글

메쉬 생성 방법 소개  (0) 2015.07.21
메쉬 제네레이션 - delaunay triangulation  (0) 2015.07.21

 Mesh Generation 방법 


  (1)Scatter Points를 이용하여 요소망 생성하기 




                                                                            xyz 파일 


                                                                         파일 임포트 

                                                       들로네 삼각화로 메쉬 생성 



(2)Polygon을 이용한 요소망 생성


● 그림과 같이 지형 자료를 바탕으로 polyline을 형성할 수 있다.

● 지형 자료와 polyline의 선 색깔을 구분하기 위해서 polyline의 Display 옵션을 조정할 수 있다.

● Polyline은 마우스 왼쪽 클릭으로 vertex를 만들어 나가며 마우스 오른쪽 버튼을 클릭하면 polyline 만들기를 멈추게 된다.

● 마우스를 vertex에 가까이 가져가게 되면 osnap 기능이 작동하여 작은 사각형이 보이게 된다. 이 상태에서 마우스 왼쪽 클릭을 하여야 만 vertex가 연결된다.

● Polyline을 만든 후에도 polyline을 선택한 후 vertex를 클릭하면 vertex의 위치를 수정할 수 있다.

● 모든 polyline이 연결된 상태에서만 polygon을 만들 수 있다.


                                                     지도를 따라 폴리라인 생성 



                                              폴리라인기반으로 삼각 메쉬 생성


(3) Structured Mesh Generation


본 요소망 생성 방법은 4개 혹은 3개의 polyline를 갖는 polygon에서 각 polyline의 절점을 생성한 후에 요소망을 생성시키는 방법 이다. 4개의 polyline을 갖는 polygon은 삼각, 사각 요소망 둘 다 가능하지만, 3개의 polyline을 갖는 polygon은 삼각형 요소망 만을 형성할 수 있다.









'그래픽스' 카테고리의 다른 글

Ease in / out 보간법 (펌)  (0) 2015.07.22
메쉬 제네레이션 - delaunay triangulation  (0) 2015.07.21

http://www.codeproject.com/Articles/492435/Delaunay-Triangulation-For-Fast-Mesh-Generation  (펌) 



Introduction  

Ten years ago, computing meshes for surfaces in real time for surfaces wasn't realistic, and having a customizable source code module wasn't available either. There are faster versions, but they are large implementations and they are hard to read and modify.  With modern computers and modern languages, not only can simple meshes be generated in real time, the code can be written in ways easy to understand. It is the authors opinion that computational geometry and computer vision are entering a new age where real time processing is realistic for a growing set of problems.  The code is designed to be reused such that a vertex can be used to both generate the mesh, but also be apart of other data structures and track other aspects at a given point.  

To form a surface that can be shaded by a graphics card, the goal is to create a list of vertexes, and a list of triplet indexes of the vertexes that form counter clockwise triangles. Whether it is to visualize a differential equation solved by finite element modeling (FEM) or to view a shape of an object in 3D, the first step is to form the triangle mesh.  Usually selecting a set of points is easy, For simple objects like a cylinder or sphere, the point generation leads directly to triangle generation. Generating a mesh from an arbitrary set of points is where Delaunay's Triangulation proves valuable.  The goal of the code wasn't to compute the ideal triangulation, but instead produce a “good enough” solution for most practical 3D or FEM problems and do so quickly. Thus the code recursively improves the triangulation after adding each point to either a recursion count is reached or it is an ideal Delaunay triangulation. This limits how long a mesh can take to compute and avoids infinite recursion should there be a software bug.

Background

Delaunay's Triangulation is named for Boris Delaunay. The general idea is to form a mesh where each triangle's three points lie on the edge of a circle that doesn't contain any other point. This means given any two adjacent triangle's (quadrilateral) the sum of the angles opposite the dividing line are less than 180 degrees.


Triangle mesh a,b,d and b, c, d don't meet the Delaunay condition. But b,c,a and c,d,a do. This is because angle bcd + dab > 180, but abc+cda < 180. This forces the mesh to have triangles that tend to be as close to evenly spaced as possible.

The Bowyer Watson algorithm iteratively adds a point at a time to a mesh to transform it from one Delaunay mesh to another. The general algorithm works by deleting all triangles whose circumscribed circle contains the new point and reform the mesh. The code provided takes a simpler approach.  

From top to bottom, the triangles are flipped to meet the Delaunay condition with 3 points:

This does the same thing but with seven points. Note how at first the triangles are mostly slivers and other triangles are huge.

 After one level of flipping per insertion the meshing is more regular (below).

After a second round of flipping, the effects of the first flip are then flipped as needed (below).

Design  

Mesh Generation

The Bower-Watson algorithm is a bit complex because:  

  • Adding one point may cause a set of triangles to be deleted, and reformed.
  • Reforming the set at once explores forming many possible triangulations.
  • One must search for the affected triangle's. 
  • There isn't a pattern for adjusting the mesh in an ordered fashion.   

The “hull” based techniques that are also commonly used spiral out from a point and reform the triangulation from the inside out. This approach is nice because it takes an ordered approach to computing and recomputing the mesh. The disadvantage as the software is recomputing the circle for each triangle and sorting through the triangles in real time.  

The code provided takes a hybrid approach that forms a linked list of triangles. Each triangle consists of three vertexes, and each side, there is a pointer to the adjacent triangle (or null). The code has the following advantages:  

  • Each triangle has a link to its neighbors.   
  • Recursion explores outward if a triangle is altered, its neighbors may be affected (no circles).
  • Triangles aren't not generally deleted, they are added or modified.  
  1. Compute the bounding rectangle: 
  2. Note that a->b->c is counter clockwise, so if it had a face rendered by say direct3D, it would face out from the page. Triangle c->b->a is clockwise so it's face is toward the page. As long as the direction is maintained, the start point isn't relevant, so bdc is the same as dcb or cbd. This concept in abstract algebra is often called commutation.

    In memory at this point: 

    Triangle 1 = a,b,c, and side b,c = triangle 2. 

    Triangle 2 = bdc, and c,b = triangle 1.

  3. Find the triangle containing the new point (for example, abc), and replace the old triangle 1 with three new triangles.  

  4. Repair the pointers: 

  5. abe with side be should point to ebc.

    Abe with side ea should point to aec.

    Etc. 

    Then repair those old adjacent triangles that used to point to abc:  bdc side bc used to point to abc, make it point to ebc.

  6. Examine each triangle and it's outward adjacent:. For example bec shares a side with bdc.

  7. Examine the angles across from the adjacent sides. If greater than 180 degrees, flip the adjacent line.

  8. If the triangle is not flipped skip to step 10.  

  9. Reform the old triangles into the new triangles, fix the triangle edges. 

  10. For each triangle and it's adjacent triangle repeat steps 5-8 recursively. 

Triangle Contains a Point

The key to the algorithm is finding the correct triangle to modify.

Classically, a triangle contains a point if it is on the interior side. If a line passes through two points, the line is often expressed as y = mx + b, where m is the slope, and b is the x=0 intercept. The area above the line can be expressed as y > mx+b. So, I a triangle has edge s, r and the other point is t. Then if test point p, is on the same side of the inequality as the point t, then the test point p is on the same side of the line as the other vertex.

This means to compute if a point p is inside, the code compares to see if it's on the same side as the vertex for an edge. That is a lot of computations. Caching the information speeds up the comparison but not enough.  Most triangles don't contain the point, and the point is not anywhere near the triangle. To accelerate the computations, only points that are near the triangle need to be tested using the classical method. The software computes the distance between each vertex and the triangle's center. If the point is not closer than this distance it does not need to be tested.

Acceleration

The triangle objects cache information calculated on demand to form the mesh. When a triangle is "flipped" with it's neighbor, two of it's side's change but two of the points remain. When a vertex moves, it invalidates the existing information about those edges.

For example, the center of a triangle changes if any vertex changes, setting points A, B, C sets the calculated to false, asking for the center calculates it ans sets the flag.

Vertex m_Center;

public Vertex Center
{
    get
    {
        if (m_centerComputed) return m_center;
        m_center = new Vertex(
            (A.X + B.X + C.X) / 3f,
            (A.Y + B.Y + C.Y) / 3f,
            (A.Z + B.Z + C.Z) / 3f);

        float delta = m_center.DeltaSquared(A);
        float tmp = m_center.DeltaSquared(B);
        delta = delta > tmp ? delta : tmp;
        tmp = m_center.DeltaSquared(C);
        delta = delta > tmp ? delta : tmp;
        FarthestFromCenter = delta;
        m_centerComputed = true;

        return m_center;
    }
} 

Once the center is computed the software can reuse this information and it is only then recalculated on demand.

'그래픽스' 카테고리의 다른 글

Ease in / out 보간법 (펌)  (0) 2015.07.22
메쉬 생성 방법 소개  (0) 2015.07.21

+ Recent posts