00001
00002
00003 #include "geom/Line.hpp"
00004 #include "geom/Point.hpp"
00005
00006 namespace jafar {
00007 namespace geom {
00008
00009 template<int dimension>
00010 HyperPlane<dimension>::EquationDriver::EquationDriver(const VecD& eqn, double d, const RepereD* reference ) : Driver(), m_reference(reference)
00011 {
00012 double norm = ublas::norm_2(eqn);
00013 ublas::subrange(m_eqn, 0, dimension ) = eqn;
00014 m_eqn(dimension) = d;
00015 m_eqn /= norm;
00016 }
00017 template<int dimension>
00018 HyperPlane<dimension>::EquationDriver::EquationDriver(const HomogenousVecD& eqn, const RepereD* reference ) : Driver(), m_reference(reference)
00019 {
00020 double norm = ublas::norm_2( ublas::subrange(eqn, 0, dimension) );
00021 m_eqn = eqn / norm;
00022 }
00023 template<int dimension>
00024 typename HyperPlane<dimension>::HomogenousVecD HyperPlane<dimension>::EquationDriver::origin() const
00025 {
00026 HomogenousVecD v = - m_eqn(dimension) * normal();
00027 v(dimension) = 1.0;
00028 return v;
00029 }
00030 template<int dimension>
00031 typename HyperPlane<dimension>::HomogenousSymMatrixD HyperPlane<dimension>::EquationDriver::originCov() const
00032 {
00033 JFR_ERROR(GeomException, GeomException::Unimplemented, "Unimplemented." );
00034 return HomogenousSymMatrixD();
00035 }
00036 template<int dimension>
00037 typename HyperPlane<dimension>::HomogenousVecD HyperPlane<dimension>::EquationDriver::normal() const
00038 {
00039 HomogenousVecD v = m_eqn;
00040 v(dimension) = 0.0;
00041 return v;
00042 }
00043 template<int dimension>
00044 typename HyperPlane<dimension>::HomogenousSymMatrixD HyperPlane<dimension>::EquationDriver::normalCov() const
00045 {
00046 JFR_ERROR(GeomException, GeomException::Unimplemented, "Unimplemented." );
00047 return HomogenousSymMatrixD();
00048 }
00049 template<int dimension>
00050 typename HyperPlane<dimension>::HomogenousVecD HyperPlane<dimension>::EquationDriver::equation() const
00051 {
00052 return m_eqn;
00053 }
00054 template<int dimension>
00055 void HyperPlane<dimension>::EquationDriver::changeReference( const RepereD* reference )
00056 {
00057 typename Atom<dimension>::HomogenousMatrixD m;
00058
00059 reference->localToRepere(m, this->m_reference);
00060
00061 typename Atom<dimension>::HomogenousMatrixD mt;
00062
00063 mt = ublas::trans( m );
00064
00065 m_eqn = ublas::prod(mt, m_eqn);
00066
00067 double norm = ublas::norm_2( ublas::subrange(m_eqn, 0, dimension) );
00068 m_eqn /= norm;
00069 this->m_reference = reference;
00070 }
00071 template<int dimension>
00072 const Repere<dimension>* HyperPlane<dimension>::EquationDriver::reference( ) const
00073 {
00074 return m_reference;
00075 }
00076 template<int dimension>
00077 typename HyperPlane<dimension>::Driver* HyperPlane<dimension>::EquationDriver::clone( ) const
00078 {
00079 return new EquationDriver( m_eqn, this->reference() );
00080 }
00081
00082 template<int dimension>
00083 HyperPlane<dimension>::VectorsDriver::VectorsDriver(const HomogenousVecD& origin, const HomogenousVecD& normal, const RepereD* reference ) : Driver(), m_origin(origin), m_normal(normal / ublas::norm_2(normal)), m_reference(reference), m_hasCov(false)
00084 {
00085 }
00086 template<int dimension>
00087 HyperPlane<dimension>::VectorsDriver::VectorsDriver(const VecD& origin, const VecD& normal, const RepereD* reference ) : Driver(), m_reference(reference), m_hasCov(false)
00088 {
00089 m_origin(dimension) = 1.0;
00090 ublas::subrange(m_origin, 0, dimension ) = origin;
00091 m_normal(dimension) = 0.0;
00092 ublas::subrange(m_normal, 0, dimension ) = normal / ublas::norm_2(normal);
00093 }
00094 template<int dimension>
00095 void HyperPlane<dimension>::VectorsDriver::setCov(HomogenousSymMatrixD _originCov, HomogenousSymMatrixD _normalCov)
00096 {
00097 m_originCov = _originCov;
00098 m_normalCov = _normalCov;
00099 m_hasCov = true;
00100 }
00101 template<int dimension>
00102 typename HyperPlane<dimension>::HomogenousVecD HyperPlane<dimension>::VectorsDriver::origin() const
00103 {
00104 return m_origin;
00105 }
00106 template<int dimension>
00107 typename HyperPlane<dimension>::HomogenousSymMatrixD HyperPlane<dimension>::VectorsDriver::originCov() const
00108 {
00109 return m_originCov;
00110 }
00111 template<int dimension>
00112 typename HyperPlane<dimension>::HomogenousVecD HyperPlane<dimension>::VectorsDriver::normal() const
00113 {
00114 return m_normal;
00115 }
00116 template<int dimension>
00117 typename HyperPlane<dimension>::HomogenousSymMatrixD HyperPlane<dimension>::VectorsDriver::normalCov() const
00118 {
00119 return m_normalCov;
00120 }
00121 template<int dimension>
00122 typename HyperPlane<dimension>::HomogenousVecD HyperPlane<dimension>::VectorsDriver::equation() const
00123 {
00124 HomogenousVecD eqn;
00125 ublas::subrange(eqn, 0, dimension ) = ublas::subrange(m_normal, 0, dimension );
00126 eqn(dimension) = - ublas::inner_prod(ublas::subrange(eqn, 0, dimension ), ublas::subrange(m_origin, 0, dimension));
00127 return eqn;
00128 }
00129 template<int dimension>
00130 void HyperPlane<dimension>::VectorsDriver::changeReference( const RepereD* reference )
00131 {
00132 typename Atom<dimension>::HomogenousMatrixD m;
00133 this->m_reference->localToRepere(m, reference);
00134 m_normal = ublas::prod(m, m_normal);
00135 m_normal /= ublas::norm_2(m_normal);
00136 m_origin = ublas::prod(m, m_origin);
00137 m_origin /= m_origin(dimension);
00138 this->m_reference = reference;
00139 }
00140 template<int dimension>
00141 const Repere<dimension>* HyperPlane<dimension>::VectorsDriver::reference( ) const
00142 {
00143 return m_reference;
00144 }
00145 template<int dimension>
00146 typename HyperPlane<dimension>::Driver* HyperPlane<dimension>::VectorsDriver::clone( ) const
00147 {
00148 return new VectorsDriver( m_origin, m_normal, this->reference() );
00149 }
00150
00151 template<int dimension>
00152 HyperPlane<dimension>::HyperPlane(Driver* d) : Atom<dimension>(d), m_driver(d)
00153 {}
00154 template<int dimension>
00155 HyperPlane<dimension>::HyperPlane(const HyperPlane& hp) : Atom<dimension>(0), m_driver( hp.m_driver->clone() )
00156 {
00157 Atom<dimension>::setDriver( m_driver );
00158 this->setId( hp.id() );
00159 }
00160 template<int dimension>
00161 HyperPlane<dimension>::~HyperPlane()
00162 {
00163 }
00164 template<int dimension>
00165 inline typename HyperPlane<dimension>::HomogenousVecD HyperPlane<dimension>::origin() const
00166 {
00167 return m_driver->origin();
00168 }
00169 template<int dimension>
00170 inline typename HyperPlane<dimension>::HomogenousVecD HyperPlane<dimension>::normal() const
00171 {
00172 return m_driver->normal();
00173 }
00174 template<int dimension>
00175 inline typename HyperPlane<dimension>::HomogenousSymMatrixD HyperPlane<dimension>::normalCov() const
00176 {
00177 return m_driver->normalCov();
00178 }
00179 template<int dimension>
00180 inline typename HyperPlane<dimension>::HomogenousVecD HyperPlane<dimension>::equation() const
00181 {
00182 return m_driver->equation();
00183 }
00184 template<int dimension>
00185 typename HyperPlane<dimension>::HomogenousVecD HyperPlane<dimension>::projectionVector(const HomogenousVecD& p) const
00186 {
00187 return - ublas::inner_prod(p - origin(), normal()) * normal();
00188 }
00189 template<int dimension>
00190 void HyperPlane<dimension>::projectionVectorCov(const HomogenousVecD& p, const HomogenousSymMatrixD& pCov, HomogenousVecD& vec, HomogenousSymMatrixD& cov) const
00191 {
00192 HomogenousMatrixD Jp, Jo, Jn;
00193 HomogenousVecD n = normal();
00194 HomogenousVecD o = origin();
00195
00196 Jp = ublas::outer_prod( n, n );
00197
00198 Jo = -Jp;
00199
00200 Jn = ublas::outer_prod( n, vec - n );
00201 double ip = ublas::inner_prod( n, vec - o );
00202 ublas::subrange(Jn, 0, 3, 0, 3 ) += jblas::identity_mat( 3, 3) * ip;
00203
00204 vec = -ip * n;
00205 cov = ublas::prod( Jp, HomogenousMatrixD( ublas::prod( cov, ublas::trans(Jp) ) ) )
00206 + ublas::prod( Jo, HomogenousMatrixD( ublas::prod( m_driver->originCov(), ublas::trans(Jo) ) ) )
00207 + ublas::prod( Jn, HomogenousMatrixD( ublas::prod( m_driver->normalCov(), ublas::trans(Jn) ) ) );
00208 }
00209 template<int dimension>
00210 void HyperPlane<dimension>::projectionVectorCov(const Point<dimension>& p, HomogenousVecD& vec, HomogenousSymMatrixD& cov) const
00211 {
00212 projectionVectorCov(p.homogenousCoordinates(), p.homogenousCoordinatesCov(), vec, cov );
00213 }
00214 template<int dimension>
00215 typename HyperPlane<dimension>::HomogenousVecD HyperPlane<dimension>::project(const HomogenousVecD& p) const
00216 {
00217 return p + projectionVector(p);
00218 }
00219 template<int dimension>
00220 void HyperPlane<dimension>::setDriver(Driver* driver)
00221 {
00222 m_driver = driver;
00223 Atom<dimension>::setDriver(driver);
00224 }
00225 template<int dimension>
00226 inline BoundingBox<dimension> HyperPlane<dimension>::boundingBox() const
00227 {
00228 return BoundingBox<dimension>();
00229 }
00230 }
00231 }