A colossal Dreamer: GR鐵塔-天生我材

드래그(Pan, drag) 동작에서 관성유지에 대한 수학적 접근 본문

낙농일기

드래그(Pan, drag) 동작에서 관성유지에 대한 수학적 접근

江多林 2018. 2. 21. 16:21

패닝이벤트 처리를 위한 수식

-상식으로도해결가능하지만-


입력종료시에 속도(v0)일 때,

시간(t1)동안 등감속하여, 멈추는 경우


이동거리는 (1/2)*v0*t1

여기서 가속도는 v0->0 으로 v0와 t1 으로 표현 가능하다.


문장으로 정리하면,

등감속 이동거리는

입력종료시의 속도(v0)로 감속시간(t1) 동안

이동한 거리의 절반이다.


아래 이미지는 수식으로 증명한 과정.





Swift code: Panning -> Moving with a Moment


@objc func panGestureAction(_ gesture: UIPanGestureRecognizer!) {

    print("\(#function) v:\(gesture.velocity(in: self.view))")

    guard gesture.state != .began else {

        gesture.setTranslation(CGPoint.zero, in: self.view)

        return

    }

    

    // 드래그 시작 후 기준좌표계에서 이동 거리

    let movingPoint: CGPoint = gesture.translation(in: self.view)

    

    if gesture.state == .ended {

        // 애니메이션 듀레이션

        let panMomentDuration: TimeInterval = 0.15

        // 시작속도 v0

        let velocity_v0 = gesture.velocity(in: self.view)

        // 듀레이션 t1

        let duration_t1 = CGFloat(panMomentDuration)

        // 관성이동거리

        let momentDistance = velocity_v0.scaling(duration_t1/2.0)

        // 최종 변경된 위치

        let endCenter = self.playerContainerView.center

            .adding(distance: movingPoint)

            .adding(distance: momentDistance)

        

        UIView.animate(withDuration: panMomentDuration,

                       delay: 0.0,

                       options: [.beginFromCurrentState,

                                 .curveEaseOut],

                       animations: {

                        self.playerContainerView.transform = .identity

                        self.playerContainerView.center = endCenter

        },

                       completion: nil)

    } else {

        let movingTransform = CGAffineTransform(translationX: movingPoint.x,

                                                y: movingPoint.y)

        self.playerContainerView.transform = movingTransform

    }

}