casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
MVPosition.h
Go to the documentation of this file.
00001 //# MVPosition.h: A 3D vector in space
00002 //# Copyright (C) 1996,1997,1998,1999,2000,2001
00003 //# Associated Universities, Inc. Washington DC, USA.
00004 //#
00005 //# This library is free software; you can redistribute it and/or modify it
00006 //# under the terms of the GNU Library General Public License as published by
00007 //# the Free Software Foundation; either version 2 of the License, or (at your
00008 //# option) any later version.
00009 //#
00010 //# This library is distributed in the hope that it will be useful, but WITHOUT
00011 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00012 //# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
00013 //# License for more details.
00014 //#
00015 //# You should have received a copy of the GNU Library General Public License
00016 //# along with this library; if not, write to the Free Software Foundation,
00017 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
00018 //#
00019 //# Correspondence concerning AIPS++ should be addressed as follows:
00020 //#        Internet email: aips2-request@nrao.edu.
00021 //#        Postal address: AIPS++ Project Office
00022 //#                        National Radio Astronomy Observatory
00023 //#                        520 Edgemont Road
00024 //#                        Charlottesville, VA 22903-2475 USA
00025 //#
00026 //# $Id: MVPosition.h 20551 2009-03-25 00:11:33Z Malte.Marquarding $
00027 
00028 #ifndef CASA_MVPOSITION_H
00029 #define CASA_MVPOSITION_H
00030 
00031 
00032 //# Includes
00033 #include <casa/aips.h>
00034 #include <casa/Arrays/Vector.h>
00035 #include <casa/Quanta/Unit.h>
00036 #include <casa/Quanta/Quantum.h>
00037 #include <casa/Quanta/MeasValue.h>
00038 #include <casa/iosfwd.h>
00039 
00040 namespace casa { //# NAMESPACE CASA - BEGIN
00041 
00042 //# Forward Declarations
00043 class RotMatrix;
00044 
00045 //# Constants (SUN compiler does not accept non-simple default arguments)
00046 
00047 // <summary> A 3D vector in space </summary>
00048 
00049 // <use visibility=export>
00050 
00051 // <reviewed reviewer="tcornwel" date="1996/02/22" tests="tMeasMath" demos="">
00052 // </reviewed>
00053 
00054 // <prerequisite>
00055 //   <li> <linkto class=MeasValue>MeasValue</linkto>
00056 //   <li> <linkto class=Vector>Vector</linkto>
00057 //   <li> <linkto class=Quantum>Quantum</linkto>
00058 // </prerequisite>
00059 //
00060 // <etymology>
00061 // From Measure, Value and Position
00062 // </etymology>
00063 //
00064 // <synopsis>
00065 // A MVPosition is a 3-vector of positions in a rectangular frame with
00066 // internal units of m.<br>
00067 // It can be constructed with:
00068 // <ul>
00069 //   <li> MVPosition() creates point at origin (0,0,0)
00070 //   <li> MVPosition(MVPosition) creates a copy
00071 //   <li> MVPosition(Double, Double, Double) creates (x,y,z) with
00072 //              specified values
00073 //   <li> MVPosition(Quantity length,Double, Double) creates a MVPosition assuming
00074 //              that the two values are (in radians) angle along 'equator' 
00075 //              and towards 'pole'. A length of zero will be made 1um.
00076 //   <li> MVPosition(Quantity length, Quantity, Quantity) creates a MVPosition 
00077 //              assuming angles as in previous, or positions
00078 //   <li> <src>MVPosition(Quantity, Quantum<Vector<Double> >)</src> creates a 
00079 //              MVPosition from angle vector, using first two angles, and 
00080 //              assuming second as zero if not present, and pole if length 0.
00081 //   <li> <src>MVPosition(Quantum<Vector<Double> ></src> creates from
00082 //              angles or positions, depending on the units in the
00083 //              quantum vector. In the angle case,
00084 //              the data derived can be scaled with the readjust() function. If
00085 //              the unit of the quantum vector is length, position is
00086 //              assumed.
00087 //    <li> <src>MVPosition(Vector<Double></src> creates from angles (less than
00088 //              or equal to two elements) or x,y,z (3 elements).
00089 //    <li> <src>MVPosition(Vector<Quantity></src> creates from length+angles,
00090 //              angles, or x,y,z, depending on units.
00091 // </ul>
00092 // A void adjust(Double) function normalises the vector to a length of 1;
00093 // a get() returns as a
00094 // Double 3-vector the length and angles of the position vector;
00095 // a getAngle() returns a Quantum 2-vector, (uInt) returns the indicated 
00096 // element, and getValue returns the vector.<br>
00097 // Positions can be added and subtracted.<br>
00098 // The multiplication of two positions produces the in-product.<br>
00099 // </synopsis>
00100 //
00101 // <example>
00102 // See <linkto class=MPosition>Mposition</linkto> class.
00103 // </example>
00104 //
00105 // <motivation>
00106 // To do coordinate transformations
00107 // </motivation>
00108 //
00109 // <todo asof="1996/02/04">
00110 //      <li> See if not better to have a direction + length
00111 // </todo>
00112 
00113 class MVPosition : public MeasValue {   
00114 
00115 public:
00116   //# Constants
00117   // Internal limts codes for negative height
00118   // <group>
00119   static const Double loLimit;
00120   static const Double hiLimit;
00121   // </group>
00122   //# Friends
00123   
00124   //# Constructors
00125   // Default constructor generates a (0,0,0) position
00126   MVPosition();
00127   // Copy constructor
00128   MVPosition(const MVPosition &other);
00129   // Creates a specified vector
00130   MVPosition(Double in0, Double in1, Double in2);
00131   // Creates a vector with specified length towards pole
00132   // <group>
00133   explicit MVPosition(Double in0);
00134   MVPosition(const Quantity &l);
00135   // </group>
00136   // Creates the position from specified (azimuth,elevation) angles and length
00137   MVPosition(const Quantity &l, Double angle0, Double angle1);
00138   // Creates the position from specified angles and length. or positions
00139   // <thrown>
00140   //    <li> AipsError if quantities not in angle format
00141   // </thrown>
00142   // <group>
00143   MVPosition(const Quantity &l, const Quantity &angle0, 
00144              const Quantity &angle1);
00145   // If not enough angles: pole assumed (if none), or elevation =0 (if 1)
00146   MVPosition(const Quantum<Vector<Double> > &angle);
00147   MVPosition(const Quantity &l, const Quantum<Vector<Double> > &angle);
00148   // </group>
00149   // Create from specified length and/or angles and/or position
00150   // <group>
00151   explicit MVPosition(const Vector<Double> &other);
00152   MVPosition(const Vector<Quantity> &other);
00153   // </group>
00154   // Copy assignment
00155   MVPosition &operator=(const MVPosition &other);
00156   
00157   // Destructor
00158   ~MVPosition();
00159   
00160   //# Operators
00161   // Multiplication defined as in-product
00162   // <group>
00163   Double operator*(const MVPosition &other) const;
00164   // </group>
00165   
00166   // Equality comparisons
00167   // <group>
00168   Bool operator== (const MVPosition &other) const;
00169   Bool operator!= (const MVPosition &other) const;
00170   Bool near(const MVPosition &other, Double tol=1e-13) const;
00171   Bool near(const MVPosition &other, Quantity tol) const;
00172   Bool nearAbs(const MVPosition &other, Double tol=1e-13) const;
00173   // </group>
00174   
00175   // Addition and subtraction
00176   // <group>
00177   MVPosition operator-() const;
00178   MVPosition &operator+=(const MVPosition &right);
00179   MVPosition operator+(const MVPosition &right) const;
00180   MVPosition &operator-=(const MVPosition &right);
00181   MVPosition operator-(const MVPosition &right) const;
00182   // </group>
00183   
00184   // Multiplication with rotation matrix (see also global functions)
00185   // <group>
00186   MVPosition &operator*=(const RotMatrix &right);
00187   // </group>
00188   
00189   // Multiplication with constant
00190   // <group>
00191   MVPosition &operator*=(Double right);
00192   // </group>
00193   
00194   // Obtain an element
00195   // <group>
00196   Double &operator()(uInt which);
00197   const Double &operator()(uInt which) const;
00198   // </group>
00199   
00200   //# General Member Functions
00201   
00202   // Tell me your type
00203   // <group>
00204   virtual uInt type() const;
00205   static void assure(const MeasValue &in);
00206   // </group>
00207   
00208   // Normalise direction aspects by adjusting the length to 1
00209   // <group>
00210   // For position no adjustment; for direction adjustment
00211   virtual void adjust();
00212   // Adjustment with returned factor
00213   virtual void adjust(Double &res);
00214   // Re-adjust using factor given
00215   virtual void readjust(Double res);
00216   // </group>
00217   // Get radius of position
00218   virtual Double radius();
00219   // Generate a 3-vector of coordinates (length(m), angles(rad))
00220   Vector<Double> get() const;
00221   // Generate a 3-vector of x,y,z in m
00222   const Vector<Double> &getValue() const;
00223   // Generate angle 2-vector (in rad)
00224   Quantum<Vector<Double> > getAngle() const;
00225   // and with specified units
00226   Quantum<Vector<Double> > getAngle(const Unit &unit) const;
00227   // Get the longitudinal angle (in radians)
00228   Double getLong() const;
00229   // and with specified units
00230   Quantity getLong(const Unit &unit) const;
00231   // Get the latitude angle (rad)
00232   Double getLat() const;
00233   // and with specified units
00234   Quantity getLat(const Unit &unit) const;
00235   // Generate the length
00236   Quantity getLength() const;
00237   // and generate it with the specified units
00238   Quantity getLength(const Unit &unit) const;
00239   // Get the position angle between the directions. I.e. the angle between
00240   // the direction from one to the pole, and from one to the other.
00241   // <group>
00242   Double positionAngle(const MVPosition &other) const;
00243   Quantity positionAngle(const MVPosition &other, 
00244                          const Unit &unit) const;
00245   // </group>
00246   // Get the angular separation between two directions.
00247   // <group>
00248   Double separation(const MVPosition &other) const;
00249   Quantity separation(const MVPosition &other, 
00250                       const Unit &unit) const;
00251   // </group>
00252   // Produce the cross product
00253   MVPosition crossProduct(const MVPosition &other) const;
00254   
00255   // Print data
00256   virtual void print(ostream &os) const;
00257   // Clone
00258   virtual MeasValue *clone() const;
00259 
00260   // Get the value in internal units
00261   virtual Vector<Double> getVector() const;
00262   // Set the value from internal units (set 0 for empty vector)
00263   virtual void putVector(const Vector<Double> &in);
00264   // Get the internal value as a <src>Vector<Quantity></src>. Usable in
00265   // records. The getXRecordValue() gets additional information for records.
00266   // Note that the Vectors could be empty.
00267   // <group>
00268   virtual Vector<Quantum<Double> > getRecordValue() const;
00269   virtual Vector<Quantum<Double> > getXRecordValue() const;
00270   virtual Vector<Quantum<Double> > getTMRecordValue() const {
00271     return getXRecordValue(); } ;
00272   // </group>
00273   // Set the internal value if correct values and dimensions
00274   virtual Bool putValue(const Vector<Quantum<Double> > &in);
00275   
00276 protected:
00277   //# Member functions
00278   // Get the latitude assuming length is given
00279   Double getLat(Double ln) const;
00280   //# Data
00281   // Position vector (in m)
00282   Vector<Double> xyz;
00283 };
00284 
00285 //# Global functions
00286 // Rotate a position vector with rotation matrix and other multiplications
00287 // <group>
00288 MVPosition operator*(const RotMatrix &left, const MVPosition &right);
00289 MVPosition operator*(const MVPosition &left, const RotMatrix &right);
00290 MVPosition operator*(Double left, const MVPosition &right);
00291 MVPosition operator*(const MVPosition &left, Double right);
00292 Double operator*(const Vector<Double> &left, const MVPosition &right);
00293 Double operator*(const MVPosition &left, const Vector<Double> &right);
00294 // </group>
00295 
00296 
00297 } //# NAMESPACE CASA - END
00298 
00299 #endif