Amazon.com Widgets 8.4
Welcome, Guest. Please login or register.
Did you miss your activation email?
June 19, 2013, 10:05:54 AM
Home Help Search chat Login Register   
News: Read this please.The Great Kangaroo Escape Looking for reviews of the 4th ed on Amazon!   Twitter:  @skochan
                     

+  Official Forum for Programming in Objective-C (the iPhone Programming Language) - Stephen Kochan
|-+  Old Stuff
| |-+  Answers to Exercises
| | |-+  Chapter 8
| | | |-+  8.4
Pages: [1]   Go Down
Print
Author Topic: 8.4  (Read 2934 times)
sir
Full Member
***
Posts: 118


Email




8.4
« on: March 15, 2009, 01:17:23 AM »

main.m
Code: (Objective-C)
/*
Write a Rectangle method called translate:
that takes a vector called XYPoint (xv, yv) as its argument.
Have it translate the rectangle's origin by the specified vector.

*/
#import "Rectangle.h";
#import "XYPoint.h";

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

XYPoint *origVector = [XYPoint new];
XYPoint *addVector = [XYPoint new];
    Rectangle *rectangleChange = [Rectangle new];

[origVector setX: 2 andY: 4];
[rectangleChange setOrigin: origVector];
NSLog(@"The original origin is: (%f, %f)", rectangleChange.origin.x, rectangleChange.origin.y);

[addVector setX: 3 andY: -2];
[rectangleChange translate: addVector];
NSLog(@"The new origin is: (%f, %f)", rectangleChange.origin.x, rectangleChange.origin.y);

[origVector release];
[addVector release];
[rectangleChange release];

    [pool drain];
    return 0;
}


XYPoint.h
Code: (Objective-C)
#import <Foundation/Foundation.h>


@interface XYPoint : NSObject {
double x, y;
}
@property double x, y;

-(void) setX: (double) xVal andY: (double) yVal;
@end


XYPoint.m
Code: (Objective-C)
#import "XYPoint.h"


@implementation XYPoint

@synthesize x, y;
-(void) setX: (double) xVal andY: (double) yVal {
x = xVal;
y = yVal;
}
@end


Rectangle.h
Code: (Objective-C)
#import "XYPoint.h"


@interface Rectangle : NSObject {
double width, height;
XYPoint *origin;
}

@property double width, height;

-(XYPoint *) origin;
-(void) setOrigin: (XYPoint *) pt;
-(void) translate: (XYPoint *) vector;
-(void) setWidth: (double) w andHeight: (double) h;
-(double) area;
-(double) perimeter;
@end


Rectangle.m
Code: (Objective-C)
#import "Rectangle.h"


@implementation Rectangle

@synthesize width, height;

-(XYPoint *) origin {
return origin;
}

-(void) setOrigin: (XYPoint *) pt {
origin = pt;
}

-(void) translate: (XYPoint *) vector {
origin.x = origin.x + vector.x;
origin.y = origin.y + vector.y;
}

-(void) setWidth: (double) w andHeight: (double) h {
width = w;
height = h;
}

-(double) area {
return width * height;
}

-(double) perimeter {
return (width +height) * 2;
}

@end

Logged
jonthornham
Full Member
***
Posts: 169



WWW Email




« Reply #1 on: May 03, 2009, 04:39:01 PM »

Great answer! I see that I made a mistake looking at this example and do not know what is going on.

I wrote this code for my version the translate: method which did not work. originPoint is used for the original origin, originVector is used for the translation, and originTranslated was supposed to be used to store the result of the addition. However when I print originPoint's value after the addition it always results with x = 0 and y = 0. I am stumped.

-(void) translate: (XYPoint *) tr
{
   if (originVector)
      originVector.release;
   
   originVector = [[XYPoint alloc] init];
   [originVector setX: tr.x andY: tr.y];
   
   //This was intended to add the x and y values and store them in originTranslated
        [originTranslated setX: (originPoint.x + originVector.x) andY: (originPoint.y + originVector.y)];  //
   
        // This was to set originPoint to the value of originTranslated
   originPoint = originTranslated;
}

This works

-(void) translate: (XYPoint *) tr
{
   if (originVector)
      originVector.release;
   
   originVector = [[XYPoint alloc] init];
   [originVector setX: tr.x andY: tr.y];
   
   originPoint.x = originPoint.x + originVector.x;
   originPoint.y = originPoint.y + originVector.y;
}

I can't see why my first example doesn't work.

Thanks,

Jon
Logged

Jon Thornham
skochan
Administrator
Hero Member
*****
Posts: 3109







« Reply #2 on: May 03, 2009, 05:06:02 PM »

Where is originTranslated defined and allocated / initialized?  Is it an instance variable?  You don't need that extra step, you can store the result back into originPoint like this:

Code: (Objective-C)
[originPoint setX: (originPoint.x + originVector.x) andY: (originPoint.y + originVector.y)]

Also realize that when you write

Code: (Objective-C)
originPoint = originTranslated;

that you're not copying the (x,y) values from originTranslated to originPoint; you're just copying the reference to the object in memory (that is the object memory address).

Cheers,

Steve Kochan

Logged
jonthornham
Full Member
***
Posts: 169



WWW Email




« Reply #3 on: May 03, 2009, 05:28:04 PM »

Ahh I see! Thanks for the help!  Grin
Logged

Jon Thornham
jonthornham
Full Member
***
Posts: 169



WWW Email




« Reply #4 on: May 11, 2009, 10:17:03 PM »

Following what you said above.

Quote
Also realize that when you write

Code:
originPoint = originTranslated;

that you're not copying the (x,y) values from originTranslated to originPoint; you're just copying the reference to the object in memory (that is the object memory address).

Why can we copy numerator and denominator or real and complex numbers in Program 9.2 on page 191 using the id Type?

dataValue = f1;

Following what you said above I know when comparing objects you test the equality of the pointers. But you can test the object attribute using isEqual:

Identity—testing equality of the pointer values
if (object1 == object2) {
NSLog(@"Same exact object instance");
}

Equality—testing object attributes
if ([object1 isEqual: object2]) {
NSLog(@"Logically equivalent, but may
        be different object instances");
}

Thanks,

Jon
Logged

Jon Thornham
skochan
Administrator
Hero Member
*****
Posts: 3109







« Reply #5 on: May 11, 2009, 10:27:09 PM »

Well, I still don't know where originTranslated is allocated and whether it's an instance varaible.
Copying a numerator or denominator, which are just basic data types  (ints), is different than copying an object like a Fraction, which is an object.  And yes, your analysis of comparing the object's contents versus the pointers is correct.

My point (no pun intended) is that I'm not sure what you're trying to do with originTranslated or why you even need it in the first place.  You can do your operation directly on originPoint.  The other point was that since I don't know where originTranslated is allocated or defined, that you have to understand that the assignment of originTranslated to originPoint simply sets the latter pointing to the former and does not copy the contents (that is the x and y coordinates) from the latter into the former.


Cheers,

Steve Kochan

Logged
jonthornham
Full Member
***
Posts: 169



WWW Email




« Reply #6 on: May 12, 2009, 05:36:24 PM »

I'm sorry I can't seem to get my point across. My originTranslated is totally useless and I understand that it is not needed. I guess my last question was:

Is setting two objects equal to each other the same as setting an id type equal to an object?

Does setting

dataValue = f1;

equate to

object1 = object2;

or

[object1 isEqual: object2];

Thanks,

Jon
Logged

Jon Thornham
skochan
Administrator
Hero Member
*****
Posts: 3109







« Reply #7 on: May 12, 2009, 05:56:11 PM »

Quote
Does setting

dataValue = f1;

equate to

object1 = object2;

Yes

In the first case, dataValue and f1 point to the same object, and in the second case object1 and object2 point to the same object at the end of the assignments.

Cheers,

Steve Kochan
Logged
jonthornham
Full Member
***
Posts: 169



WWW Email




« Reply #8 on: May 13, 2009, 11:59:27 AM »

Thanks for your patience. I get it now.

Jon
Logged

Jon Thornham
Crivo
Newbie
*
Posts: 12







« Reply #9 on: June 06, 2009, 01:13:55 PM »

 Here's my version of it:

Ex8.4.m
Code: (Objective-C)
#import <Foundation/Foundation.h>
#import "Rectangle.h"
#import "XYPoint.h"

int main (int argc, const char * argv[])
{
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
Rectangle * myRectangle = [[Rectangle alloc] init];
XYPoint * myPoint = [[XYPoint alloc] init];
XYPoint * myVector = [[XYPoint alloc] init];

myRectangle.height = 5;
myRectangle.width = 8;
myPoint.x = 100;
myPoint.y = 200;
myRectangle.origin = myPoint;
   
printf("rectangle h = %.2f w = %.2f", myRectangle.height, myRectangle.width);
printf("\norigin at x = %.2f y = %.2f", myRectangle.origin.x, myRectangle.origin.y);
printf("\narea = %.2f perimeter = %.2f", myRectangle.area, myRectangle.perimeter);

myVector.Xv = 55;
myVector.Yv = 66;
[myRectangle translate: myVector];

printf("\n\nrectangle h = %.2f w = %.2f", myRectangle.height, myRectangle.width);
printf("\norigin at x = %.2f y = %.2f", myRectangle.origin.x, myRectangle.origin.y);
printf("\narea = %.2f perimeter = %.2f", myRectangle.area, myRectangle.perimeter);

myPoint.release;
myRectangle.origin.release;
myRectangle.release;
myVector.release;
[pool drain];
    return 0;
}
XYPoint.h
Code: (Objective-C)
#import <Foundation/Foundation.h>

@interface XYPoint : NSObject
{
double x, y, Xv, Yv;
}

-(double) x;
-(double) y;
-(void) setX: (double) value1 andY: (double) value2;
-(void) setX: (double) value1;
-(void) setY: (double) value2;

-(double) Xv;
-(double) Yv;
-(void) setXv: (double) value1 andYv: (double) value2;
-(void) setXv: (double) value1;
-(void) setYv: (double) value2;

@end
XYPoint.m
Code: (Objective-C)
#import "XYPoint.h"

@implementation XYPoint

-(void) setX: (double) value1
{
x = value1;
}

-(void) setY: (double) value2
{
y = value2;
}

-(void) setX: (double) value1 andY: (double) value2
{
x = value1;
y = value2;
}

-(double) x
{
return x;
}
-(double) y
{
return y;
}



-(void) setXv: (double) value1
{
Xv = value1;
}

-(void) setYv: (double) value2
{
Yv = value2;
}

-(void) setXv: (double) value1 andYv: (double) value2
{
Xv = value1;
Yv = value2;
}

-(double) Xv
{
return Xv;
}
-(double) Yv
{
return Yv;
}
@end
Rectangle.h
Code: (Objective-C)
#import <Foundation/Foundation.h>

@class XYPoint;
@interface Rectangle : NSObject

{
double height;
double width;
XYPoint * origin;
}

@property double width, height;

-(XYPoint *) origin;
-(void) setOrigin: (XYPoint *) pt;
-(void) setWidth: (double) w andHeight: (double) h;
-(double) area;
-(double) perimeter;
-(void) translate: (XYPoint *) vector;

@end
Rectangle.m
Code: (Objective-C)
#import "Rectangle.h"
#import "XYPoint.h";

@implementation Rectangle

@synthesize width, height;

-(void) setWidth: (double) w andHeight: (double) h
{
width = w;
height = h;
}

-(void) setOrigin: (XYPoint *) pt
{
origin = [[XYPoint alloc] init];
[origin setX: pt.x andY: pt.y];
}

-(void) translate: (XYPoint *) vector 
{
[origin setX: (origin.x + vector.Xv) andY: (origin.y + vector.Yv)];
}

-(double) area
{
return width * height;
}

-(double) perimeter
{
return (width + height) * 2;
}

-(XYPoint *) origin
{
return origin;
}

@end
Logged
stevew
Newbie
*
Posts: 1






« Reply #10 on: July 11, 2009, 11:53:28 PM »

I'm a little fuzzy on something.
What is the reason that myPoint is created and assigned values and then those values passed onto origin, is it not possible to directly assign values to the origin object owned by myRectangle?
Logged
skochan
Administrator
Hero Member
*****
Posts: 3109







« Reply #11 on: July 12, 2009, 12:13:34 AM »

@Crivo:  Although it's not enforced, the dot operator is really meant to be used with properties.  Therefore, a statement like this:

Code: (Objective-C)
myRectangle.origin.release;

would be better written this way:

Code: (Objective-C)
[myRectangle.prigin release];

This has nothing to do with functionality, but more to do with readability and convention.

Cheers,

Steve Kochan
Logged
nhohmann
Global Moderator
Jr. Member
*****
Posts: 57







« Reply #12 on: July 15, 2009, 12:13:14 AM »

I must admit, Chapter 8 has been a bit of a challenge for me and my first go at this exercise resulted in some unwieldy code, though functional. I reread some parts of chapters 7 and 8 and then came up with the following solution.

In main I created a new XYPoint instance called vector.  Vector's coordinates are set and then are passed to myRect when the translate method is called.  A new XYPoint is created called newOrigin in which the (x, y) coordinates of "origin" and "vector" are added together to create a new position for myRect.

The original origin of myRect is preserved -- mainly because I didn't know if our goal was to permanently change its position or not.

Console ouput:
Code: (Objective-C)
[Session started at 2009-07-15 09:14:12 +0200.]
2009-07-15 09:14:12.446 Prog ex8.2[1868:10b] Rectangle: w = 5.000000, h = 8.000000
2009-07-15 09:14:12.449 Prog ex8.2[1868:10b] Origin at (100.449997, 198.800003)
2009-07-15 09:14:12.449 Prog ex8.2[1868:10b] Area = 40.000000, Perimeter = 26.000000
2009-07-15 09:14:12.450 Prog ex8.2[1868:10b] Vector coordiantes (5.000000, -10.000000)
2009-07-15 09:14:12.450 Prog ex8.2[1868:10b] New origin: (105.449997, 188.800003)

The Debugger has exited with status 0.

Code: (Objective-C)
// Chapter 8, exercise 4 (p. 184)
// Based on Prog ex8.2


#import "Rectangle.h"
#import "XYPoint.h"

int main (int argc, const char * argv[])
{
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

Rectangle *myRect = [[Rectangle alloc] init];
XYPoint *myPoint = [[XYPoint alloc] init];
XYPoint *vector = [[XYPoint alloc] init];

[myRect setWidth: 5 andHeight: 8];
[myPoint setX: 100.45 andY: 198.80];

myRect.origin = myPoint; // same as [myRect setOrigin: myPoint];

NSLog (@"Rectangle: w = %f, h = %f", myRect.width, myRect.height); // equal to [myRect width], [myRect height]
NSLog (@"Origin at (%f, %f)", myRect.origin.x, myRect.origin.y);
NSLog (@"Area = %f, Perimeter = %f", [myRect area], [myRect perimeter]);

// set vector coordinates
[vector setX: 5 andY: -10];

// send the translate message to myRect
[myRect translate: vector];

// return newOrigin, which is myRect's new position
[myRect newOrigin];

NSLog (@"Vector coordiantes (%f, %f)", vector.x, vector.y);
NSLog (@"New origin: (%f, %f)", myRect.newOrigin.x, myRect.newOrigin.y);


[[myRect newOrigin] release];
[[myRect origin] release];
[myRect release];
[myPoint release];
[vector release];

    [pool drain];
    return 0;
}

Rectangle.h
Code: (Objective-C)
//
//  Rectangle.h
//  Prog ex8.2
//
//  Created by Neil Hohmann on 7/10/09.
//  Copyright 2009 __MyCompanyName__. All rights reserved.
//

#import <Foundation/Foundation.h>

#import "XYPoint.h"

@interface Rectangle : NSObject
{
float width;
float height;
XYPoint *origin;
XYPoint *newOrigin;
}

@property float width, height;

-(XYPoint *) origin;
-(void) setOrigin: (XYPoint *) pt;
-(void) setWidth: (float) w andHeight: (float) h;
-(float) area;
-(float) perimeter;
-(void) translate: (XYPoint *) vector;
-(XYPoint *) newOrigin;

@end

Rectangle.m
Code: (Objective-C)
//
//  Rectangle.m
//  Prog ex8.2
//
//  Created by Neil Hohmann on 7/10/09.
//  Copyright 2009 __MyCompanyName__. All rights reserved.
//

#import "Rectangle.h"


@implementation Rectangle

@synthesize width, height;

-(void) setWidth: (float) w andHeight: (float) h
{
width = w;
height = h;
}

-(void) setOrigin: (XYPoint *) pt
{
origin = [[XYPoint alloc] init];
[origin setX: pt.x andY: pt.y];
}

-(float) area
{
return width * height;
}

-(float) perimeter
{
return (width + height) * 2;
}

-(XYPoint *) origin
{
return origin;
}

-(void) translate: (XYPoint *) vector
{
// "add" vector's coordinates to myRect's coordiantes (translate)

newOrigin = [[XYPoint alloc] init];
[newOrigin setX: (origin.x + vector.x) andY: (origin.y + vector.y)];

}

-(XYPoint *) newOrigin
{
return newOrigin;
}



@end
« Last Edit: July 15, 2009, 12:15:58 AM by nhohmann » Logged
adamburrito
Newbie
*
Posts: 12


Email




« Reply #13 on: September 30, 2009, 07:41:35 PM »

This is my first time posting and I'm probably not adding too much new... But I decided to have the user input the translation amount via the scanf option in the console. The first time I wrote this I thought the author intended us to translate the coordinates to a new position while preserving the values of the origin of the point. I later realized that he probably just wanted us to simply move the origin. This is my attempt at it and it seems to work well. Any comments or suggestions are very welcomed! I'm really struggling to make it through this chapter!!


-----------------------------------------------------
XYPoint.h
-----------------------------------------------------
#import <Foundation/Foundation.h>

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

@property float x, y;

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

@end


---------------------------------------------------------
XYPoint.m
---------------------------------------------------------
#import <Foundation/Foundation.h>

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

@property float x, y;

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

@end


---------------------------------------------------------
Rectangle.h
---------------------------------------------------------
#import <Foundation/Foundation.h>
@class XYPoint;

@interface Rectangle : NSObject
{

   XYPoint *origin;
   XYPoint *movedPoint;                     //a new instance variable that takes on the value of the new translated point, so as to preserve the origin point
   float width;
   float height;
}

@property float width, height;

-(XYPoint *) origin;                        //method for returning the value of "origin" point
-(XYPoint *) movedPoint;                     //method for returning the value of the new point
-(void) translate: (XYPoint *) vector;            //method for adding the translation amount to the origin point, which will end up equalling "movedPoint"
-(void) setOrigin: (XYPoint *) pt;               //method for assigning the origin point to the
-(void) setWidth: (float) w andHeight: (float) h;
-(float) area;
-(float) perimeter;
-(void) dealloc;


@end


---------------------------------------------------------
Rectangle.m
---------------------------------------------------------
#import "Rectangle.h"
#import "XYPoint.h"

@implementation Rectangle

@synthesize width, height;

-(void) setWidth: (float) w andHeight: (float) h
{
   width = w;
   height = h;
}

-(float) area
{
   return width * height;   
}

-(float) perimeter
{
   return (width + height) * 2;   
}

-(void) setOrigin: (XYPoint *) pt
{
   if (origin)
      [origin release];
   
   origin = [[XYPoint alloc] init];
   
   [origin setX: pt.x andY:pt.y];
}

-(XYPoint *) origin
{
   return origin;   
}

-(void) dealloc
{
   [origin release];
   [super dealloc];
}

-(void) translate: (XYPoint *) vector
{
   if (movedPoint)
      [movedPoint release];
   movedPoint = [[XYPoint alloc] init];
      
   movedPoint.x = origin.x + vector.x;
   movedPoint.y = origin.y + vector.y;
}

-(XYPoint *) movedPoint
{
   return movedPoint;   
}


@end

---------------------------------------------------------
RectangleTest.m    (program file)
--------------------------------------------------------

#import "Rectangle.h"
#import "XYPoint.h"

int main (int argc, const char * argv[])
{
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

   Rectangle *myRect = [[Rectangle alloc] init];
   XYPoint     *originalPoint = [[XYPoint alloc] init];
   XYPoint     *newPoint = [[XYPoint alloc] init];
   
   
   [originalPoint setX: 100 andY: 200];      // setting x value and y for "myPoint"
   [myRect setOrigin: originalPoint];         //This sets the origin of the myRect object to = myPoint, which means myRect origin is now (100, 200)
 
   NSLog(@"The origin of the rectangle was initially set at (%f, %f)", myRect.origin.x, myRect.origin.y);   //this retrieves myRect's x and y coordinates through two dot operators each

   float inputxVector = 0, inputyVector = 0;
   NSLog(@"Please enter translation amounts for rectangle (x,y) point:");
   scanf("%f %f", &inputxVector, &inputyVector);
   
   [newPoint setX:inputxVector andY:inputyVector];
   [myRect translate: newPoint];
   
   NSLog(@"After translation, the new position of the rectangle is: (%f,%f)", myRect.movedPoint.x, myRect.movedPoint.y);
   NSLog(@"The origin of the rectangle has not changed from (%f,%f)", myRect.origin.x, myRect.origin.y);
   
   [newPoint release];
   [myRect release];
   [originalPoint release];
   
   [pool drain];
    return 0;
}
Logged
pinksoie
Newbie
*
Posts: 7



WWW




« Reply #14 on: October 19, 2010, 03:40:34 PM »

@ nhohmann

I like this solution the best for Ex 8.4. I'm not sure if it's the best from a coders perspective but it is easy to follow and seems clean.

Thanks for the post!
Logged
Pages: [1]   Go Up
Print
Jump to:  



Login with username, password and session length

Powered by MySQL Powered by PHP Powered by SMF 1.1.11 | SMF © 2006-2009, Simple Machines LLC Valid XHTML 1.0! Valid CSS!
Entire forum contents (c) 2009 classroomM.com. All rights reserved.