반응형
블로그 이미지
개발자로서 현장에서 일하면서 새로 접하는 기술들이나 알게된 정보 등을 정리하기 위한 블로그입니다. 운 좋게 미국에서 큰 회사들의 프로젝트에서 컬설턴트로 일하고 있어서 새로운 기술들을 접할 기회가 많이 있습니다. 미국의 IT 프로젝트에서 사용되는 툴들에 대해 많은 분들과 정보를 공유하고 싶습니다.
솔웅

최근에 받은 트랙백

글 보관함

Pinch Zoom Rotate 구현하기 - 10/11 -

2013. 2. 14. 06:23 | Posted by 솔웅


Posted on . Written by



Pinch Centre Translation


이전 글에서 만들었던 sample9.lua 코드를 실행해 보세요. tracking dot 들이 rotate,scale, move 할 때 display object 가 약간씩 이동하는 걸 보실 수 있을 겁니다. 이렇게 하면 정확하게 그 midpoint 를 얻을 수가 없는 상황이거든요.


이 문제를 해결하려면 translation, scaling, rotation 을 적용하는데 단순히 basic 만 사용하면 안됩니다. 여기에 display object 의 center point location 도 같이 적용해야 합니다.

    Scaling 은 midpoint 와 “rect” centre 사이의 거리도 참고해서 적용되어야 합니다.
    Rotation 은 “rect” centre 에 적용 되야 합니다. tracking dot midpoint 주위를 회전해야 합니다.
    translation 은 이미 적용됐기 때문에 따로 고려를 하지 않아도 됩니다.


이제 어떤 standard library 수학 함수를 우리가 사용해야 할까요? point 를 회전시켜야 하는데 그 회전은 다른 포인트 주변을 돌아야 합니다. 그러니까 우리는 math helper 들을 사용할 필요가 있습니다. 또한 moved phase 에도 작업을 해 줘야 합니다.



sample10.lua


-- rotates a point around the (0,0) point by degrees
-- returns new point object
function rotatePoint( point, degrees )
local x, y = point.x, point.y
local theta = math.rad( degrees )
local pt = {
x = x * math.cos(theta) - y * math.sin(theta),
y = x * math.sin(theta) + y * math.cos(theta)
}
return pt
end
 
-- rotates point around the centre by degrees
-- rounds the returned coordinates using math.round() if round == true
-- returns new coordinates object
function rotateAboutPoint( point, centre, degrees, round )
 
local pt = { x=point.x - centre.x, y=point.y - centre.y }
pt = rotatePoint( pt, degrees )
pt.x, pt.y = pt.x + centre.x, pt.y + centre.y
if (round) then
pt.x = math.round(pt.x)
pt.y = math.round(pt.y)
end
return pt
end
 
 
-- changes to 'moved' phase
 
-- ...
-- apply rotation and scaling to rect
rect.rotation = rect.rotation + rotate
rect.xScale, rect.yScale = rect.xScale * scale, rect.yScale * scale
end
local pt = {} -- declare working point for the rect location
-- translation relative to centre point move
pt.x = rect.x + (centre.x - rect.prevCentre.x)
pt.y = rect.y + (centre.y - rect.prevCentre.y)
-- scale around the average centre of the pinch (centre of tracking dots, not rect centre)
pt.x = centre.x + ((pt.x - centre.x) * scale)
pt.y = centre.y + ((pt.y - centre.y) * scale)
-- rotate the rect centre around the pinch centre (same rotation as the rect is rotated!)
pt = rotateAboutPoint( pt, centre, rotate, false )
-- apply pinch translation, scaling and rotation to the rect centre
rect.x, rect.y = pt.x, pt.y
-- store the centre of all touch points
rect.prevCentre = centre
 
else -- "ended" and "cancelled" phases

main.lua

sample10.lua


moved phase 에 여러 기능들이 추가 됐습니다.


    pt 는 display 객체의 포지션 에 대한 working space 를 사용하기 위해 정의됩니다.
    midpoint translation은 working object 에 적용됩니다.
    midpoint 와 display object 중심사이의 거리가 scale 됩니다.
    display object 의 중심은 midpoint 주위를 회전합니다.


이제 코드를 실행해 보세요. 여러분 손가락이 어디에 있던 touch (tracking dot) 은 display object 에서 시작되고 touch point 에 따라 pinch-zoom 이 일어날 겁니다.


이 효과는 손가락 두개를 사용할 때 제대로 나타날 겁니다. 이전에는 tracking point들이 display object 에서의 그들의 시작지점의 영향을 받았었는데 이제는 약간 달라졌거든요. 결과는 거의 같긴 하지만 터치 포인트들간의 평균이 조금 더 정확해 졌습니다.



반응형

Comment