408 lines
9.0 KiB
C++
408 lines
9.0 KiB
C++
//
|
|
// ********************************************************************
|
|
// * This Software is part of the AIDA Unified Solids Library package *
|
|
// * See: https://aidasoft.web.cern.ch/USolids *
|
|
// ********************************************************************
|
|
//
|
|
// $Id:$
|
|
//
|
|
// --------------------------------------------------------------------
|
|
//
|
|
// UVector2
|
|
//
|
|
// Class description:
|
|
//
|
|
// UVector2 is a general 2-vector class defining vectors in two
|
|
// dimension using double components.
|
|
//
|
|
// 19.09.12 Marek Gayer
|
|
// Created from original implementation in CLHEP
|
|
// --------------------------------------------------------------------
|
|
|
|
#ifndef UVECTOR2_H
|
|
#define UVECTOR2_H
|
|
|
|
#include <cmath>
|
|
#include <iostream>
|
|
|
|
#include "UVector3.hh"
|
|
|
|
// Declarations of classes and global methods
|
|
class UVector2;
|
|
std::ostream& operator << (std::ostream&, const UVector2&);
|
|
//std::istream & operator >> (std::istream &, UVector2 &);
|
|
inline double operator * (const UVector2& a, const UVector2& b);
|
|
inline UVector2 operator * (const UVector2& p, double a);
|
|
inline UVector2 operator * (double a, const UVector2& p);
|
|
UVector2 operator / (const UVector2& p, double a);
|
|
inline UVector2 operator + (const UVector2& a, const UVector2& b);
|
|
inline UVector2 operator - (const UVector2& a, const UVector2& b);
|
|
|
|
/**
|
|
* @author
|
|
* @ingroup vector
|
|
*/
|
|
class UVector2
|
|
{
|
|
|
|
public:
|
|
|
|
enum { X = 0, Y = 1, NUM_COORDINATES = 2, SIZE = NUM_COORDINATES };
|
|
// Safe indexing of the coordinates when using with matrices, arrays, etc.
|
|
|
|
inline UVector2(double x = 0.0, double y = 0.0);
|
|
// The constructor.
|
|
|
|
inline UVector2(const UVector2& p);
|
|
// The copy constructor.
|
|
|
|
explicit UVector2(const UVector3& s);
|
|
// "demotion" constructor"
|
|
// WARNING -- THIS IGNORES THE Z COMPONENT OF THE UVector3.
|
|
// SO IN GENERAL, UVector2(v)==v WILL NOT HOLD!
|
|
|
|
inline ~UVector2();
|
|
// The destructor.
|
|
|
|
// inline double x() const;
|
|
// inline double y() const;
|
|
// The components in cartesian coordinate system.
|
|
|
|
double operator()(int i) const;
|
|
inline double operator [](int i) const;
|
|
// Get components by index. 0-based.
|
|
|
|
double& operator()(int i);
|
|
inline double& operator [](int i);
|
|
// Set components by index. 0-based.
|
|
|
|
inline void setX(double x);
|
|
inline void setY(double y);
|
|
inline void set(double x, double y);
|
|
// Set the components in cartesian coordinate system.
|
|
|
|
inline double phi() const;
|
|
// The azimuth angle.
|
|
|
|
inline double mag2() const;
|
|
// The magnitude squared.
|
|
|
|
inline double mag() const;
|
|
// The magnitude.
|
|
|
|
inline double r() const;
|
|
// r in polar coordinates (r, phi): equal to mag().
|
|
|
|
inline void setPhi(double phi);
|
|
// Set phi keeping mag constant.
|
|
|
|
inline void setMag(double r);
|
|
// Set magnitude keeping phi constant.
|
|
|
|
inline void setR(double r);
|
|
// Set R keeping phi constant. Same as setMag.
|
|
|
|
inline void setPolar(double r, double phi);
|
|
// Set by polar coordinates.
|
|
|
|
inline UVector2& operator = (const UVector2& p);
|
|
// Assignment.
|
|
|
|
inline bool operator == (const UVector2& v) const;
|
|
inline bool operator != (const UVector2& v) const;
|
|
// Comparisons.
|
|
|
|
int compare(const UVector2& v) const;
|
|
bool operator > (const UVector2& v) const;
|
|
bool operator < (const UVector2& v) const;
|
|
bool operator>= (const UVector2& v) const;
|
|
bool operator<= (const UVector2& v) const;
|
|
// dictionary ordering according to y, then x component
|
|
|
|
static inline double getTolerance();
|
|
static double setTolerance(double tol);
|
|
|
|
double howNear(const UVector2& p) const;
|
|
bool isNear(const UVector2& p, double epsilon = tolerance) const;
|
|
|
|
double howParallel(const UVector2& p) const;
|
|
bool isParallel
|
|
(const UVector2& p, double epsilon = tolerance) const;
|
|
|
|
double howOrthogonal(const UVector2& p) const;
|
|
bool isOrthogonal
|
|
(const UVector2& p, double epsilon = tolerance) const;
|
|
|
|
inline UVector2& operator += (const UVector2& p);
|
|
// Addition.
|
|
|
|
inline UVector2& operator -= (const UVector2& p);
|
|
// Subtraction.
|
|
|
|
inline UVector2 operator - () const;
|
|
// Unary minus.
|
|
|
|
inline UVector2& operator *= (double a);
|
|
// Scaling with real numbers.
|
|
|
|
inline UVector2 unit() const;
|
|
// Unit vector parallel to this.
|
|
|
|
inline UVector2 orthogonal() const;
|
|
// Vector orthogonal to this.
|
|
|
|
inline double dot(const UVector2& p) const;
|
|
// Scalar product.
|
|
|
|
inline double angle(const UVector2&) const;
|
|
// The angle w.r.t. another 2-vector.
|
|
|
|
void rotate(double);
|
|
// Rotates the UVector2.
|
|
|
|
operator UVector3() const;
|
|
// Cast a UVector2 as a UVector3.
|
|
|
|
// The remaining methods are friends, thus defined at global scope:
|
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
|
friend std::ostream& operator<< (std::ostream&, const UVector2&);
|
|
// Output to a stream.
|
|
|
|
inline friend double operator * (const UVector2& a,
|
|
const UVector2& b);
|
|
// Scalar product.
|
|
|
|
inline friend UVector2 operator * (const UVector2& p, double a);
|
|
// v*c
|
|
|
|
inline friend UVector2 operator * (double a, const UVector2& p);
|
|
// c*v
|
|
|
|
friend UVector2 operator / (const UVector2& p, double a);
|
|
// v/c
|
|
|
|
inline friend UVector2 operator + (const UVector2& a,
|
|
const UVector2& b);
|
|
// v1+v2
|
|
|
|
inline friend UVector2 operator - (const UVector2& a,
|
|
const UVector2& b);
|
|
// v1-v2
|
|
|
|
enum { ZMpvToleranceTicks = 100 };
|
|
|
|
double x;
|
|
double y;
|
|
// The components.
|
|
|
|
private:
|
|
|
|
static double tolerance;
|
|
// default tolerance criterion for isNear() to return true.
|
|
|
|
}; // UVector2
|
|
|
|
static const UVector2 X_HAT2(1.0, 0.0);
|
|
static const UVector2 Y_HAT2(0.0, 1.0);
|
|
|
|
|
|
/*
|
|
inline double UVector2::x() const {
|
|
return x;
|
|
}
|
|
|
|
inline double UVector2::y() const {
|
|
return y;
|
|
}
|
|
*/
|
|
|
|
inline UVector2::UVector2(double x1, double y1)
|
|
: x(x1), y(y1) {}
|
|
|
|
inline UVector2::UVector2(const UVector3& s)
|
|
: x(s.x), y(s.y) {}
|
|
|
|
inline void UVector2::setX(double x1)
|
|
{
|
|
x = x1;
|
|
}
|
|
|
|
inline void UVector2::setY(double y1)
|
|
{
|
|
y = y1;
|
|
}
|
|
|
|
inline void UVector2::set(double x1, double y1)
|
|
{
|
|
x = x1;
|
|
y = y1;
|
|
}
|
|
|
|
double& UVector2::operator[](int i)
|
|
{
|
|
return operator()(i);
|
|
}
|
|
double UVector2::operator[](int i) const
|
|
{
|
|
return operator()(i);
|
|
}
|
|
|
|
inline UVector2::UVector2(const UVector2& p)
|
|
: x(p.x), y(p.y) {}
|
|
|
|
inline UVector2::~UVector2() {}
|
|
|
|
inline UVector2& UVector2::operator = (const UVector2& p)
|
|
{
|
|
if (this == &p) { return *this; }
|
|
x = p.x;
|
|
y = p.y;
|
|
return *this;
|
|
}
|
|
|
|
inline bool UVector2::operator == (const UVector2& v) const
|
|
{
|
|
return (v.x == x && v.y == y) ? true : false;
|
|
}
|
|
|
|
inline bool UVector2::operator != (const UVector2& v) const
|
|
{
|
|
return (v.x != x || v.y != y) ? true : false;
|
|
}
|
|
|
|
inline UVector2& UVector2::operator += (const UVector2& p)
|
|
{
|
|
x += p.x;
|
|
y += p.y;
|
|
return *this;
|
|
}
|
|
|
|
inline UVector2& UVector2::operator -= (const UVector2& p)
|
|
{
|
|
x -= p.x;
|
|
y -= p.y;
|
|
return *this;
|
|
}
|
|
|
|
inline UVector2 UVector2::operator - () const
|
|
{
|
|
return UVector2(-x, -y);
|
|
}
|
|
|
|
inline UVector2& UVector2::operator *= (double a)
|
|
{
|
|
x *= a;
|
|
y *= a;
|
|
return *this;
|
|
}
|
|
|
|
inline double UVector2::dot(const UVector2& p) const
|
|
{
|
|
return x * p.x + y * p.y;
|
|
}
|
|
|
|
inline double UVector2::mag2() const
|
|
{
|
|
return x * x + y * y;
|
|
}
|
|
|
|
inline double UVector2::mag() const
|
|
{
|
|
return std::sqrt(mag2());
|
|
}
|
|
|
|
inline double UVector2::r() const
|
|
{
|
|
return std::sqrt(mag2());
|
|
}
|
|
|
|
inline UVector2 UVector2::unit() const
|
|
{
|
|
double tot = mag2();
|
|
UVector2 p(*this);
|
|
return tot > 0.0 ? p *= (1.0 / std::sqrt(tot)) : UVector2(1, 0);
|
|
}
|
|
|
|
inline UVector2 UVector2::orthogonal() const
|
|
{
|
|
double x1 = std::fabs(x), y1 = std::fabs(y);
|
|
if (x1 < y1)
|
|
{
|
|
return UVector2(y, -x);
|
|
}
|
|
else
|
|
{
|
|
return UVector2(-y, x);
|
|
}
|
|
}
|
|
|
|
inline double UVector2::phi() const
|
|
{
|
|
return x == 0.0 && y == 0.0 ? 0.0 : std::atan2(y, x);
|
|
}
|
|
|
|
inline double UVector2::angle(const UVector2& q) const
|
|
{
|
|
double ptot2 = mag2() * q.mag2();
|
|
return ptot2 <= 0.0 ? 0.0 : std::acos(dot(q) / std::sqrt(ptot2));
|
|
}
|
|
|
|
inline void UVector2::setMag(double r1)
|
|
{
|
|
double ph = phi();
|
|
setX(r1 * std::cos(ph));
|
|
setY(r1 * std::sin(ph));
|
|
}
|
|
|
|
inline void UVector2::setR(double r1)
|
|
{
|
|
setMag(r1);
|
|
}
|
|
|
|
inline void UVector2::setPhi(double phi1)
|
|
{
|
|
double ma = mag();
|
|
setX(ma * std::cos(phi1));
|
|
setY(ma * std::sin(phi1));
|
|
}
|
|
|
|
inline void UVector2::setPolar(double r1, double phi1)
|
|
{
|
|
setX(r1 * std::cos(phi1));
|
|
setY(r1 * std::sin(phi1));
|
|
}
|
|
|
|
inline UVector2 operator + (const UVector2& a, const UVector2& b)
|
|
{
|
|
return UVector2(a.x + b.x, a.y + b.y);
|
|
}
|
|
|
|
inline UVector2 operator - (const UVector2& a, const UVector2& b)
|
|
{
|
|
return UVector2(a.x - b.x, a.y - b.y);
|
|
}
|
|
|
|
inline UVector2 operator * (const UVector2& p, double a)
|
|
{
|
|
return UVector2(a * p.x, a * p.y);
|
|
}
|
|
|
|
inline UVector2 operator * (double a, const UVector2& p)
|
|
{
|
|
return UVector2(a * p.x, a * p.y);
|
|
}
|
|
|
|
inline double operator * (const UVector2& a, const UVector2& b)
|
|
{
|
|
return a.dot(b);
|
|
}
|
|
|
|
inline double UVector2::getTolerance()
|
|
{
|
|
return tolerance;
|
|
}
|
|
|
|
|
|
#endif /* UVECTOR2_H */
|