// @(#)root/mathcore:$Id$
// Authors: L. Moneta    12/2005

/**********************************************************************
*                                                                    *
* Copyright (c) 2005 , LCG ROOT MathLib Team                         *
*                                                                    *
*                                                                    *
**********************************************************************/

// Header file for class LorentzVector
//
// Created by:    moneta   at Fri Dec 02   2005
//
// Last update: $Id$
//
#ifndef ROOT_Math_GenVector_Plane3D
#define ROOT_Math_GenVector_Plane3D  1

#include "Math/GenVector/DisplacementVector3D.h"
#include "Math/GenVector/PositionVector3D.h"

namespace ROOT {

namespace Math {

//_______________________________________________________________________________
/**
Class describing a geometrical plane in 3 dimensions.
A Plane3D is a 2 dimensional surface spanned by two linearly independent vectors.
The plane is described by the equation
\f$a*x + b*y + c*z + d = 0 \f$ where (a,b,c) are the components of the
normal vector to the plane \f$n = (a,b,c) \f$ and \f$d = - n \dot x \f$, where x is any point
belonging to plane.
More information on the mathematics describing a plane in 3D is available on
<A HREF=http://mathworld.wolfram.com/Plane.html>MathWord</A>.
The Plane3D class contains the 4 scalar values in double which represent the
four coefficients, fA, fB, fC, fD. fA, fB, fC are the normal components normalized to 1,
i.e. fA**2 + fB**2 + fC**2 = 1

@ingroup GenVector
*/
class Plane3D {

public:

// ------ ctors ------

typedef double Scalar;

typedef  DisplacementVector3D<Cartesian3D<double>, DefaultCoordinateSystemTag > Vector;
typedef  PositionVector3D<Cartesian3D<double>, DefaultCoordinateSystemTag >     Point;

/**
default constructor create plane z = 0
*/
Plane3D ( ) : fA(0), fB(0), fC(1.), fD(0) { }

/**
generic constructors from the four scalar values describing the plane
according to the equation ax + by + cz + d = 0
\param a scalar value
\param b scalar value
\param c scalar value
\param d sxcalar value
*/
Plane3D(const Scalar & a, const Scalar & b, const Scalar & c, const Scalar & d);

/**
constructor a Plane3D from a normal vector and a point coplanar to the plane
\param n normal expressed as a ROOT::Math::DisplacementVector3D<Cartesian3D<double> >
\param p point  expressed as a  ROOT::Math::PositionVector3D<Cartesian3D<double> >
*/
Plane3D(const Vector & n, const Point & p )
{
BuildFromVecAndPoint( n, p );
}

/**
Construct from a generic DisplacementVector3D (normal vector) and PositionVector3D (point coplanar to
the plane)
\param n normal expressed as a generic ROOT::Math::DisplacementVector3D
\param p point  expressed as a generic ROOT::Math::PositionVector3D
*/
template<class T1, class T2, class U>
Plane3D( const  DisplacementVector3D<T1,U> & n, const  PositionVector3D<T2,U> & p)
{
BuildFromVecAndPoint( Vector(n), Point(p) );
}

/**
constructor from three Cartesian point belonging to the plane
\param p1 point1  expressed as a generic ROOT::Math::PositionVector3D
\param p2 point2  expressed as a generic ROOT::Math::PositionVector3D
\param p3 point3  expressed as a generic ROOT::Math::PositionVector3D
*/
Plane3D(const Point & p1, const Point & p2, const Point & p3  ) {
BuildFrom3Points(p1,p2,p3);
}

/**
constructor from three generic point belonging to the plane
\param p1 point1 expressed as  ROOT::Math::DisplacementVector3D<Cartesian3D<double> >
\param p2 point2 expressed as  ROOT::Math::DisplacementVector3D<Cartesian3D<double> >
\param p3 point3 expressed as  ROOT::Math::DisplacementVector3D<Cartesian3D<double> >
*/
template <class T1, class T2, class T3, class U>
Plane3D(const  PositionVector3D<T1,U> & p1, const  PositionVector3D<T2,U> & p2, const  PositionVector3D<T3,U> & p3  )
{
BuildFrom3Points( Point(p1.X(), p1.Y(), p1.Z()),
Point(p2.X(), p2.Y(), p2.Z()),
Point(p3.X(), p3.Y(), p3.Z()) );
}

// compiler-generated copy ctor and dtor are fine.

// ------ assignment ------

/**
Assignment operator from other Plane3D class
*/
Plane3D & operator= ( const Plane3D & plane) {
fA = plane.fA;
fB = plane.fB;
fC = plane.fC;
fD = plane.fD;
return *this;
}

/**
Return the a coefficient of the plane equation \f$a*x + b*y + c*z + d = 0 \f$. It is also the
x-component of the vector perpendicular to the plane.
*/
Scalar A() { return fA; }

/**
Return the b coefficient of the plane equation \f$a*x + b*y + c*z + d = 0 \f$. It is also the
y-component of the vector perpendicular to the plane
*/
Scalar B() { return fB; }

/**
Return the c coefficient of the plane equation \f$a*x + b*y + c*z + d = 0 \f$. It is also the
z-component of the vector perpendicular to the plane
*/
Scalar C() { return fC; }

/**
Return the d coefficient of the plane equation \f$a*x + b*y + c*z + d = 0 \f$. It is also
the distance from the origin (HesseDistance)
*/
Scalar D() { return fD; }

/**
Return normal vector to the plane as Cartesian DisplacementVector
*/
Vector Normal() const {
return Vector(fA, fB, fC);
}

/**
Return the Hesse Distance (distance from the origin) of the plane or
the d coefficient expressed in normalize form
*/
Scalar HesseDistance() const {
return fD;
}

/**
Return the signed distance to a Point.
The distance is signed positive if the Point is in the same side of the
normal vector to the plane.
\param p Point expressed in Cartesian Coordinates
*/
Scalar Distance(const Point & p) const;

/**
Return the distance to a Point described with generic coordinates
\param p Point expressed as generic ROOT::Math::PositionVector3D
*/
template <class T, class U>
Scalar Distance(const PositionVector3D<T,U> & p) const {
return Distance( Point(p.X(), p.Y(), p.Z() ) );
}

/**
Return the projection of a Cartesian point to a plane
\param p Point expressed as PositionVector3D<Cartesian3D<double> >
*/
Point ProjectOntoPlane(const Point & p) const;

/**
Return the projection of a point to a plane
\param p Point expressed as generic ROOT::Math::PositionVector3D
*/
template <class T, class U>
PositionVector3D<T,U> ProjectOntoPlane(const PositionVector3D<T,U> & p) const {
Point pxyz = ProjectOntoPlane(Point(p.X(), p.Y(), p.Z() ) );
PositionVector3D<T,U> p2;
p2.SetXYZ( pxyz.X(), pxyz.Y(), pxyz.Z() );
return p2;
}

// ------------------- Equality -----------------

/**
Exact equality
*/
bool operator==(const Plane3D & rhs) const {
return  fA  == rhs.fA &&  fB == rhs.fB  &&  fC == rhs.fC && fD == rhs.fD;
}
bool operator!= (const Plane3D & rhs) const {
return !(operator==(rhs));
}

protected:

/**
Normalize the normal (a,b,c) plane components
*/
void Normalize();

private:

// internal method to construct class from a vector and a point
void BuildFromVecAndPoint(const Vector & n, const Point & p);
// internal method to construct class from 3 points
void BuildFrom3Points(const Point & p1, const Point & p2, const Point & p3);

// plane data members the four scalar which  satisfies fA*x + fB*y + fC*z + fD = 0
// for every point (x,y,z) belonging to the plane.
// fA**2 + fB**2 + fC** =1 plane is stored in normalized form
Scalar  fA;
Scalar  fB;
Scalar  fC;
Scalar  fD;

};  // Plane3D<>

/**
Stream Output and Input
*/
// TODO - I/O should be put in the manipulator form

std::ostream & operator<< (std::ostream & os, const Plane3D & p);

} // end namespace Math

} // end namespace ROOT

#endif


Plane3D.h:1
Plane3D.h:2
Plane3D.h:3
Plane3D.h:4
Plane3D.h:5
Plane3D.h:6
Plane3D.h:7
Plane3D.h:8
Plane3D.h:9
Plane3D.h:10
Plane3D.h:11
Plane3D.h:12
Plane3D.h:13
Plane3D.h:14
Plane3D.h:15
Plane3D.h:16
Plane3D.h:17
Plane3D.h:18
Plane3D.h:19
Plane3D.h:20
Plane3D.h:21
Plane3D.h:22
Plane3D.h:23
Plane3D.h:24
Plane3D.h:25
Plane3D.h:26
Plane3D.h:27
Plane3D.h:28
Plane3D.h:29
Plane3D.h:30
Plane3D.h:31
Plane3D.h:32
Plane3D.h:33
Plane3D.h:34
Plane3D.h:35
Plane3D.h:36
Plane3D.h:37
Plane3D.h:38
Plane3D.h:39
Plane3D.h:40
Plane3D.h:41
Plane3D.h:42
Plane3D.h:43
Plane3D.h:44
Plane3D.h:45
Plane3D.h:46
Plane3D.h:47
Plane3D.h:48
Plane3D.h:49
Plane3D.h:50
Plane3D.h:51
Plane3D.h:52
Plane3D.h:53
Plane3D.h:54
Plane3D.h:55
Plane3D.h:56
Plane3D.h:57
Plane3D.h:58
Plane3D.h:59
Plane3D.h:60
Plane3D.h:61
Plane3D.h:62
Plane3D.h:63
Plane3D.h:64
Plane3D.h:65
Plane3D.h:66
Plane3D.h:67
Plane3D.h:68
Plane3D.h:69
Plane3D.h:70
Plane3D.h:71
Plane3D.h:72
Plane3D.h:73
Plane3D.h:74
Plane3D.h:75
Plane3D.h:76
Plane3D.h:77
Plane3D.h:78
Plane3D.h:79
Plane3D.h:80
Plane3D.h:81
Plane3D.h:82
Plane3D.h:83
Plane3D.h:84
Plane3D.h:85
Plane3D.h:86
Plane3D.h:87
Plane3D.h:88
Plane3D.h:89
Plane3D.h:90
Plane3D.h:91
Plane3D.h:92
Plane3D.h:93
Plane3D.h:94
Plane3D.h:95
Plane3D.h:96
Plane3D.h:97
Plane3D.h:98
Plane3D.h:99
Plane3D.h:100
Plane3D.h:101
Plane3D.h:102
Plane3D.h:103
Plane3D.h:104
Plane3D.h:105
Plane3D.h:106
Plane3D.h:107
Plane3D.h:108
Plane3D.h:109
Plane3D.h:110
Plane3D.h:111
Plane3D.h:112
Plane3D.h:113
Plane3D.h:114
Plane3D.h:115
Plane3D.h:116
Plane3D.h:117
Plane3D.h:118
Plane3D.h:119
Plane3D.h:120
Plane3D.h:121
Plane3D.h:122
Plane3D.h:123
Plane3D.h:124
Plane3D.h:125
Plane3D.h:126
Plane3D.h:127
Plane3D.h:128
Plane3D.h:129
Plane3D.h:130
Plane3D.h:131
Plane3D.h:132
Plane3D.h:133
Plane3D.h:134
Plane3D.h:135
Plane3D.h:136
Plane3D.h:137
Plane3D.h:138
Plane3D.h:139
Plane3D.h:140
Plane3D.h:141
Plane3D.h:142
Plane3D.h:143
Plane3D.h:144
Plane3D.h:145
Plane3D.h:146
Plane3D.h:147
Plane3D.h:148
Plane3D.h:149
Plane3D.h:150
Plane3D.h:151
Plane3D.h:152
Plane3D.h:153
Plane3D.h:154
Plane3D.h:155
Plane3D.h:156
Plane3D.h:157
Plane3D.h:158
Plane3D.h:159
Plane3D.h:160
Plane3D.h:161
Plane3D.h:162
Plane3D.h:163
Plane3D.h:164
Plane3D.h:165
Plane3D.h:166
Plane3D.h:167
Plane3D.h:168
Plane3D.h:169
Plane3D.h:170
Plane3D.h:171
Plane3D.h:172
Plane3D.h:173
Plane3D.h:174
Plane3D.h:175
Plane3D.h:176
Plane3D.h:177
Plane3D.h:178
Plane3D.h:179
Plane3D.h:180
Plane3D.h:181
Plane3D.h:182
Plane3D.h:183
Plane3D.h:184
Plane3D.h:185
Plane3D.h:186
Plane3D.h:187
Plane3D.h:188
Plane3D.h:189
Plane3D.h:190
Plane3D.h:191
Plane3D.h:192
Plane3D.h:193
Plane3D.h:194
Plane3D.h:195
Plane3D.h:196
Plane3D.h:197
Plane3D.h:198
Plane3D.h:199
Plane3D.h:200
Plane3D.h:201
Plane3D.h:202
Plane3D.h:203
Plane3D.h:204
Plane3D.h:205
Plane3D.h:206
Plane3D.h:207
Plane3D.h:208
Plane3D.h:209
Plane3D.h:210
Plane3D.h:211
Plane3D.h:212
Plane3D.h:213
Plane3D.h:214
Plane3D.h:215
Plane3D.h:216
Plane3D.h:217
Plane3D.h:218
Plane3D.h:219
Plane3D.h:220
Plane3D.h:221
Plane3D.h:222
Plane3D.h:223
Plane3D.h:224
Plane3D.h:225
Plane3D.h:226
Plane3D.h:227
Plane3D.h:228
Plane3D.h:229
Plane3D.h:230
Plane3D.h:231
Plane3D.h:232
Plane3D.h:233
Plane3D.h:234
Plane3D.h:235
Plane3D.h:236
Plane3D.h:237
Plane3D.h:238
Plane3D.h:239
Plane3D.h:240
Plane3D.h:241
Plane3D.h:242
Plane3D.h:243
Plane3D.h:244
Plane3D.h:245
Plane3D.h:246
Plane3D.h:247
Plane3D.h:248
Plane3D.h:249
Plane3D.h:250
Plane3D.h:251
Plane3D.h:252
Plane3D.h:253
Plane3D.h:254
Plane3D.h:255
Plane3D.h:256
Plane3D.h:257
Plane3D.h:258
Plane3D.h:259
Plane3D.h:260
Plane3D.h:261
Plane3D.h:262
Plane3D.h:263
Plane3D.h:264
Plane3D.h:265
Plane3D.h:266
Plane3D.h:267
Plane3D.h:268
Plane3D.h:269
Plane3D.h:270
Plane3D.h:271