Exercise 8-4 of Kochan 2.0

Discussion in 'Mac Programming' started by mdeh, Jan 14, 2009.

  1. mdeh macrumors 6502

    Joined:
    Jan 3, 2009
    #1
    "Write a Rectangle method called translate: that takes a vector Point (xv, yv) as its argument. Have it translate the rectangle's origin by the specified vector"

    Not that familiar with vectors. Is the argument simply a couple of integers. And by "translate", is the implication that one is assigning a new value to an existing point?

    thanks
     
  2. skochan macrumors regular

    Joined:
    Apr 1, 2006
    Location:
    California
    #2
    The arguments are a rectangle and an XPoint object (a set of two integers). Translation simply means to add the corresponding x, y coordinates from that argument to the rectangle's origin. Hope that clears it up!

    Cheers,

    Steve Kochan
     
  3. mdeh thread starter macrumors 6502

    Joined:
    Jan 3, 2009
    #3
    So the declaration should look something like this?

    -(void) translate: ( XYPoint *) myPt; ?????


    Thanks Steve...
     
  4. savar macrumors 68000

    savar

    Joined:
    Jun 6, 2003
    Location:
    District of Columbia
    #4
    More specifically, add the dx and the dy to each corner of the rectangle.
     
  5. skochan macrumors regular

    Joined:
    Apr 1, 2006
    Location:
    California
    #5
    Yes, that's correct. As defined in the text, a Rectangle object has an origin and a width and a height. So in this case, you'd be adding the offset vector (the argument to the translate method) to the Rectangle's origin.

    Cheers,

    Steve
     
  6. mdeh thread starter macrumors 6502

    Joined:
    Jan 3, 2009
    #6

    OK...got it...thank you
     
  7. mdeh thread starter macrumors 6502

    Joined:
    Jan 3, 2009
    #7
    OK....here is my code for the answer to the exercise. Anyones' criticism is welcome. ( Gentle please :) )

    So, given a rectangle which as 3 ivars; height, width, and a point which again, are 2 values x, and y.
    I am not sure whether one needs to test of the "non-nil" value of origin first, as it should not be called before the value of origin is set, but if it is called, then an exception is generated. ( I am not sure whether to include a small test program or not. If others start posting their answers too, then maybe we can get some sort of consensus)


    Code:
    -(void) translate: (XYPpoint_f *) myPt
    {
    	if  (! origin)
    		origin = [[XYPpoint_f alloc] init];
    	
    	origin.x = myPt.x ;
    	origin.y = myPt.y ;
    	
    }
    
     
  8. skochan macrumors regular

    Joined:
    Apr 1, 2006
    Location:
    California
    #8
    You need to add the offsets to the current origin:

    Code:
    	origin.x += myPt.x ;
    	origin.y += myPt.y ;
    
    Cheers,

    Steve Kochan
     
  9. mdeh thread starter macrumors 6502

    Joined:
    Jan 3, 2009
    #9

    OOPS..of course! ( I guess that's what "add to" means :) ) Thanks.
     
  10. TotalLuck macrumors newbie

    TotalLuck

    Joined:
    Jan 3, 2009
    Location:
    Moreno Vallley
    #10
    Is this what I'm supposed to get?

    First let me say I'm glad someone else asked this question. So here's what I got.

    The implementation
    I used -(XYpoint *) instead of -(void). is that not correct? :
    did not however check for the (! origin) (and i am not understanding why I should do that. please explain)
    Code:
    -(XYpoint *) translate: (XYpoint *) mypt
    {
    	origin.x += mypt.x;
    	origin.y += mypt.y;
    	
    	return origin;
    	
    }
    
    the main
    Code:
    int main(int argc, char *argv[])
    {
    	NSAutoreleasePool * pool = [[NSAutoreleasePool alloc]init];
    	
    	Rectangle *myRect = [[Rectangle alloc]init]; // create instance of a Rectangle
    	XYpoint *myPoint = [[XYpoint alloc]init]; // create origin xypoint
    	XYpoint *myVector = [[XYpoint alloc] init]; // create vector
    	
    	[myRect setwidth: 10 andheight: 80]; 
    	[myPoint setX:10 andY: 80]; 
    	
    	
    	myRect.origin = myPoint; // sets the origin of the rectangle to the coordinates in myPoint
    	
    	NSLog(@"The Origin of the rectangle is at (%g,%g)", myRect.origin.x, myRect.origin.y);
    	
    	[myVector setX:15 andY: 40]; // set a vector point 
    	NSLog(@"A Vector point  at (%g,%g)", myVector.x, myVector.y);
    	
    	[myRect translate: myVector];
    	
    	NSLog(@"The Rectangles new origin is translated to (%g,%g)", myRect.origin.x, myRect.origin.y);
    	
    	
    	[[myRect origin] release];
    	[myVector release];	
    	[myRect release];
    	[myPoint release];
    	[pool drain];
    	
    	
    	return 0;
    }
    i get this output:

    The Origin of the rectangle is at (10,80)
    A Vector point at (15,40)
    The Rectangles new origin is translated to (25,120)

    this compiles and runs fine.
    what should i have gotten?
     
  11. skochan macrumors regular

    Joined:
    Apr 1, 2006
    Location:
    California
    #11
    It depends on how you (or others who will use your Rectangle class) will use the translate method in expressions. If the translated origin might be used direclty in an expression after the method call, then you would declare the method as you did: -(XYPoint *) and return the origin from the method (also as you did). This would be a more flexible implementation than not returning a value and declaring the method as void.

    This is defensive programming. It's possible that someone could call the translate method without having first set the Rectangle's origin (it's also possible that someone could call the translate method without even first allocating or initializing a Rectangle object).

    One of the good things about Objective-C is that sending a message to a nil object has no effect and is also considered "OK" programming practice. Thus, writing a statement like

    origin.x += mypt.x;

    works even if origin is nil (it has no effect).

    Again, the correct approach here depends on how you want your Rectangle class to work. If you write a translate method you could decide that it's a catastrophic error if it's called with a nil origin and throw an exception; or you could allocate an origin object and set it to (0, 0); or you might decide to just add the offset vector to a possibly nil origin object, knowing that it will effectively do nothing if the origin is in fact nil. The choice is a design consideration and the behavior should be documented with the method.

    This output is correct.

    Cheers,



    Steve Kochan
     

Share This Page