0

Hi I have an image like a round top of a table. I want to move it clockwise when ever user swipes from left to right and counter clockwise when user swipes from right to left.

Like moving a round table top in real time. How can I do this in the app?

I am using the following code for rotation. Its from the TrackBall example. The problem I am having is the when ever the image spins, it changes its position.

- (CATransform3D)rotationTransformForLocation:(CGPoint)location 
{  
    CGFloat trackBallCurrentPoint[3] = {location.x - trackBallCenter.x, location.y - trackBallCenter.y, 0.0f};

    if(fabs(trackBallCurrentPoint[0] - trackBallStartPoint[0]) < kTol && fabs(trackBallCurrentPoint[1] - trackBallStartPoint[1]) < kTol) 
    {
        return CATransform3DIdentity;
    }

    CGFloat dist = trackBallCurrentPoint[0] * trackBallCurrentPoint[0] + trackBallCurrentPoint[1] * trackBallCurrentPoint[1];
    if(dist > trackBallRadius * trackBallRadius) 
    {
        // outside the center of the sphere so make it zero
        trackBallCurrentPoint[2] = 0.0f;
    } 
    else 
    {
        trackBallCurrentPoint[2] = sqrt(trackBallRadius * trackBallRadius - dist);
    }

    // cross product yields the rotation vector
    CGFloat rotationVector[3];
    rotationVector[0] =  trackBallStartPoint[1] * trackBallCurrentPoint[2] - trackBallStartPoint[2] * trackBallCurrentPoint[1];
    rotationVector[1] = -trackBallStartPoint[0] * trackBallCurrentPoint[2] + trackBallStartPoint[2] * trackBallCurrentPoint[0];
    rotationVector[2] =  trackBallStartPoint[0] * trackBallCurrentPoint[1] - trackBallStartPoint[1] * trackBallCurrentPoint[0];

    // calc the angle between the current point vector and the starting point vector
    // use arctan so we get all eight quadrants instead of just the positive ones

    // cos(a) = (start . current) / (||start|| ||current||)
    // sin(a) = (||start X current||) / (||start|| ||current||)
    // a = atan2(sin(a), cos(a))
    CGFloat startLength = sqrt(trackBallStartPoint[0] * trackBallStartPoint[0] + trackBallStartPoint[1] * trackBallStartPoint[1] + trackBallStartPoint[2] * trackBallStartPoint[2]);
    CGFloat currentLength = sqrt(trackBallCurrentPoint[0] * trackBallCurrentPoint[0] + trackBallCurrentPoint[1] * trackBallCurrentPoint[1] + trackBallCurrentPoint[2] * trackBallCurrentPoint[2]);
    CGFloat startDotCurrent = trackBallStartPoint[0] * trackBallCurrentPoint[0] + trackBallStartPoint[1] * trackBallCurrentPoint[1] + trackBallStartPoint[2] * trackBallCurrentPoint[2]; // (start . current)

    // start X current we have already calcualted in the rotation vector
    CGFloat rotationLength = sqrt(rotationVector[0] * rotationVector[0] + rotationVector[1] * rotationVector[1] + rotationVector[2] * rotationVector[2]);

    CGFloat angle = atan2(rotationLength / (startLength * currentLength), startDotCurrent / (startLength * currentLength));

    // normalize the rotation vector
    rotationVector[0] = rotationVector[0] / rotationLength;
    rotationVector[1] = rotationVector[1] / rotationLength;
    rotationVector[2] = rotationVector[2] / rotationLength;

    CATransform3D rotationTransform = CATransform3DMakeRotation(angle, rotationVector[0], rotationVector[1], rotationVector[2]);
    return CATransform3DConcat(baseTransform, rotationTransform);
}

Thanks in advance.

tobinjim
  • 1,852
  • 1
  • 19
  • 30
Shakti
  • 1,689
  • 4
  • 17
  • 28
  • Look into both UIGestureRecognizer objects, and CAAnimation (Core Animation)! Else if there are specific code questions, please post what you have already!!! – trumpetlicks Jun 29 '12 at 05:30
  • Is this for frontend (web view, javascript) or for native app? – Tom Roggero Jun 29 '12 at 05:38
  • 1
    @Tom This is for native iPad app. – Shakti Jun 29 '12 at 06:01
  • 1
    Thanks for adding the code. The trackball example wants to move the object in all three dimensions. If I understand your goal, you only want to rotate around one axis. So if you don't want to reduce this method to operate on only one dimension, you'll need to at least modify the last line before the return to exclude the unnecessary rotations from the transform. – tobinjim Jul 11 '12 at 17:26
  • Do you think the position is changing possibly due to device orientation changes? See my [post](http://stackoverflow.com/questions/9488374/orientation-change-shrinking-the-frame-of-a-uiview-backed-by-a-catransformlayer) for my discussion of what I was seeing. – tobinjim Jul 11 '12 at 17:53

1 Answers1

2

Take a look at a question I posed... you might be trying to do the same thing (I don't think the question covered it, but after getting rotation working I implemented pan gesture to allow the user to spin the disc in either direction)

How to rotate a flat object around its center in perspective view?

Community
  • 1
  • 1
tobinjim
  • 1,852
  • 1
  • 19
  • 30
  • If you don't mind, can you please share the code to spin the disc in either direction. – Shakti Jul 03 '12 at 04:46
  • @Shakti, my code is fairly extensive because the design called for the platter to be rotating constantly, yet allows the user to spin it faster or slower, in either direction, so there are timers and brakes that restore the rotation to "normal" overtime. Here are the learning resources that helped me: – tobinjim Jul 03 '12 at 14:15
  • http://bill.dudney.net/roller/objc/entry/trackball_3d_transforms_made_easy and http://www.sunsetlakesoftware.com/2008/10/22/3-d-rotation-without-trackball – tobinjim Jul 03 '12 at 14:16
  • Thanks a lot for your help. I will try to work it out for me. – Shakti Jul 04 '12 at 03:19
  • The key thing to know is that presentationLayer has the *current* angle of rotation so when you're adjusting a rotation that's being animated you want to work from presentationLayer's values. – tobinjim Jul 04 '12 at 17:08
  • @ tobinjim Hi I am trying to spin the disk but the problem I am facing is the position doesn't remain same while spinning the disk. Some times it goes up n down. Can you help me on this? to spin it smoothly without changing the position of the image. – Shakti Jul 09 '12 at 04:09
  • If I understand stackoverflow etiquette you should edit your original post to include the rotation code you're using; that way I can look at it and others can comment as well. – tobinjim Jul 09 '12 at 04:45