Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

larswik

macrumors 68000
Original poster
Sep 8, 2006
1,552
11
I started to read Beginning iPhone Game Development by Apress. I decided to experiment a little to better understand so I created a Color wheel in Photoshop that was 250 x 250. I made the view background black and the edges of my wheel black.

I used this code which I wrote to turn the wheel which it does just fine.
Code:
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
    
    UITouch *touch = [[event allTouches] anyObject];
    CGPoint touchLocation = [touch locationInView:touch.view];
    
    tempF = atan2(touchLocation.y - theDisc.center.y, touchLocation.x - theDisc.center.x);
        
    theDisc.center = CGPointMake(theDisc.center.x, theDisc.center.y);
    theDisc.transform = CGAffineTransformMakeRotation(tempF);
    
    theValue.text = [NSString stringWithFormat:@"%f",tempF];
  
}

The problem is that when I take my finger off of the wheel and place it someplace else to turn the wheel the wheel's rotation snaps to the new CGPoint location. The interesting thing is that when it spans to the new location it is the right side of the disc (I know the right side of a circle)

Since this is new territory for me I thought I would check to see if there is anything that I am unaware of to adjust for this offset? Or a different approach to spinning the wheel. I don't want to continue down the wrong path if I am.
 

Attachments

  • wheel.jpg
    wheel.jpg
    29 KB · Views: 147

PhoneyDeveloper

macrumors 68040
Sep 2, 2008
3,114
93
transform is an animatable property. Change the transform inside an animation block.

Actually I haven't tried this myself so I'm not sure of the details but that's the way you make a smooth change between states. You might want to alter the duration of the animation based on the angular change. Also, you might want to try different animation curves to see how they affect the rotation.
 

North Bronson

macrumors 6502
Oct 31, 2007
395
1
San José
I am not sure if this is exactly the problem, but one thing I noticed is that:

Code:
 theDisc.transform = CGAffineTransformMakeRotation(tempF);

is not aggregating changes to your transformation -- each time you set the property you are setting it without respect to where it was before. For example:

Code:
CGAffineTransform transform = theDisc.transform;

CGAffineTransformRotate(transform, tempF);

theDisc.transform = transform;

will make your changes look like they are picking up from where the view was before. Is that one of the problems that you were having?

I have done this sort of thing with gesture recognizers and it's super-easy. I haven't looked through the actual touch-handling in a while.
 

larswik

macrumors 68000
Original poster
Sep 8, 2006
1,552
11
Thanks for the responses.

North Bronson, PhoneyDeveloper - It sounds like you are understanding the problem.
will make your changes look like they are picking up from where the view was before

Yes. Now it will only continue where it left off if I place my finger in the exact place I removed my finger from. IF I place it some place else and then start to drag my finger the UIImageView wil' 'snap' the rotation to the new location first and then rotate smoothly, instead of just something continuing where it stopped the last place the finger was removed from. Let me break down the code so I better understand it.

This code sets the CGPoint to where the finger is placed on the screen
Code:
CGPoint touchLocation = [touch locationInView:touch.view];

This code finds the offset of my touch for y and x axis and finds the angle which I add to a float instance variable.
Code:
 tempF = atan2(touchLocation.y - theDisc.center.y, touchLocation.x - theDisc.center.x);
This code set the center of my disc that it the rotation point of my UIImageView
Code:
theDisc.center = CGPointMake(theDisc.center.x, theDisc.center.y);
This code sets / updates the UIImageView transform property to rotate to the tempF float value as my finger drags on the screen.
Code:
theDisc.transform = CGAffineTransformMakeRotation(tempF);

I hope I said all that correctly. So as you said here
Code:
each time you set the property you are setting it without respect to where it was before

That would be an 'offset' from the last position of where the finger was removed from the screen to the new location.

So now your 3 lines of code, so I understand them. First looks like you are setting the property of theDisc.transform to transform.
Code:
CGAffineTransform transform = theDisc.transform;

The next part I don't get really? it takes 2 parameters the transform and the float value called tempF. Is this to calculate the offset from the last touch?

Code:
CGAffineTransformRotate(transform, tempF);

Lastly you are assigning transform back to theDisc.transform property
Code:
theDisc.transform = transform;
 

North Bronson

macrumors 6502
Oct 31, 2007
395
1
San José
Yes. Now it will only continue where it left off if I place my finger in the exact place I removed my finger from. IF I place it some place else and then start to drag my finger the UIImageView wil' 'snap' the rotation to the new location first and then rotate smoothly, instead of just something continuing where it stopped the last place the finger was removed from. Let me break down the code so I better understand it.

Now I understand what is happening.

Code:
theDisc.center = CGPointMake(theDisc.center.x, theDisc.center.y);

Does the application work exactly the same if you remove this line? What exactly are you doing with this line?

The issue seems to be that when you take the user's touch, you are finding the angle with which that point is displaced *from the origin*. The origin, in this case, is the positive X-axis.

What it sounds like you want to do is that if the user touches in any arbitrary point, and then drags their finger, you want to find the angle with which that point is displaced *relative to where their finger initially landed*.

Do you see how these two approaches are different? Do you see how you might design the second approach?
 

larswik

macrumors 68000
Original poster
Sep 8, 2006
1,552
11
Thanks North for your continuing help on this.

I did remove this code and it worked fine.
Code:
theDisc.center = CGPointMake(theDisc.center.x, theDisc.center.y);
That code was to identify the center of the UIImageView which it would rotate around. It appears I do not need that.

What it sounds like you want to do is that if the user touches in any arbitrary point, and then drags their finger, you want to find the angle with which that point is displaced *relative to where their finger initially landed*.
BINGO!
Do you see how you might design the second approach?

Needless to say this test did not work as I thought. I think the answer is in making the new touch point be equal to the last touch point. But I am unsure as to how to calculate and implement that offset. You mentioned that I am working with the X-axis, but would it not be both the X and Y Axis?

I kind of see what I need to do. But I was unsure since Objective - C is so large I was not sure if there was a method for the offset from the previous touch point to the new one.

I did try this last night by getting the last touched location
Code:
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{

    lastNumber = tempF;
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
    UITouch *touch = [[event allTouches] anyObject];
    CGPoint touchLocation = [touch locationInView:touch.view];
    
    tempF = atan2(touchLocation.y - theDisc.center.y, touchLocation.x - theDisc.center.x);
    
    newValue = tempF - lastNumber; // Attempt to use for offset

    theDisc.transform = CGAffineTransformMakeRotation (newValue);

    theValue.text = [NSString stringWithFormat:@"%f",newValue]; // displays the radian number
}
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.