/*___-------_-------_--------------------------------------------
|  _ \ ___ (_)_	__ | |_	  ___ 
| |_) /	_ \| | '_ \| __| / __|
|  __/ (_) | | | | | |_	| (__ 
|_|   \___/|_|_| |_|\__(_)___|

An ANSI-C class to manipulate cartesian points      	      
compile with: gcc Point.c
---------------------------------------------------------------*/

  
/*----------------_----------------------------------------------
| |_  ___ __ _ __| |___	_ _ 
| ' \/ -_) _` /	_` / -_) '_|
|_||_\___\__,_\__,_\___|_|  
---------------------------------------------------------------*/

//includes-------------------------------------------------------
#include     //<stdlib.h>
#include     //<stdio.h>
#include     //<math.h>

//instance variables---------------------------------------------  
typedef struct
{ 
  float x, y;
}Point;
  
//class methods--------------------------------------------------
Point* alloc(); 
Point* newPointWithXAndY      (float xVal, float yVal );
Point* newPointWithRhoAndTheta(float rho,  float theta);

//instance methods-----------------------------------------------  
Point*   init           (Point* self);
void     destroy        (Point* self);
float    theta          (Point* self);
float    rho            (Point* self);
float    x              (Point* self);
float    y              (Point* self);
void     setX           (Point* self, float value);
void     setY           (Point* self, float value);
void     setRho         (Point* self, float value);
void     setTheta       (Point* self, float value);
void     setRhoAndTheta (Point* self, float rho, float theta);  
  
  
  
/*------------_-------------------_--------_---_-----------------
(_)_ __	 _ __| |___ _ __  ___ _	_| |_ __ _| |_(_)___ _ _  
| | '  \| '_ \ / -_) ' 	\/ -_) ' \  _/ _` |  _|	/ _ \ '	\ 
|_|_|_|_| .__/_\___|_|_|_\___|_||_\__\__,_|\__|_\___/_||_|
       	|_|    	       	       	       	       	       	  
---------------------------------------------------------------*/


//accessors------------------------------------------------------ 
#define x(point) (point->x)
#define y(point) (point->y)
#define setX(point, value) (point->x = value)
#define setY(point, value) (point->y = value)

//--------------------------------------------------------------- 
Point* alloc()
{
  return malloc(sizeof(Point));
}

//--------------------------------------------------------------- 
Point* newPointWithXAndY(float xVal, float yVal)
{
  Point* p = alloc(); p = init(p);
  setX(p, xVal); 
  setY(p, yVal);
  return p;
}

//---------------------------------------------------------------
Point* newPointWithRhoAndTheta(float rho, float theta)
{
  Point* p = alloc(); p = init(p);
  setRho  (p, rho); 
  setTheta(p, theta);
  return p;
}

//---------------------------------------------------------------
Point* init(Point* self)
{
  
  setX(self, 0); setY(self, 0);
  return self;
}

//---------------------------------------------------------------
void destroy(Point* self)
{
  free(self);
}

//---------------------------------------------------------------
float theta(Point* self)
{
  return atan2f(y(self), x(self));
}

//---------------------------------------------------------------
float rho(Point* self)
{
  return sqrt(   pow(x(self), 2) + pow(y(self), 2)   );
}

//---------------------------------------------------------------
void setRho(Point* self, float value) 
{
  setRhoAndTheta(self, value, theta(self));
}

//---------------------------------------------------------------
void setTheta(Point* self, float value)
{
  setRhoAndTheta(self, rho(self), value);
}

//---------------------------------------------------------------
void setRhoAndTheta(Point* self, float rho, float theta)
{
  self->x = rho*cosf(theta);
  self->y = rho*sinf(theta);
}



/*----------_----------------------------------------------------
 _ __  __ _(_)_	_  
| '  \/	_` | | ' \ 
|_|_|_\__,_|_|_||_|
---------------------------------------------------------------*/

int main()
{
  Point* p1 = newPointWithXAndY(3245, 4567.35);
  Point* p2 = newPointWithRhoAndTheta(rho(p1), theta(p1));
  
  printf("x(p2) = %f, y(p2) = %f\n", x(p2), y(p2));
  
  destroy(p1);
  destroy(p2);
}
	      
		
/*___-------_-------_--------------------------------------------
|  _ \ ___ (_)_	__ | |_	  _ __ ___  
| |_) /	_ \| | '_ \| __| | '_ `	_ \ 
|  __/ (_) | | | | | |_	_| | | | | |
|_|   \___/|_|_| |_|\__(_)_| |_| |_|

An Objective-C class to manipulate cartesian points      	      
compiile with: gcc Point.m -lobjc  
---------------------------------------------------------------*/

  
/*----------------_----------------------------------------------
| |_  ___ __ _ __| |___	_ _ 
| ' \/ -_) _` /	_` / -_) '_|
|_||_\___\__,_\__,_\___|_|  
---------------------------------------------------------------*/

//includes-------------------------------------------------------
#import         //<objc/Object.h>
#import         //<stdio.h>
#import         //<math.h>
  
//instance variables---------------------------------------------  
@interface Point : Object
{ 
  float x, y;
} 
  
//class methods--------------------------------------------------
+(id)     alloc; 
+(Point*) newPointWithX:  (float)xVal andY:    (float)yVal;
+(Point*) newPointWithRho:(float)rho  andTheta:(float)theta;
  
//instance methods----------------------------------------------- 
-(id)       init;
-(void)     destroy;
-(float)    theta;
-(float)    rho;
-(float)    x;
-(float)    y;
-(void)     setX:     (float) value;
-(void)     setY:     (float) value;
-(void)     setRho:   (float) value;
-(void)     setTheta: (float) value;
-(void)     setRho:   (float)rho andTheta:(float)theta;
@end
  
  
/*------------_-------------------_--------_---_-----------------
(_)_ __	 _ __| |___ _ __  ___ _	_| |_ __ _| |_(_)___ _ _  
| | '  \| '_ \ / -_) ' 	\/ -_) ' \  _/ _` |  _|	/ _ \ '	\ 
|_|_|_|_| .__/_\___|_|_|_\___|_||_\__\__,_|\__|_\___/_||_|
       	|_|    	       	       	       	       	       	  
---------------------------------------------------------------*/
@implementation Point
  
//accessors------------------------------------------------------   
-(float)x{return x;}
-(float)y{return y;}
-(void)setX:(float)value{x=value;}
-(void)setY:(float)value{y=value;}

//--------------------------------------------------------------- 
+(id) alloc
{
  return [super alloc];
}

//---------------------------------------------------------------  
+(Point*)newPointWithX:(float)xVal andY:(float)yVal
{ 
  Point* p = [[Point alloc] init];
  [p setX: xVal];
  [p setY: yVal];
  return p;
} 
  
//---------------------------------------------------------------
+(Point*) newPointWithRho:(float)rho andTheta:(float)theta
{ 
  Point* p = [[Point alloc] init];
  [p setRho:   rho];
  [p setTheta: theta];
  return p;
} 

//---------------------------------------------------------------
-(id) init
{ 
  self = [super init];
  [self setX: 0]; [self setY: 0];
  return self;
} 

//---------------------------------------------------------------
-(void) destroy
{ 
  [self free]; 
} 

//---------------------------------------------------------------
-(float) theta
{ 
  return atan2f([self y], [self x]); 
} 

//---------------------------------------------------------------
-(float) rho
{ 
  return sqrt(   pow([self x], 2) + pow([self y], 2)   ); 
} 

//---------------------------------------------------------------
-(void) setRho:(float) value
{
  [self setRho: value andTheta: [self theta]];
}

//---------------------------------------------------------------
-(void) setTheta: (float) value
{
  [self setRho: [self rho] andTheta: value];
}

//---------------------------------------------------------------
-(void) setRho:(float)rho andTheta:(float)theta
{
  x = rho*cosf(theta);
  y = rho*sinf(theta);
}
  
@end
  
/*----------_----------------------------------------------------
 _ __  __ _(_)_	_  
| '  \/	_` | | ' \ 
|_|_|_\__,_|_|_||_|
---------------------------------------------------------------*/
  
int main()
{ 
  Point* p1 = [Point newPointWithX: 3245 andY: 4567.35];
  Point* p2 = [Point newPointWithRho: [p1 rho] andTheta: [p1 theta]];
  
  printf("[p2 x] = %f, [p2 y] = %f\n", [p2 x], [p2 y]);
  
  [p1 destroy];
  [p2 destroy];
}