views:

386

answers:

2

Hi there,

Still an iphone dev starter but trying.

I would like to have the user touch the screen at which point a pin (dot) will be placed on the view.

I have accomplished this (yey) but i would like to have snap to grip effect, and can not come up with a solution. This is how i am placing that dot:

CGPoint drawPoint = CGPointMake(lastTouch.x - horizontalOffset, lastTouch.y - >verticalOffset); [drawImage drawAtPoint:drawPoint]; //Tell the image to draw itself

I have a grid as a background on a Viewcontroller, overlapping that grid i have a UIView with custom drawing that displays a pin every time the user touches the screen.

(and for some reason the dot already appears before the user touches... all though that is another query that i am looking into at the moment)

So snap to grid effect. Any ideas?

+1  A: 

You'll need some kind of data structure that represents the grid in your view controller. Maybe it'll contain an array of coordinates, each representing where the vertical and horizontal lines cross.

Then when you touch the view, you compare the y value with all the y values in your grid structure, and choose the one that is closest. Same for the x value. That should give the idea of a snap to grid.

Jasarien
The idea i was kicking about was to round the value of the touch x and y coordinates to the nearest 5, could this also produce the desired effect?
Tom G
It depends how your rounding logic will work.Many people forget that when you cast a float to an int, rounding does not occur - the value is truncated, so 12.6 will become 12.You could use nearbyint() (declared in math.h) to round your numbers.
Jasarien
nearbyint() would also make my solution neater (shows how much C programming I've done lately... I had no idea that existed!)
Sixten Otto
Thanks for both of your collaborated effort in finding a solution for me. Otto you say that nearbyInt makes your solution neater... how could it be implemented into your solution? i think im missing something! And thanks again :)
Tom G
In Sixten Otto's solution, you could possible replace the usage of floor() and the calculations done for the parameters with nearbyint()...
Jasarien
+1  A: 

Assuming that your approach is to let the user tap, and then put the pin at the closest grid intersection, this is basically just a rounding problem.

// assume these constants
// kVGridOffset, kHGridOffset: the difference between the origin of the view
//   and the origin of the grid
// kVGridSpacing, kHGridSpacing: the size of the grid itself

// set initial coordinates from touch
CGPoint drawPoint = CGPointMake(lastTouch.x - horizontalOffset, lastTouch.y - verticalOffset);

// remove the offset, round to nearest increment of spacing, and return offset
drawPoint.x = floor((drawPoint.x - kHGridOffset) / kHGridSpacing + 0.5) * kHGridSpacing + kHGridOffset;
drawPoint.y = floor((drawPoint.y - kVGridOffset) / kVGridSpacing + 0.5) * kVGridSpacing + kVGridOffset;

// draw the image
[drawImage drawAtPoint:drawPoint];

EDIT: with the availability of nearbyint() for rounding, things can be a little neater:

drawPoint.x = nearbyint((drawPoint.x - kHGridOffset) / kHGridSpacing) * kHGridSpacing + kHGridOffset;
drawPoint.y = nearbyint((drawPoint.y - kVGridOffset) / kVGridSpacing) * kVGridSpacing + kVGridOffset;
Sixten Otto
This is a better solution than mine ;)
Jasarien