Scaling
display object를 멀티 터치로 컨트롤 하면서 우리가 원하는 transformation을 적용하려면 모든 tracking dot들의 평균 값들이 필요합니다. 그리고 그 값을 display object의 midpoint (그 평균 위치) 에 이미지를 위치시켜야 합니다.
scaling 과 관련해서는 수학적인 계산이 필요합니다.
midpoint 와 tracking dot들 간의 거리의 합 구하기
거리의 합계를 dot 들의 갯수로 나눈 평균 거리 구하기
tracking dot 들의 이전 위치에 대한 같은 평균 거리 구하기
이전과 현재의 평균 거리 사이의 차이 구하기
display object 의 .xScale 과 .yScale에 multiplication 으로 그 차이를 적용하기
이건 여러 tracking dot들이 움직일 때 display object 의 평균 transition 을 어떻게 적용할 지를 정해 주는 겁니다. 이 scaling 값을 얻도록 하는 기본 라이브러리 함수들을 만들 겁니다. 아래 함수는 스크린의 두개의 지점사이의 거리를 계산하는 함수입니다. 아주 전형적인 삼각함수죠.
sample8.lua
-- returns the distance between points a and bfunction lengthOf( a, b )local width, height = b.x-a.x, b.y-a.yreturn (width*width + height*height)^0.5end
tracking dot들의 midpoint 를 얻기 위해 sample 5 에서 다뤘던 calcAvgCentre() 함수를 사용할 겁니다. midpoint 와 tracking dot 들 사이의 평균 거리를 구해서 저장하기 위해 다음과 같은 함수들을 사용할 겁니다. 첫번째는 각 dot 들의 현재 distance 를 get 해서 그 값을 tracking dot 에 저장할 겁니다. 그리고 이전 distance 도 물론 저장하구요. 두번째 함수에서는 이전과 현재 거리 set 들 사이의 차이를 계산하는 함수를 사용할 겁니다.
-- calculate each tracking dot's distance from the midpointlocal function updateTracking( centre, points )for i=1, #points dolocal point = points[i]point.prevDistance = point.distancepoint.distance = lengthOf( centre, point )endend-- calculates scaling amount based on the average change in tracking point distanceslocal function calcAverageScaling( points )local total = 0for i=1, #points dolocal point = points[i]total = total + point.distance / point.prevDistanceendreturn total / #pointsend
이 함수를 사용하는 방법은 간단합니다. rect:touch()의 began 과 ended phase 에서 call 하시면 됩니다. 그러면 이 함수들이 적당한 값으로 해당 tracking dot 들의 값을 update 할 겁니다. 아래는 began 과 ended phase 에서 call 하는 부분입니다.
-- "began"-- pre-store the tracking dot scale and rotation valuesupdateTracking( rect.prevCentre, rect.dots )return true -- we handled the began phase-- "ended"-- store the new centre of all touch pointsrect.prevCentre = calcAvgCentre( rect.dots )-- refresh tracking dot scale and rotation valuesupdateTracking( rect.prevCentre, rect.dots )
moved phase 는 조금 더 복잡합니다. 왜냐하면 실제 이 부분에서 대부분의 일이 진행 될 거거든요. 다행히 여기서 우리가 해야 될 일은 tracking dot 을 update 하는 똑 같은 일에다가 tracking dot 이 한개 이상일 경우 scaling 을 적용하는 일 뿐입니다.
if (e.phase == "moved") thenprint( e.phase, e.x, e.y )local centre, scale, rotate = {}, 1, 0 -- declare working variablescentre = calcAvgCentre( rect.dots ) -- calculate the average centre position of all touch pointsupdateTracking( rect.prevCentre, rect.dots ) -- refresh tracking dot scale and rotation values-- if there is more than one tracking dot, calculate the rotation and scalingif (#rect.dots > 1) thenscale = calcAverageScaling( rect.dots ) -- calculate the average scaling of the tracking dotsrect.xScale, rect.yScale = rect.xScale * scale, rect.yScale * scale -- apply scaling to rectendrect.x = rect.x + (centre.x - rect.prevCentre.x) -- update the X position of rectrect.y = rect.y + (centre.y - rect.prevCentre.y) -- update the Y position of rectrect.prevCentre = centre -- store the centre of all touch pointselse -- "ended" and "cancelled" phases
위에서 moved phase 에서 우리가 바꾼 부분은 아래와 같습니다.
앞으로 일어날 transformation 값들과 같이 사용될 변수들 정의
tracking dot 들의 저장된 distance 값을 refresh 하기 위해 updateTracking 을 call 하기
tracking scaling 에서 변한 값의 평균을 구하기 위해 distance 값들 사용하기
display object "rect" 에 해당 scaling 적용하기
The display object now translates (moves) and scales (zooms) along with our tracking dots (touch points).
이제 이 display object 는 tracking dot 들 (touch point 들) 의 움직임에 따라 translates (moves) 과 scales (zooms) 를 하게 됐습니다.
'Corona SDK > Corona Doc' 카테고리의 다른 글
iOS 에서 이메일 첨부파일 사용하기 (0) | 2013.02.19 |
---|---|
멀티 터치 지원하는 모양 맞추기 앱 개발하기 (2) | 2013.02.15 |
Pinch Zoom Rotate 구현하기 - 11/11 - (0) | 2013.02.14 |
Pinch Zoom Rotate 구현하기 - 10/11 - (0) | 2013.02.14 |
Pinch Zoom Rotate 구현하기 - 9/11 - (0) | 2013.02.14 |
Pinch Zoom Rotate 구현하기 - 7/11 - (0) | 2013.02.12 |
Pinch Zoom Rotate 구현하기 - 6/11 - (0) | 2013.02.12 |
Pinch Zoom Rotate 구현하기 - 5/11 - (0) | 2013.02.09 |
Pinch Zoom Rotate 구현하기 - 4/11 - (0) | 2013.02.01 |
Pinch Zoom Rotate 구현하기 - 3/11 - (0) | 2013.01.29 |