
 

// Emacs: -*- C++ -*-

/*
        Copyright 1993, Center for Computer Vision and Visualization,
        University of Florida.  All rights reserved.

// $Log: Point_h.m4,v $
// Revision 2.21.1.1  1994/11/30  16:17:13  thoth
// Added cross product and dot product.
//
// Revision 2.21  1994/08/22  14:39:02  thoth
// fixed conflict with system's abs.
//
// Revision 2.20  1994/08/16  20:59:00  fjsoria
// added derange and enorm as non-member functions, keeping member versions
// added inorm, mnorm, abs, fabs as non-member functions
//
// Revision 2.19  1994/07/25  16:42:26  thoth
// FloatPoint is now either Point<double> or DoublePoint.
//
// Revision 2.18  1994/04/27  04:05:55  jnw
// added operator() for points
//
// Revision 2.17  1994/03/14  18:44:44  jnw
// Modified sum and product
//
// Revision 2.16  1994/03/14  18:16:38  jnw
// Added point reduce functions 'sum' and 'product'
//
// Revision 2.15  1993/11/16  13:27:10  thoth
// Pointcmp is now pointcmp
//
// Revision 2.14  1993/09/15  12:26:01  thoth
// Point is now a template with specializations only.
//
// Revision 2.13  93/05/26  16:59:41  rjj
// Added copyright notice
// 
// Revision 2.12  93/04/29  21:51:17  rjj
// Added missing  const  for  IA_Point op NUMBER.  See change in defines.m4 also.
// 
// Revision 2.11  93/04/06  22:25:39  rjj
// Removed const from "const int" and "const double"
// Changed bitwise unsigned parameters to int
// removed backwards compability with IntPoint and FloatPoint
// 
// Revision 2.10  93/04/05  23:00:56  rjj
// Many changes:
//   member size renamed to dimen
//   member dimensions() renamed as dim()
//   postfix members ++ and -- added
//   operator() changed into member derange() and extended with array version
//   member infimum() rename to inf()
//   member supremum() renamed to sup()
//   all references to IntPoint changed to IA_IntPoint
//   all references to FloatPoint changed to IA_FloatPoint
//   change to map IA_IntPoint to IntPoint now does the reverse
//   change to map IA_FloatPoint to FloatPoint now does the reverse
//   file reorganized to group related members as I saw fit
//   in general the interface as been mutated into the interface
//     reflected by newpoint, which spans Point.h, ArithPoint.h
//     LatticePoint.h, BitwisePoint.h and of course
//     IntPoint.h and FloatPoint.h
// 
// Revision 2.9  92/12/11  01:11:57  rjj
// Modified to support the IA_ prefix naming convention.
// Also put #ifdef IA_PRII around the #pragma stamt
// 
// Revision 2.8  92/09/02  14:50:44  rjj
// Corrected renameing of min to infimum and max to supremum
// 
// Revision 2.7  92/09/01  20:45:29  rjj
// Added support to ensure float op IntPoint and IntPoint op float
//  yield FloatPoint.
// 
// Revision 2.6  92/08/28  11:55:11  jnw
// Changed relation functions with IA_Point<int>& and float args
// to have IA_Point<int>& and double args to match current .C code
// 
// Revision 2.5  92/08/27  12:11:27  jnw
// Added C style comments around Log Messages to fixx gcc-cpp bug
// 
// Revision 2.4  92/08/23  13:35:47  thoth
// CFrontified
// throw changed to ia_throw.
// didn't hint to inline for loop stuff any more (braindead compiler).
// fixed const pass-by-value problem.
// 
// 

*/

#ifndef IA_IntPoint_h_
#define IA_IntPoint_h_

#include "ia.h"

#ifdef IA_PRII
#pragma interface
#endif

#define SUPPRESS_INCLUDE
#include "Point.h"
#undef SUPPRESS_INCLUDE

class IA_Point<int> {
    
  protected:  
    unsigned dimen;
    int *coordinates;
    
  public:
    ////////////////////////////////////////////////////////////
    // C O N S T R U C T O R S
    ////////////////////////////////////////////////////////////
    
    IA_Point (const IA_Point<int>&);

    IA_Point () {coordinates = 0; dimen = 0; }
    
    IA_Point (int c0) {
	coordinates = new int[dimen = 1];
	coordinates[0] =  c0;
    }
    
    IA_Point (int c0, int c1) {
	coordinates = new int[dimen = 2];
	coordinates[0] = c0;
	coordinates[1] = c1;
    }
    
    IA_Point (int c0, int c1, int c2) {
	coordinates = new int[dimen = 3];
	coordinates[0] = c0;
	coordinates[1] = c1;
	coordinates[2] = c2;
    }
    
    IA_Point (int c0, int c1, int c2, int c3) {
	coordinates = new int[dimen = 4];
	coordinates[0] = c0;
	coordinates[1] = c1;
	coordinates[2] = c2;
	coordinates[3] = c3;
    }
    
    IA_Point (int c0, int c1, int c2, int c3, int c4) {
	coordinates = new int[dimen = 5];
	coordinates[0] = c0;
	coordinates[1] = c1;
	coordinates[2] = c2;
	coordinates[3] = c3;
	coordinates[4] = c4;
    }

    IA_Point (int *, unsigned, int =0);

  // derangment ROF
    friend IA_Point<int>    derange (const IA_Point<int> &, unsigned );
    friend IA_Point<int>    derange (const IA_Point<int> &, unsigned, unsigned);
    friend IA_Point<int>    derange (const IA_Point<int> &,unsigned, unsigned, unsigned);
    friend IA_Point<int>    derange (const IA_Point<int> &,unsigned, unsigned,
				  unsigned, unsigned);
    friend IA_Point<int>    derange (const IA_Point<int> &,unsigned, unsigned,
				  unsigned, unsigned, unsigned);
    friend IA_Point<int>    derange (const IA_Point<int> &, unsigned *, const unsigned);
  
  // derangment member functions
  IA_Point<int>  derange (unsigned i0) const { return ::derange(*this, i0);}

  IA_Point<int>  derange (unsigned i0, unsigned i1) const{
    return ::derange(*this, i0, i1);}
  IA_Point<int>  derange (unsigned i0, unsigned i1, unsigned i2) const {
    return ::derange(*this, i0, i1, i2);}
  IA_Point<int>  derange (unsigned i0, unsigned i1, unsigned i2, unsigned i3)
       const { return ::derange(*this, i0, i1, i2, i3);}
  IA_Point<int>  derange (unsigned i0, unsigned i1, unsigned i2, unsigned i3,
       unsigned i4) const { return ::derange(*this, i0, i1,i2, i3, i4);} 

  IA_Point<int>  derange (unsigned *vec , unsigned vecLen) const {
    return ::derange( *this, vec, vecLen);}

  
    friend IA_Point<int>    extend_to_point (int, unsigned);
    friend IA_Point<int>    concat   (const IA_Point<int>&, const IA_Point<int>&);
    friend IA_Point<int>    concat   (const IA_Point<int>&, int);
    friend IA_Point<int>    concat   (int, const IA_Point<int>&);

    friend IA_Point<int>    cdr      (const IA_Point<int>&, int =1);

  

    // The destructor for this class
    ~IA_Point () { delete[] coordinates; }  // OK even if coordinates NULL.

    ////////////////////////////////////////////////////////////
    // M I S C    O P E R A T I O N S
    ////////////////////////////////////////////////////////////

    IA_Point<int>& operator = (const IA_Point<int>&);

    unsigned            dim () const { return dimen; }

    friend IA_Point<int>	inf    (const IA_Point<int>&, const IA_Point<int>&);
    friend int		min    (const IA_Point<int>&);
    friend IA_Point<int>	sup    (const IA_Point<int>&, const IA_Point<int>&);
    friend int		max    (const IA_Point<int>&);

    friend ostream& operator << (ostream&, const IA_Point<int>&);

    ////////////////////////////////////////////////////////////
    // I N D E X I N G    O P E R A T I O N S
    ////////////////////////////////////////////////////////////

    int&      operator[] (unsigned i)       { return coordinates[i]; }
    const int operator[] (unsigned i) const { return coordinates[i]; }
    const int operator() (unsigned i) const { return coordinates[i]; }

    ////////////////////////////////////////////////////////////
    // A R I T H M E T I C   O P E R A T I O N S
    ////////////////////////////////////////////////////////////

    IA_Point<int>&   operator +=  (const IA_Point<int>&);
    IA_Point<int>&   operator -=  (const IA_Point<int>&);
    IA_Point<int>&   operator *=  (const IA_Point<int>&);
    IA_Point<int>&   operator /=  (const IA_Point<int>&);

    IA_Point<int>&   operator +=  (int);
    IA_Point<int>&   operator -=  (int);
    IA_Point<int>&   operator *=  (int);
    IA_Point<int>&   operator /=  (int);
    
    IA_Point<int>    operator +  (const IA_Point<int>&) const;
    IA_Point<int>    operator -  (const IA_Point<int>&) const;
    IA_Point<int>    operator *  (const IA_Point<int>&) const;
    IA_Point<int>    operator /  (const IA_Point<int>&) const;
    
    IA_Point<int>    operator +  (int) const;
    IA_Point<int>    operator -  (int) const;
    IA_Point<int>    operator *  (int) const;
    IA_Point<int>    operator /  (int) const;
    
    friend IA_Point<int>    operator +  (int, const IA_Point<int>&);
    friend IA_Point<int>    operator -  (int, const IA_Point<int>&);
    friend IA_Point<int>    operator *  (int, const IA_Point<int>&);
    friend IA_Point<int>    operator /  (int, const IA_Point<int>&);

    IA_Point<int>    operator -   () const;

    // Prefix operators
    IA_Point<int>&   operator ++  ();
    IA_Point<int>&   operator --  ();

    // Postfix operators
    IA_Point<int>    operator ++ (int);
    IA_Point<int>    operator -- (int);

    friend double enorm(const IA_Point<int> &p);   // Cartesian distance
    double enorm() const { return (double) ::enorm(*this);}
  
    // Point reduce operations
    friend int sum     (const IA_Point<int> &);
    friend int product (const IA_Point<int> &);

    ////////////////////////////////////////////////////////////
    // L A T T I C E   O P E R A T I O N S
    ////////////////////////////////////////////////////////////

    int    operator <   (const IA_Point<int>&) const;
    int    operator <=  (const IA_Point<int>&) const;
    int    operator >   (const IA_Point<int>&) const;
    int    operator >=  (const IA_Point<int>&) const;
    int    operator ==  (const IA_Point<int>&) const;
    int    operator !=  (const IA_Point<int>&) const;

    int    operator <   (int) const;
    int    operator <=  (int) const;
    int    operator >   (int) const;
    int    operator >=  (int) const;
    int    operator ==  (int) const;
    int    operator !=  (int) const;

    friend  int    operator <   (int, const IA_Point<int>&);
    friend  int    operator <=  (int, const IA_Point<int>&);
    friend  int    operator >   (int, const IA_Point<int>&);
    friend  int    operator >=  (int, const IA_Point<int>&);
    friend  int    operator ==  (int, const IA_Point<int>&);
    friend  int    operator !=  (int, const IA_Point<int>&);

    // Ensure that IntPoints and double arguments are compared
    // without rounding to int issues.
    int    operator <   (double) const;
    int    operator <=  (double) const;
    int    operator >   (double) const;
    int    operator >=  (double) const;
    int    operator ==  (double) const;
    int    operator !=  (double) const;

    friend  int    operator <   (double, const IA_Point<int>&);
    friend  int    operator <=  (double, const IA_Point<int>&);
    friend  int    operator >   (double, const IA_Point<int>&);
    friend  int    operator >=  (double, const IA_Point<int>&);
    friend  int    operator ==  (double, const IA_Point<int>&);
    friend  int    operator !=  (double, const IA_Point<int>&);

    friend  int    pointcmp (const IA_Point<int>&, const IA_Point<int>&);

    ////////////////////////////////////////////////////////////
    // B I T W I S E   O P E R A T I O N S
    ////////////////////////////////////////////////////////////

    IA_Point<int>    operator ~  () const;

    IA_Point<int>&   operator %=  (const IA_Point<int>&);
    IA_Point<int>&   operator <<= (const IA_Point<int>&);
    IA_Point<int>&   operator >>= (const IA_Point<int>&);
    IA_Point<int>&   operator &=  (const IA_Point<int>&);
    IA_Point<int>&   operator ^=  (const IA_Point<int>&);
    IA_Point<int>&   operator |=  (const IA_Point<int>&);

    IA_Point<int>&   operator %=  (int);
    IA_Point<int>&   operator <<= (int);
    IA_Point<int>&   operator >>= (int);
    IA_Point<int>&   operator &=  (int);
    IA_Point<int>&   operator ^=  (int);
    IA_Point<int>&   operator |=  (int);

    IA_Point<int>    operator %  (const IA_Point<int>&) const;
    IA_Point<int>    operator << (const IA_Point<int>&) const;
    IA_Point<int>    operator >> (const IA_Point<int>&) const;
    IA_Point<int>    operator &  (const IA_Point<int>&) const;
    IA_Point<int>    operator ^  (const IA_Point<int>&) const;
    IA_Point<int>    operator |  (const IA_Point<int>&) const;

    IA_Point<int>    operator %  (int) const;
    IA_Point<int>    operator << (int) const;
    IA_Point<int>    operator >> (int) const;
    IA_Point<int>    operator &  (int) const;
    IA_Point<int>    operator ^  (int) const;
    IA_Point<int>    operator |  (int) const;

    friend IA_Point<int>    operator %  (int, const IA_Point<int>&);
    friend IA_Point<int>    operator << (int, const IA_Point<int>&);
    friend IA_Point<int>    operator >> (int, const IA_Point<int>&);
    friend IA_Point<int>    operator &  (int, const IA_Point<int>&);
    friend IA_Point<int>    operator ^  (int, const IA_Point<int>&);
    friend IA_Point<int>    operator |  (int, const IA_Point<int>&);

};

#endif

//below are the ROF or regular old functons, enorm was previously a member function
//it was decided that transducers, would become ROF

// abs will work with double points and int points, fabs will only work with
// double points, to extend the operation of fabs in math.h lib.

IA_Point<int> abs (const IA_Point<int> &p);

int inorm(const IA_Point<int> &p);  
int mnorm(const IA_Point<int> &p);

IA_Point<int> cross(const IA_Point<int> &a, const IA_Point<int> &b);
int dot(const IA_Point<int> &a, const IA_Point<int> &b);
