17 #ifndef ROOT_Math_GenVector_Plane3D
18 #define ROOT_Math_GenVector_Plane3D 1
20 #include <type_traits>
50 template <
typename T =
double>
58 typedef DisplacementVector3D<Cartesian3D<T>, DefaultCoordinateSystemTag> Vector;
59 typedef PositionVector3D<Cartesian3D<T>, DefaultCoordinateSystemTag> Point;
64 Plane3D() : fA(0), fB(0), fC(1), fD(0) {}
74 Plane3D(
const Scalar &a,
const Scalar &b,
const Scalar &c,
const Scalar &d) : fA(a), fB(b), fC(c), fD(d)
85 Plane3D(
const Vector &n,
const Point &p) { BuildFromVecAndPoint(n, p); }
93 template <
class T1,
class T2,
class U>
94 Plane3D(
const DisplacementVector3D<T1, U> &n,
const PositionVector3D<T2, U> &p)
96 BuildFromVecAndPoint(Vector(n), Point(p));
105 Plane3D(
const Point &p1,
const Point &p2,
const Point &p3) { BuildFrom3Points(p1, p2, p3); }
113 template <
class T1,
class T2,
class T3,
class U>
114 Plane3D(
const PositionVector3D<T1, U> &p1,
const PositionVector3D<T2, U> &p2,
const PositionVector3D<T3, U> &p3)
116 BuildFrom3Points(Point(p1.X(), p1.Y(), p1.Z()), Point(p2.X(), p2.Y(), p2.Z()), Point(p3.X(), p3.Y(), p3.Z()));
120 Plane3D(
const Plane3D &) =
default;
127 Plane3D &operator=(
const Plane3D &) =
default;
133 Scalar A()
const {
return fA; }
139 Scalar B()
const {
return fB; }
145 Scalar C()
const {
return fC; }
151 Scalar D()
const {
return fD; }
156 Vector Normal()
const {
return Vector(fA, fB, fC); }
162 Scalar HesseDistance()
const {
return fD; }
170 Scalar Distance(
const Point &p)
const {
return fA * p.X() + fB * p.Y() + fC * p.Z() + fD; }
176 template <
class T1,
class U>
177 Scalar Distance(
const PositionVector3D<T1, U> &p)
const
179 return Distance(Point(p.X(), p.Y(), p.Z()));
186 Point ProjectOntoPlane(
const Point &p)
const
188 const Scalar d = Distance(p);
189 return XYZPoint(p.X() - fA * d, p.Y() - fB * d, p.Z() - fC * d);
196 template <
class T1,
class U>
197 PositionVector3D<T1, U> ProjectOntoPlane(
const PositionVector3D<T1, U> &p)
const
199 const Point pxyz = ProjectOntoPlane(Point(p.X(), p.Y(), p.Z()));
200 return PositionVector3D<T, U>(pxyz.X(), pxyz.Y(), pxyz.Z());
208 bool operator==(
const Plane3D &rhs)
const {
return (fA == rhs.fA && fB == rhs.fB && fC == rhs.fC && fD == rhs.fD); }
209 bool operator!=(
const Plane3D &rhs)
const {
return !(operator==(rhs)); }
215 template <typename SCALAR = T, typename std::enable_if<std::is_arithmetic<SCALAR>::value>::type * =
nullptr>
219 const SCALAR s = sqrt(fA * fA + fB * fB + fC * fC);
221 if (s == SCALAR(0)) {
224 const SCALAR w = Scalar(1) / s;
235 template <typename SCALAR = T, typename std::enable_if<!std::is_arithmetic<SCALAR>::value>::type * =
nullptr>
239 SCALAR s = sqrt(fA * fA + fB * fB + fC * fC);
241 const auto m = (s == SCALAR(0));
245 const SCALAR w = SCALAR(1) / s;
254 void BuildFromVecAndPoint(
const Vector &n,
const Point &p)
265 void BuildFrom3Points(
const Point &p1,
const Point &p2,
const Point &p3)
269 const Vector n = (p2 - p1).Cross(p3 - p1);
291 template <
typename T>
292 std::ostream &operator<<(std::ostream &os, const Plane3D<T> &p)
295 << p.Normal().X() <<
" " << p.Normal().Y() <<
" " << p.Normal().Z() <<
" " << p.HesseDistance() <<
"\n";
302 typedef Impl::Plane3D<double> Plane3D;
303 typedef Impl::Plane3D<float> Plane3DF;