返回2个矩形交集的方法

时间:2012-10-02 22:22:54

标签: objective-c

我是编程和Objective-c的新手(所以我可以离开这里)并且我正在通过目标c第4版教科书中的编程工作,并且已经陷入其中一个练习中。

有人能说出下面这个方法有什么问题吗?在我的程序中有一个矩形类,它有方法来设置它的宽度,高度和它的原点(来自一个名为XYPoint的类)。

containsPoint方法检查矩形的原点是否在另一个矩形内。当我测试这个方法时,即使矩形确实包含该点,它也总是返回'否'。

intersects方法采用矩形作为参数(aRect)并在if语句中使用containsPoint方法检查它是否与接收器相交,如果是,则返回一个矩形,其原点位于相交处,且宽度正确和身高。

-(BOOL) containsPoint:(XYPoint *) aPoint
{
//create two variables to be used within the method 
float upperX, upperY;

//assign them values, add the height and width to the origin values to range which the XYPoint must fall into 
upperX = origin.x + height;
upperY = origin.y + width;    

//if the value of aPoint's x and y points fall between the object's origin and the upperX or upperY values then the rectangle must contain the XYPoint and a message is sent to NSLog

if ((aPoint.x >= origin.x) && (aPoint.x <= upperX) && (aPoint.y >= origin.y) && (aPoint.y <= upperY) ) 
{
    NSLog(@"Contains point");
    return YES;

}

else
{
    NSLog(@"Does not contain point");
    return NO;

}


}


-(Rectangle *) intersects: (Rectangle *) aRect
{
//create new  variables, Rectangle and XYPoint objects to use within the method
Rectangle *intersectRect = [[Rectangle alloc] init];
XYPoint *aRectOrigin = [[XYPoint alloc] init];
float wi, he;   //create some variables

if ([self containsPoint:aRect.origin]) {     //send the containsPoint method to self to test if the intersect
    [aRectOrigin setX:aRect.origin.x andY:origin.y];   //set the origin for the new intersecting rectangle
    [intersectRect setOrigin:aRectOrigin];
    wi = (origin.x + width) - aRect.origin.x;   //determine the width of the intersecting rectangle
    he = (origin.y + height) - aRect.origin.y;  //determine the height of the intersecting rectangle
    [intersectRect setWidth:wi andHeight:he];   //set the rectangle's width and height

    NSLog(@"The shapes intersect");
    return intersectRect;
}

//if the test returned NO then send back these values
else {
    [intersectRect setWidth:0. andHeight:0.];
    [aRectOrigin setX:0. andY:0.];
    [intersectRect setOrigin:aRectOrigin];

    NSLog(@"The shapes do not intersect");
    return intersectRect;
}
}

当我使用以下代码进行测试时

    int main (int argc, char * argv [])
{
    @autoreleasepool {

        Rectangle *aRectangle = [[Rectangle alloc] init];
        Rectangle *bRectangle = [[Rectangle alloc] init];
        Rectangle *intersectRectangle = [[Rectangle alloc] init];
        XYPoint *aPoint = [[XYPoint alloc] init];
        XYPoint *bPoint = [[XYPoint alloc] init];

        [aPoint setX:200.0 andY:420.00];
        [bPoint setX:400.0 andY:300.0];

        [aRectangle setWidth:250.00 andHeight:75.00];
        [aRectangle setOrigin:aPoint];

        [bRectangle setWidth:100.00 andHeight:180.00];
        [bRectangle setOrigin:bPoint];    

        printf("Are the points within the rectangle's borders?  ");  
        [aRectangle containsPoint: bPoint] ? printf("YES\n") : printf("NO\n");  
        intersectRectangle = [aRectangle intersects:bRectangle];

}
    return 0;   
}

我得到以下输出

Contains point  
The origin is at 0.000000,0.000000, the width is 250.000000 and the height is 75.000000  

4 个答案:

答案 0 :(得分:3)

以下是代码(我目前正在使用“Stephen Kochan的Objective-C第5版编程”)并根据您的变量和语法判断,看起来你也是。

    // Use Floats for XYPoint and Rectangular exercise 8.4 on pg. 166

import“Rectangle.h”

导入“XYPoint.h”

int main(int argc,const char * argv []) {

@autoreleasepool {
    Rectangle *myRect = [[Rectangle alloc] init];
    Rectangle *yourRect = [[Rectangle alloc] init];
    XYPoint   *myPoint = [[XYPoint alloc] init];
    XYPoint   *yourPoint = [[XYPoint alloc] init];

    // For first Rectangle set w, h, origin
    [myRect setWidth:250 andHeight:75];
    [myPoint setX:200 andY:420];
    myRect.origin = myPoint;

    // Second Rectangle
    [yourRect setWidth:100 andHeight:180];
    [yourPoint setX:400 andY:300];
    yourRect.origin = yourPoint;

    // Find Points of intersection
    float x1, x2, y1, y2;
    x1 = MAX(myRect.origin.x, yourRect.origin.x);
    x2 = MIN(myRect.origin.x + myRect.width, yourRect.origin.x + yourRect.width);
    y1 = MAX(myRect.origin.y, yourRect.origin.y);
    y2 = MIN(myRect.origin.y + myRect.height, yourRect.origin.y + yourRect.height);

    // Make Intersecting Rectangle
    Rectangle *intrRect = [[Rectangle alloc] init];
    [intrRect setWidth: abs(x2 - x1) andHeight: abs(y2 - y1)];

    // Print Intersecting Rectangle's infor for a check
    NSLog(@"Width = %g, Height = %g, Bottom point = (%g, %g), Top point = (%g, %g)", intrRect.width, intrRect.height, x1, y1, x2, y2);

}
return 0;

}

答案 1 :(得分:2)

为什么不使用包含的函数来确定交集和/或包含:

if (CGRectContainsPoint(CGRect rect, CGPoint point))
{
    // Contains point...
}

if (CGRectIntersectsRect(CGRect rectOne, CGRect rectTwo))
{
    // Rects intersect...
}

if (CGRectContainsRect(CGRect rectOne, CGRect rectTwo))
{
    // RectOne contains rectTwo...
}

答案 2 :(得分:0)

你在几何和Objective-C中都犯了很多错误,但这就是你学习的方法!

  1. 几何:对于两个矩形相交,一个原点不需要在另一个的区域内。您的两个矩形相交,但交叉点不包含任何原点。因此,containsPoint:将返回NO
  2. 您只能在创建对象时分配对象,而不是在您调用的代码创建并返回它们时。因此,您在Rectangle *intersectRectangle = [[Rectangle alloc] init];中的分配会创建一个对象,然后您的作业intersectRectangle = [aRectangle intersects:bRectangle];
  3. 会将其丢弃
  4. 对于像这样的简单类,通常会创建设置属性的init方法,因为创建对象而不设置属性是没有用的。例如。对于XYPoint课程,您通常会使用初始化方法- (id) initWithX:(float)x andY:(float)y;。然后,您可以使用[[XYPoint alloc] initWithX:200.0 andY:420.0]]一次创建和初始化。
  5. 在进行实验时,这并不重要,但在实际代码中,对于具有值语义的非常简单和小的类 - 这意味着它们的行为与整数和浮点数非常相似 - 通常使用结构(struct)和函数,而不是对象和方法。查找NSRectNSPoint的定义作为示例。
  6. HTH

答案 3 :(得分:0)

 //intersect function
 -(Rectangle *)intersect:(Rectangle *)secondRec
 {
 int intersectRectWidth;
 int intersectRectHeight;
 int intersectRectOriginX;
 int intersectRectOriginY;
 Rectangle * intersectRec =[[Rectangle alloc]init];
 intersectRectOriginX = MAX(self.origin.x,secondRec.origin.x);

 intersectRectOriginY = MAX((self.origin.y) , (secondRec.origin.y));
int myWidth=self.width+self.origin.x;
int secondRecWidth=secondRec.width+secondRec.origin.x;
int tempWidth=secondRecWidth - myWidth;
if (tempWidth > 0) {
    intersectRectWidth=secondRec.width - tempWidth;
}
else
{
    tempWidth=abs(tempWidth);
    intersectRectWidth = self.width - tempWidth;
}

//height
int myHeight=self.height+self.origin.y;
int secondRecHeight=secondRec.height +secondRec.origin.y;
int tempHeight=secondRecHeight - myHeight;
if (tempHeight > 0) {
    intersectRectHeight=secondRec.height - tempHeight;
}
else
{
    tempHeight=abs(tempHeight);
    intersectRectHeight = self.height - tempHeight;
}
intersectRec.width=intersectRectWidth;
intersectRec.height=intersectRectHeight;
XYPoint * intersectOrigin =[[XYPoint alloc]init];
[intersectOrigin setX:intersectRectOriginX andY:intersectRectOriginY];
[intersectRec setOrigin:intersectOrigin];
return intersectRec;

}

    //main
    XYPoint * org1=[[XYPoint alloc]init];
    XYPoint * org2=[[XYPoint alloc]init];
    Rectangle * firstRec=[[Rectangle alloc]init];
    Rectangle * secondRec=[[Rectangle alloc]init];
    Rectangle * intersectRec=[[Rectangle alloc]init];
    [org1 setX:400 andY:300];
    [org2 setX:200 andY:420];
    [firstRec setOrigin:org1];
    [secondRec setOrigin:org2];
    [firstRec setWidth:100 andHeight:180];
    [secondRec setWidth:250 andHeight:75];
    intersectRec=[firstRec intersect:secondRec];
    NSLog(@"intersect rectangle origin.x= %i origin.y=%i width=%i height=%i",intersectRec.origin.x,intersectRec.origin.y,intersectRec.width,intersectRec.height);