开发者

Pointers, Invalid Operands to Binary, and Noobs

[Edit: Rectangle definition added at bottom.] [Edit2: XYPoint interface added at bottom.]

I'm working on a method that checks if two rectangles overlap. (Yeah, I'm in Kochan's Programming in Objective-C, doing the exercises, and I am painfully new at this.) When I compile this, the error message is: "Invalid operands to binary +". I get it on the first if statement and on the if-else that follows it.

I think I have an issue with pointers, but Kochan doesn't talk about this much.

And, if I take out these lines, the rest of the method works just fine. And the relevant variables are all floating type.

Help?

Also, any other thoughts on the method would be totally welcome. (Like, how do I make lines of code not go out so long. Like I said, painfully new at this.)

-(void) overlap: (Rectangle *)r2
{

overlapRectangle = [[Rectangle alloc] init];
leftRectangle = [[Rectangle alloc] init];
rightRectangle = [[Rectangle alloc] init];
lowerRectangle = [[Rectangle alloc] init];
upperRectangle = [[Rectangle alloc] init];

BOOL xIntersect = NO;
BOOL yIntersect = NO;


//  Test to see if the Rectangle contains, or is equal to, Rectangle b

if (origin.x <= r2.origin.x && origin.y <= r2.origin.y && (origin.x + width) >= (r2.origin + r2.width) && (origin.y + height) >= (r2.origin.y + r2.height) ) 
{
    overlapRectangle = r2;
}

//  Test to see if Retangle b contains, or is equal to, the Rectangle

else if (开发者_开发问答origin.x >= r2.origin.x && origin.y >= r2.origin.y && origin.x + width <= r2.origin + r2.width && origin.y + height <= r2.origin.y + r2.height ) 
{
    overlapRectangle = self;
}

//  I should add tests for triangles overlapping on three 
//  sides or overlapping  on two sides, but I'm not going 
//  to right now. Just learning objects and methods.


//  Test to see if rectangles overlap on the x-axis 
//  Current is an if, because I wanted to run the code below
//  to see if it worked, and it did. 

if (origin.x <= r2.origin.x)
{
    leftRectangle = self;
    rightRectangle = r2;
}
else 
{
    rightRectangle = self;
    leftRectangle = r2;
}

if (rightRectangle.origin.x + rightRectangle.width > leftRectangle.origin.x) 
{
    xIntersect = YES;
}



//  Test to see if rectangles overlap on the y-axis

if (origin.y <= r2.origin.y)
{
    lowerRectangle = self;
    upperRectangle = r2;
}
else 
{
    lowerRectangle = self;
    upperRectangle = r2;
}

if (lowerRectangle.origin.y + lowerRectangle.height > upperRectangle.origin.y) 
{
    yIntersect = YES;
}



//  If retangles overlap on both the x-axis and y-axis, 
//  determination of overlapping rectangle's origin, height, and width
//  and display same.

if (xIntersect == YES && yIntersect == YES) 
{
    overlapRectangle.origin.y = upperRectangle.origin.y;
    overlapRectangle.origin.x = rightRectangle.origin.x;
    overlapRectangle.height = lowerRectangle.height - (upperRectangle.origin.y - lowerRectangle.origin.y);
    overlapRectangle.width = leftRectangle.width - (rightRectangle.origin.x - leftRectangle.origin.x);


    NSLog (@"Your rectangles overlap.");
    NSLog (@"Rectangle: w = %g, h = %g", overlapRectangle.width, overlapRectangle.height);
    NSLog (@"Area = %g, Perimeter = %g", [overlapRectangle area], [overlapRectangle perimeter]);
    NSLog (@"Origin at (%g, %g)", overlapRectangle.origin.x, overlapRectangle.origin.y);
}

else 
{
    NSLog (@"Your rectangles do not overlap.");
}



[overlapRectangle autorelease];
[leftRectangle autorelease];
[rightRectangle autorelease];
[lowerRectangle autorelease];
[upperRectangle autorelease];

}

Rectangle Definition:

// Interface, Rectangle Class

@interface Rectangle : NSObject

{
    float width;
    float height;
    XYPoint *origin;

    // For overlapping calculations

    Rectangle *overlapRectangle;
    Rectangle *leftRectangle; 
    Rectangle *rightRectangle; 
    Rectangle *lowerRectangle; 
    Rectangle *upperRectangle; 
}

@property float width, height;

-(XYPoint *) origin;
-(void) setOrigin: (XYPoint *) pt;
-(void) setWidth: (float) w andHeight: (float) h;
-(float) area;        
-(float) perimeter;   
-(void) print;
-(void) translate;
-(void) overlap: (Rectangle *)r2;
-(void) draw;


@end

XYPoint interface:

#import <Foundation/Foundation.h>

@interface XYPoint : NSObject
{
    float x;
    float y;
}

@property float x, y;

-(void) setX: (float) xVal andY: (float) yVal;

@end


You've just got what is probably a typo:

// Test to see if the Rectangle contains, or is equal to, 
// Rectangle b

if (origin.x <= r2.origin.x && origin.y <= r2.origin.y && 
   (origin.x + width) >= (r2.origin + r2.width) && 
                         //^^^This is trying to add an XYPoint,
                         // which is an object, to a float.
   (origin.y + height) >= (r2.origin.y + r2.height) ) 
{
   overlapRectangle = r2;
}

// Test to see if Rectangle b contains, or is equal to, 
// the Rectangle
else if (origin.x >= r2.origin.x && origin.y >= r2.origin.y && 
         origin.x + width <= r2.origin + r2.width && 
                            //^^^Same thing.
         origin.y + height <= r2.origin.y + r2.height ) 
{
...

The compiler should have told you what the types were that you were asking to be added:

error: invalid operands to binary + (have 'struct XYPoint *' and 'float')

that's the key. You just need to change the r2.origin to r2.origin.x so that you're adding two floats.

As for the length of the lines, there's two things you can do. You can move each segment of the conditions to different lines as I've done, but it would probably be best to create a couple of methods for Rectangle that will do the tests for you. This will make the code more readable, so when you come back to it in six months and the line reads:

if( [self containsRectangle:r2] || [self isEqualToRectangle:r2] ){

you'll know what's going on right away. Here's some suggestions for that:

- (BOOL)containsRectangle:(Rectangle *)otherRect {
    BOOL originBelow = ((origin.x <= otherRect.origin.x) && 
                        (origin.y <= otherRect.origin.y));
    float maxX = origin.x + width;
    float otherMaxX = otherRect.origin.x + otherRect.width;
    BOOL maxXGreater = maxX >= otherMaxX;
    Bfloat maxY = origin.y + height;
    float otherMaxY = otherRect.origin.y + otherRect.height;
    BOOL maxYGreater = maxY >= otherMaxY;
    return originBelow && maxXGreater && maxYGreater;
}

- (BOOL)isEqualToRectangle:(Rectangle *)otherRect {
    BOOL sizeEqual = ((width == otherRect.width) && 
                      (height == otherRect.height));
    return sizeEqual && [origin isEqualToXYPoint:otherRect.origin];

}

Note: I didn't test these, just pasted them together from the conditions of your ifs, so double-check them before you use them. I did fix the typo, though.

Notice that I also made up a method on XYPoint here, isEqualToXYPoint:; you can implement that as well, to return a BOOL if the x and y of both XYPoints are equal.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜