How to recognize if CGPoint is included in shape? - objective-c

I'm a beginner in quartz.
I'm wonderring a way that recognize if CGPoint is included in shape.
Please give me a help of Expert.
Follow is concept diagram.
In above three case,
Result I want is YES, Because three RED CGPoint is included in shape.
It is possible like follow way?
CGPoint RedPoint1 = {200,100};
CGPoint RedPoint2 = {200,200};
CGPoint RedPoint3 = {350,300};
BOOL includeRect;
includeRect = CGRectContainsPoint(RectCase, RedPoint1);
BOOL includeCircle;
includeCircle = CG ? ContainsPoint(CircleCase, RedPoint2)
BOOL includeBoldLine;
includeBoldLine = CG ? ContainsPoint(BoldLineCase, RedPoint3);

The ease of this all depends on how your shapes are defined.
If you have these as CGPathRefs or NSBezierPaths there is a containsPoint: method you could use.
If these are CGRects that have a transform applied to them, you can use the CGAffineTransformPoint methods to move the point into the same coordinate space and then use CGRectContainsPoint

Related

Stopping objects when collision occurs in sprite kit

I'm building a game using Apple's SpriteKit and SKPhysics that use squares that move around on the screen based on user input. I'm having an issue with collisions in that the squares will move out of place if they collide. For example, if all the blocks move to the right, any blocks that are on the same "row" need stack next to each other and not overlap or move position vertically. As of now, they will change their vertical direction. Here is my code:
self.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:self.size];
self.physicsBody.dynamic = YES;
self.physicsBody.allowsRotation = NO;
self.physicsBody.affectedByGravity = NO;
Are there any other settings that I'm missing?
The issue could be coming from your collisionBitMask category. In order to solve that, you need to first create categories for the blocks' physics bodies as follows:
struct PhysicsCategory {
static let None : UInt32 = 0
static let All : UInt32 = UInt32.max
static let block : UInt32 = 0b1
}
then set the blocks' settings to the following.
block.physicsBody?.categoryBitMask = PhysicsCategory.block
block.physicsBody?.collisionBitMask = PhysicsCategory.None
This should prevent the collision calculations from being automatically carried out by spritekit.
If you're moving your sprites via user inputs(i.g. SKAction's moveTo), then you're most likely not using physics to move your sprite. In this case, you should make the velocity of the physicsbody to 0- this will make the sprite completely rigid when it comes in contact with another object.
Try:
self.physicsBody.velocity = CGVectorMake(0, 0);
You should put this code inside your update loop.

Get all annotations around another annotation

I'm trying to get all annotations around another annotation on a specified area, but I can't figure how to do it. Now I'm trying with:
MKMapRect mapRect = MKMapRectMake(annotation.coordinate.longitude, annotation.coordinate.latitude, 10.0, 10.0);
NSSet *nearbyAnnotations = [map annotationsInMapRect:mapRect];
but nearbyAnnotations is empty. I tried by swapping longitude with latitude and also with bigger numbers for the 3rd and 4th parameters, but still no result. How I should do this?
An MKMapRect uses MKMapPoint units which are not the same thing as CLLocationDegrees.
The MKMapRectMake function needs the top-left MKMapPoint and then the width and height (again in MKMapPoint units).
Basically, you need to use the the MKMapPointForCoordinate function to help you do this conversion from degrees to MKMapPoint units.
First, you could construct an MKCoordinateRegion and then convert it to an MKMapRect.
For example:
//create a region 10km around the annotation...
MKCoordinateRegion mapRegion = MKCoordinateRegionMakeWithDistance
(annotation.coordinate, 10000, 10000);
//convert the MKCoordinateRegion to an MKMapRect...
MKMapRect mapRect = [self mapRectForCoordinateRegion:mapRegion];
The mapRectForCoordinateRegion method is something you have to write.
For an example of one way to write it, see this answer:
How to make the union between two MKCoordinateRegion
By the way, note that in your case, annotationsInMapRect will include the annotation that you are searching around (since you are using it as the center).

How to generate CGPoint-Array out of UIBezierPath (to touch-slide object along given path) [duplicate]

This question already has an answer here:
Drag UIView around Shape Comprised of CGMutablePaths
(1 answer)
Closed 6 years ago.
I have a UIBezierPath (curved like an '8', with only 4 points in it) and I need to make some kind of CGPoint-Array out of it. Any ideas? thanx!
edit:
I have my bezier initlialized like that
-(void) initBezier
{
theBezierPath = [UIBezierPath bezierPath];
[theBezierPath moveToPoint:P(211.00, 31.00)];
[theBezierPath addCurveToPoint:P(870.00, 191.00) controlPoint1:P(432.00, -11.00) controlPoint2:P(593.00, 209.00)];
[theBezierPath addCurveToPoint:P(731.00, 28.00) controlPoint1:P(1061.95, 178.53) controlPoint2:P(944.69, 5.78)];
[theBezierPath addCurveToPoint:P(189.00, 190.00) controlPoint1:P(529.00, 49.00) controlPoint2:P(450.00, 189.00)];
[theBezierPath addCurveToPoint:P(211.00, 31.00) controlPoint1:P(-33.01, 190.85) controlPoint2:P(71.00, 37.00)];
}
and I animate an object on it with
anim = [CAKeyframeAnimation animationWithKeyPath:#"emitterPosition"];
anim.path = theBezierPath.CGPath;
anim.calculationMode = kCAAnimationCubicPaced;
anim.repeatCount = HUGE_VALF;
anim.duration = tme;
I want to animate the object on the path pixel by pixel (via touch-position). I want the object to "snap" a given coordinate of a touch to the nearest point on the curve so it touch-slides the object along the path.
Use the CGPathApply() function to iterate over all elements in a path. As one of the arguments, you have to specify a pointer to a function that will then be called for each path element. The path element data structure (of type CGPathElement) then contains the point(s) that describe it.
Use NSValue as a wrapper to add the points to an NSMutableArray.
Neither UIBezierPath nor CGPath provide a way to evaluate the points along an arbitrary Bezier path, or a way to find the nearest point on the path. You'll have to write that code yourself.
Fortunately, this is a very well-studied topic. This tutorial has a lot of useful information, to get you started. You're interested in "cubic" or "third-order" Bezier curves.

What does 'ccp' signify in Cocos2d/Objective-C?

I keep seeing a phrase like this:
//Example one
CGPoint backgroundScrollVel = ccp(-1000, 0);
//Another Example
// 3) Determine relative movement speeds for space dust and background
CGPoint dustSpeed = ccp(0.1, 0.1);
CGPoint bgSpeed = ccp(0.05, 0.05);
So what does ccp signify? Is it a property of CCParallax?
Like Stephen said, it's just a macro for CGPointMake(x, y), but if you particularly mean what does "ccp" stand for it's most likely c o c os2d p oint
Are you using Cocos2D? If so, ccp is just a C macro to create a point. As in:
#define ccp(__X__,__Y__) CGPointMake(__X__,__Y__)
It's just a convenience constructor for the CGPoint type.
Pretty sure it's just a macro to CGPointMake, but don't quote me on that.
It's a shorthand macro that maps to CGPointMake(x, y).
Basically it's a way to create CGPoints with less typing.
Nope no difference except CGPointMake is harder to type:
#define ccp(__X__, __Y__) CGPointMake(__X__,__Y__)
Found here:
http://www.cocos2d-iphone.org/api-ref/0.99.3/_c_g_point_extension_8h_source.html

setting and using obj-c CGPoint, CGRect, and others

I have three questions surrounding what I think is the topic of structs in obj-c
1) Why is it that I often (or always) cannot take a member var that is a CGPoint or a CGRect and set the values one by one? I find I have to do:
CGPoint point;
point.x = someValue;
point.y = someOtherValue;
obj.myPoint = point;
instead of simply obj.myPoint.x = someValue etc.
2) Is this behavior that is consistent across all structs in obj-c?
3) Is there an easy way to add two CGPoints? It seems like there should already be, but I couldn't find one. I thought it'd be cumbersome if I'd have to use a temporary CGPoint to accumulate values between two CGPoints before setting the dest var to the temp var (because of not being able to just do pointA.x += pointB.x (same for y).
1) From #sb in an answer to Cocoa Objective-c Property C structure assign fails
That won't accomplish anything, because [t member] returns a struct, which is an "r-value", ie. a value that's only valid for use on the right-hand side of an assignment. It has a value, but it's meaningless to try to change that value.
Basically you just have to live with the fact that you can't set the fields of struct directly when returned from a function.
2) Yes
3) Unfortunately I don't think there is a built-in convenience method for adding two CGPoint. If you find your self doing this frequently you can make your own:
CGPoint CGPointAdd(CGPoint p1, CGPoint p2)
{
return CGPointMake(p1.x + p2.x, p1.y + p2.y);
}
and then use it like:
obj.pointA = CGPointAdd(obj.pointA, pointB);
not as elegant as obj.pointA.X += ... but sometimes life isn't fair.
This is perfectly normal. The 'obj' owns that var and has getters and setters, you can not modify parts of that variable.
The best thing to do is copy the struct and modify whatever you need.
Also note you can use the CGPointMake(x, y) function (and the same for all CG structs), which is much easier.
To update this is easiest:
CGPoint point = obj.myPoint;
point.x += 10.0f;
obj.myPoint = point;
Obj-C 2.0 hides the getters and setters which looks like this:
CGPoint point = [obj myPoint];
point.x += 10.0f;
[obj setMyPoint:point];