How to check if CGVector is nil? - ios

I'm curious how I would use an if statement to see if a CGVector variable is nil, as objects are done like so:
if (!object){
//Do This
}
But with CGVector it's not an object (As I know of). How would I determine if my CGVector variable is nil?

As you know it is a struct not an object
struct CGVector {
CGFloat dx;
CGFloat dy;
};
typedef struct CGVector CGVector;
Edit:
There is no such thing to check if a struct is nil.
Even if you check with dx==0 and dy==0, this is not correct at all an {0,0} is still a valid vector point.
For similar approach/question : How do I check if a CGPoint has been initialised?

Related

Cocos2d v3: What do you pass into drawPolyWithVerts?

I've looked at the documentation for CCDrawNode, and the method to draw a polygon is
- (void)drawPolyWithVerts:(const CGPoint *)verts
count:(NSUInteger)count
fillColor:(CCColor *)fill
borderWidth:(CGFloat)width
borderColor:(CCColor *)line
http://www.cocos2d-swift.org/docs/api/Classes/CCDrawNode.html#//api/name/drawPolyWithVerts:count:fillColor:borderWidth:borderColor:
I'm confused by the (const CGPoint *)certs parameter. I thought a CGPoint was a struct, and so didn't need a pointer.
Also, I'm a assuming you'll need a series of points to construct a polygon, and I thought CGPoint just represented one point.
I've checked through the Cocos 2d Programming Guide and I couldn't see anything about this method in there.
https://www.makegameswith.us/docs/#!/cocos2d/1.1/overview
I've also check out CGGeometry Reference on Apple's site, but couldn't see anything there.
https://developer.apple.com/library/mac/documentation/graphicsimaging/reference/CGGeometry/Reference/reference.html#//apple_ref/c/func/CGPointMake
I think I'm missing something fairly basic about C / Objective-C, but I can't figure it out.
My Question
What do i pass into drawPolyWithVerts:(const CGPoint *)verts, and how do I make it?
As user667648 pointed out in the comments, the answer is to pass a C array of CGPoints into the method.
Example:
CGPoint polygon[4] =
{
CGPointMake(0, 0),
CGPointMake(2, 0),
CGPointMake(0, 7),
CGPointMake(2, 25)
};

How to define array of CGPoints within a struct definition?

I want to do this:
typedef struct
{
CGPoint vertices[];
NSUInteger vertexCount;
} Polygon;
But it says Field has incomplete type CGPoint [].
You need to do one of two things:
Declare the array to be a fixed size (probably not what you want)
Make it a pointer. But then you need to properly malloc and free the array as needed.
A better choice is to not use a struct and instead create a full class. Then you can add methods and properties as well as make memory management much easier. You are working in Objective-C. Take advantage of the Object Oriented aspects of the language. Add a method to calculate the circumference and area, etc. Put the logic where it belongs.
Set array size CGPoint vertices[count];
Don't you want a unique name for each element of your struct anyway? If you just want a bunch of CGPoint's in a numerical order, with the ability to count how many of them there are you'd be much better served by shoving them in an NSArray or NSMutableArray (stored as NSValue's of course)
The whole point of a struct would be to have easy access to the values by a descriptive name, ie:
typedef struct {
CGPoint helpfulAndDescriptiveNameOne;
CGPoint helpfulAndDescriptiveNameTwoWhichIsDifferentThanTheOtherName;
etc...
NSUInteger vertexCount;
}
For example, a CGRect is just a struct composed of four different CGFloats, each of which is descriptively and helpfully named:
typedef {
CGFloat x;
CGFloat y;
CGFloat width;
CGFloat height;
} CGRect;

Why can't access view.center.x / y

I'm just curious why can't you access view.center.x or view.center.y but you can access view.center and change it.
I wanted to write this code:
imgView_.center = scrollView_.center;
if (imgView_.frame.origin.x < 0)
imgView_.center = CGPointMake(imgView_.center.x + (imgView_.frame.size.width - self.view.frame.size.width) / 2, imgView_.center.y);
if (imgView_.frame.origin.y < 0)
imgView_.center = CGPointMake(imgView_.center.x, imgView_.center.y + (imgView_.frame.size.height - self.view.frame.size.height) / 2);
As:
imgView_.center = scrollView_.center;
if (imgView_.frame.origin.x < 0)
imgView_.center.x = imgView_.center.x + (imgView_.frame.size.width - self.view.frame.size.width) / 2;
if (imgView_.frame.origin.y < 0)
imgView_.center.y = imgView_.center.y + (imgView_.frame.size.height - self.view.frame.size.height) / 2;
I find the second way a lot more elegant, but I can't access the x and y, so I thought I'd ask if anyone knows what's Apple's reason for blocking it.
See center property defined in UIView's UIViewGeometry category as below
#property(nonatomic) CGPoint center;
By declaration of center property, we have getter & setter methods for center property. it means we have setter & getter method for structure not for the values inside structure.
and Center is a CGPoint structure variable that has two CGFloat value x and y.
that's by we can't set directly x and y values in center property. it is similar to Frame property.
The UIView property center is a CGPoint which is of type struct and not an ObjectiveC class.
Even though writing this
view.center.x = view.center.x +10;
looks similar to
CGPoint center = view.center;
center.x = center.x +10;
view.center = center;
they are different things.
According to the compiler view.center is a method call [view center] and center.x is accessing the public ivar of the struct CGPoint. If you write all of this in a single line
view.center.x = view.center.x +10;
compiler is unable to resolve this and throws an error Expression is not assignable. Reason is view.center.x is further resolved as function call,
objc_msgSend(view, #selector(center))
Now you are trying to modify the return value of a C function as below
objc_msgSend(view, #selector(center)).x = 20 //(Some value on RHS)
which is not meaningful as the function return value isn't stored anywhere, hence the resulting expression is not assignable.
For more information read through this answer.
Hope that helps!
In the fragment imgView_.center.x the .center is a property access while the .x is a field access. The type of the property is CGPoint, which is a structure type which is passed by value.
If you have a variable of type CGPoint you can directly assign to individual fields, e.g.:
CGPoint myPoint;
myPoint.x = 3;
However when passing a CGPoint value to a function or method you cannot pass just one of it's fields - it makes no sense. E.g. if you have the function:
void doSomething(CGPoint aPoint);
you could pass myPoint:
doSomething(myPoint);
but there is no way to say "just pass the x field" - what would that even mean? The function is expecting a CGPoint, what would passing it one coordinate mean?
When you put the fragment imgView_.center on the left hand side of an assignment you are just using a shorthand for calling a method. E.g.:
imgView_.center = myPoint; <=> [imgView_ setCenter:myPoint];
and just like with the function above there is no way to say "just pass the x field".
The key point is a property access is not a variable access, even though it is often thought of as one, but a function/method call; so you can't assign to the individual fields of a property of structure type.
On the right hand side accessing a field of a property is fine. E.g. on the rhs imgView_.center translates to [imgView_ center] - which returns a CGPoint value, and you can access a field of structure value, so on the rhs imgView_.center.x translates to [imgView_ center].x and all is OK. But note that in both cases (setCenter: and center methods) the methods themselves take/return a complete CGPoint.
HTH.

Cant check if CGPoint is not equal CGPointZero

I have a CGPoint declared in a UIView class, in my viewController I try to check if that CGPoint is not equal to CGPointZero, but I get this error:Invalid operands to binary expression ('CGPoint' (aka 'struct CGPoint') and 'CGPoint')
This is the if-statement:
if (joystick.velocity != CGPointZero)
The error points to the != and I dont know why it gives me an error.
joystick is the UIView class, CGPoint velocity is declared like this:
#property(nonatomic) CGPoint velocity;
Try this:
if (!CGPointEqualToPoint(joystick.velocity, CGPointZero))
Explanation: A CGPoint is actually a struct. The binary operand ("==" or "!=") it's only used to compare primitive values, usually useful to compare pointers, which in fact are integers representing a memory position.
As you have a struct, and not a reference to something, you would have to compare each value inside your struct, but fortunately apple already implemented a macro that performs this for you in the case of CGPoint.
If you are curious, you can command-click the macro above and see the implementation:
__CGPointEqualToPoint(CGPoint point1, CGPoint point2)
{
return point1.x == point2.x && point1.y == point2.y;
}

i want to make an if statement, so if some images are on a specific coordinate, there will be a sound

i know how to make playin a sound but i don't know how to use the 'CGPointisEqualtoPoint' method. How do i use that or are there other ways?
-(void)beloning {
if (//CGPointisEqualtoPoint?!
) {
//play sound
}
From the docs:
Returns whether two points are equal.
bool CGPointEqualToPoint (
CGPoint point1,
CGPoint point2
);
But you may be better off with this one:
CGRectContainsPoint
Returns whether a rectangle contains a specified point.
bool CGRectContainsPoint (
CGRect rect,
CGPoint point
);
So now you can check if the rect of your image contains the coordinate point you care about

Resources