★ TouchArcade needs your help. Click here to support us on Patreon.

Area of Movement in a game

04-20-2009, 03:26 PM
#1
Joined: Apr 2009
Posts: 4
Area of Movement in a game

Hello,

I've been trying to figure this out for days now, and I'm starting to get pretty frustrated. Right now, I have a game that moves a clicked button (a game piece) to anywhere you touch on the iPhone screen. I set it up so it only allows you to move withen a specific square area around the button. This works great. But now I want to change that square into a circle, and I can't for the life of me figure out how it's done.

I'm thinking that I need to find all the x and Y points withen the area of the circle, throw them into an array, and check them against the x and y points of where the user is touching. But I don't know how to set up an equation that figures out every point in a circle. I also don't think this would be very efficient, seeing as how the computer would have to check tens of thousands of points every time the user touches.

I've just hit a wall and I can't figure out where else to go from here. Any help at all would be appreciated.
04-20-2009, 04:17 PM
#3
Joined: Apr 2009
Posts: 4
Thanks!

That's exactly what I've been looking for! I guess I was too specific in my searches and just looking for obj-c code and general math equations. Thanks again!
04-20-2009, 04:39 PM
#4
You could also go a much much simplier route and create a circular path, and check if the point is in the path.

Code:
		CGMutablePathRef path = CGPathCreateMutable();
		
		if ( path )
		{
			CGPathAddArc(path, NULL, center.x, center.y, width, 0, 2*PI, 1);
			CGPathCloseSubpath(path); 	
			
			if ( CGPathContainsPoint(path, NULL, location, TRUE) )
				found = YES;
			
			CGPathRelease(path);
		}
04-24-2009, 12:29 PM
#5
Joined: Apr 2009
Posts: 4
Thanks for the tip, but I ended using this equation in an if else statement: (x-center_x)^2 + (y - center_y)^2 < radius^2.


I do have one other question. Now I want to draw a circle around a button. I was going to use the drawRect: method, but the I relized that this method can only be used in a view, not a view controller. So I made a new view, and I can draw a circle using a radius and x and y points that I manually type in, but I want the circle to grab the x, y and radius values from the view controller. The problem I'm having is getting the values from the view controller to the view.
04-24-2009, 01:51 PM
#6
Joined: Dec 2008
Posts: 675
wow...seriously? to check if it's inside a circle, just use the pythagorean theorem...

aa + bb = cc

Take the coordinates of the finger press, subtract the coordinates of the center of the circle.

User presses [20, 10]
Circle is at [5, 8] of radius 7

[20, 10] - [5, 8] = [15, 2]

15*15 + 2*2 = cc
225 + 4 = cc
sqrt(229) = 15.132....


EDIT: you're right, you don't need to do the sqrt(), compared against radius squared is "faster"

The user pressed at a distance of 15.132 from the center of the circle, whose radius is 7, so 15.132 > 7, so it's outside. Of course, make sure you abs() the value before the sqrt()...

As for drawing a circle, you tesselate it into line segments.

double i;
double last_x = 0;
double last_y = -abs(radius);
for (i = 0; i < tesselate_amount; i+=1.0) {
new_x = last_x + (sin(pi*(i/tesselate_amount)) * circumference);
new_y = last_y + (cos(pi*(i/tesselate_amount)) * circumference);
draw_line(last_x,last_y, new_x, new_y);
last_x = new_x;
last_y = new_y;
}

You can determine the amount to tesselate by by getting the circumference; tesselating by this number (rounded to an integer) should give acceptable results. thats Pi * (radius * 2) here. and note, this assumes your math library sin() and cos() are taking fractions of pi, I'm not sure what the default is on the iPhone. and it only works pretty for circles with a radius larger than 10 or so, but I hope the basic concept was illustrated. the code isn't 100% correct. the point is to show the idea. This is NOT an optimal algorithm either; there are like 100 of those out there. just search for "circle drawing algorithm." if you're using GL, you're going to want to make a list of line segments using a method like this anyway; if a framebuffer, there are as I said alternatives.

Last edited by writingsama; 04-24-2009 at 08:17 PM.
04-24-2009, 10:46 PM
#7
Quote:
Originally Posted by Redoctober11 View Post
Thanks for the tip, but I ended using this equation in an if else statement: (x-center_x)^2 + (y - center_y)^2 < radius^2.


I do have one other question. Now I want to draw a circle around a button. I was going to use the drawRect: method, but the I relized that this method can only be used in a view, not a view controller. So I made a new view, and I can draw a circle using a radius and x and y points that I manually type in, but I want the circle to grab the x, y and radius values from the view controller. The problem I'm having is getting the values from the view controller to the view.
Doesn't your view controller have access to the view? If so, you could assign the values to some variables in your view, and then tell the view to update. Then your drawRect could use those values.
04-24-2009, 10:55 PM
#8
Quote:
Originally Posted by writingsama View Post
As for drawing a circle, you tesselate it into line segments.
Very interesting, although I have to ask why wouldn't you just draw a path? I don't know about the OpenGL world, but in 2D land, paths are the easiest way to draw vector data.
04-25-2009, 12:43 AM
#9
Quote:
Originally Posted by Little White Bear Studios View Post
Very interesting, although I have to ask why wouldn't you just draw a path? I don't know about the OpenGL world, but in 2D land, paths are the easiest way to draw vector data.
OpenGL lives in the discrete hardware level world. In order to draw anything curvy, you have to break it down into strait lines.

Kevin Calderone - @bovinedragon
Trace 2 is Out!

Last edited by bovinedragon; 04-25-2009 at 12:59 AM.
04-25-2009, 01:20 AM
#10
Quote:
Originally Posted by bovinedragon View Post
OpenGL lives in the discrete hardware level world. In order to draw anything curvy, you have to break it down into strait lines.
Gotcha. Thanks for the clarification.