Files
geant4/source/externals/clhep/src/BasicVector3D.cc
T
2016-06-09 17:01:34 +02:00

323 lines
9.7 KiB
C++

// -*- C++ -*-
// $Id:$
// ---------------------------------------------------------------------------
#include <cmath>
#include <float.h>
#include <iostream>
#include "CLHEP/Geometry/BasicVector3D.h"
namespace HepGeom {
//--------------------------------------------------------------------------
template<>
float BasicVector3D<float>::pseudoRapidity() const {
float ma = mag(), dz = z();
if (ma == 0) return 0;
if (ma == dz) return FLT_MAX;
if (ma == -dz) return -FLT_MAX;
return 0.5*std::log((ma+dz)/(ma-dz));
}
//--------------------------------------------------------------------------
template<>
void BasicVector3D<float>::setEta(float a) {
double ma = mag();
if (ma == 0) return;
double tanHalfTheta = std::exp(-a);
double tanHalfTheta2 = tanHalfTheta * tanHalfTheta;
double cosTheta1 = (1 - tanHalfTheta2) / (1 + tanHalfTheta2);
double rh = ma * std::sqrt(1 - cosTheta1*cosTheta1);
double ph = phi();
set(rh*std::cos(ph), rh*std::sin(ph), ma*cosTheta1);
}
//--------------------------------------------------------------------------
template<>
float BasicVector3D<float>::angle(const BasicVector3D<float> & v) const {
double cosa = 0;
double ptot = mag()*v.mag();
if(ptot > 0) {
cosa = dot(v)/ptot;
if(cosa > 1) cosa = 1;
if(cosa < -1) cosa = -1;
}
return std::acos(cosa);
}
//--------------------------------------------------------------------------
template<>
BasicVector3D<float> & BasicVector3D<float>::rotateX(float a) {
double sina = std::sin(a), cosa = std::cos(a), dy = y(), dz = z();
setY(dy*cosa-dz*sina);
setZ(dz*cosa+dy*sina);
return *this;
}
//--------------------------------------------------------------------------
template<>
BasicVector3D<float> & BasicVector3D<float>::rotateY(float a) {
double sina = std::sin(a), cosa = std::cos(a), dz = z(), dx = x();
setZ(dz*cosa-dx*sina);
setX(dx*cosa+dz*sina);
return *this;
}
//--------------------------------------------------------------------------
template<>
BasicVector3D<float> & BasicVector3D<float>::rotateZ(float a) {
double sina = std::sin(a), cosa = std::cos(a), dx = x(), dy = y();
setX(dx*cosa-dy*sina);
setY(dy*cosa+dx*sina);
return *this;
}
//--------------------------------------------------------------------------
template<>
BasicVector3D<float> &
BasicVector3D<float>::rotate(float a, const BasicVector3D<float> & v) {
if (a == 0) return *this;
double cx = v.x(), cy = v.y(), cz = v.z();
double ll = std::sqrt(cx*cx + cy*cy + cz*cz);
if (ll == 0) {
std::cerr << "BasicVector<float>::rotate() : zero axis" << std::endl;
return *this;
}
double cosa = std::cos(a), sina = std::sin(a);
cx /= ll; cy /= ll; cz /= ll;
double xx = cosa + (1-cosa)*cx*cx;
double xy = (1-cosa)*cx*cy - sina*cz;
double xz = (1-cosa)*cx*cz + sina*cy;
double yx = (1-cosa)*cy*cx + sina*cz;
double yy = cosa + (1-cosa)*cy*cy;
double yz = (1-cosa)*cy*cz - sina*cx;
double zx = (1-cosa)*cz*cx - sina*cy;
double zy = (1-cosa)*cz*cy + sina*cx;
double zz = cosa + (1-cosa)*cz*cz;
cx = x(); cy = y(); cz = z();
set(xx*cx+xy*cy+xz*cz, yx*cx+yy*cy+yz*cz, zx*cx+zy*cy+zz*cz);
return *this;
}
//--------------------------------------------------------------------------
std::ostream &
operator<<(std::ostream & os, const BasicVector3D<float> & a)
{
return os << "(" << a.x() << "," << a.y() << "," << a.z() << ")";
}
//--------------------------------------------------------------------------
std::istream &
operator>> (std::istream & is, BasicVector3D<float> & a)
{
// Required format is ( a, b, c ) that is, three numbers, preceded by
// (, followed by ), and separated by commas. The three numbers are
// taken as x, y, z.
float x, y, z;
char c;
is >> std::ws >> c;
// ws is defined to invoke eatwhite(istream & )
// see (Stroustrup gray book) page 333 and 345.
if (is.fail() || c != '(' ) {
std::cerr
<< "Could not find required opening parenthesis "
<< "in input of a BasicVector3D<float>"
<< std::endl;
return is;
}
is >> x >> std::ws >> c;
if (is.fail() || c != ',' ) {
std::cerr
<< "Could not find x value and required trailing comma "
<< "in input of a BasicVector3D<float>"
<< std::endl;
return is;
}
is >> y >> std::ws >> c;
if (is.fail() || c != ',' ) {
std::cerr
<< "Could not find y value and required trailing comma "
<< "in input of a BasicVector3D<float>"
<< std::endl;
return is;
}
is >> z >> std::ws >> c;
if (is.fail() || c != ')' ) {
std::cerr
<< "Could not find z value and required close parenthesis "
<< "in input of a BasicVector3D<float>"
<< std::endl;
return is;
}
a.setX(x);
a.setY(y);
a.setZ(z);
return is;
}
//--------------------------------------------------------------------------
template<>
double BasicVector3D<double>::pseudoRapidity() const {
double ma = mag(), dz = z();
if (ma == 0) return 0;
if (ma == dz) return DBL_MAX;
if (ma == -dz) return -DBL_MAX;
return 0.5*std::log((ma+dz)/(ma-dz));
}
//--------------------------------------------------------------------------
template<>
void BasicVector3D<double>::setEta(double a) {
double ma = mag();
if (ma == 0) return;
double tanHalfTheta = std::exp(-a);
double tanHalfTheta2 = tanHalfTheta * tanHalfTheta;
double cosTheta1 = (1 - tanHalfTheta2) / (1 + tanHalfTheta2);
double rh = ma * std::sqrt(1 - cosTheta1*cosTheta1);
double ph = phi();
set(rh*std::cos(ph), rh*std::sin(ph), ma*cosTheta1);
}
//--------------------------------------------------------------------------
template<>
double BasicVector3D<double>::angle(const BasicVector3D<double> & v) const {
double cosa = 0;
double ptot = mag()*v.mag();
if(ptot > 0) {
cosa = dot(v)/ptot;
if(cosa > 1) cosa = 1;
if(cosa < -1) cosa = -1;
}
return std::acos(cosa);
}
//--------------------------------------------------------------------------
template<>
BasicVector3D<double> & BasicVector3D<double>::rotateX(double a) {
double sina = std::sin(a), cosa = std::cos(a), dy = y(), dz = z();
setY(dy*cosa-dz*sina);
setZ(dz*cosa+dy*sina);
return *this;
}
//--------------------------------------------------------------------------
template<>
BasicVector3D<double> & BasicVector3D<double>::rotateY(double a) {
double sina = std::sin(a), cosa = std::cos(a), dz = z(), dx = x();
setZ(dz*cosa-dx*sina);
setX(dx*cosa+dz*sina);
return *this;
}
//--------------------------------------------------------------------------
template<>
BasicVector3D<double> & BasicVector3D<double>::rotateZ(double a) {
double sina = std::sin(a), cosa = std::cos(a), dx = x(), dy = y();
setX(dx*cosa-dy*sina);
setY(dy*cosa+dx*sina);
return *this;
}
//--------------------------------------------------------------------------
template<>
BasicVector3D<double> &
BasicVector3D<double>::rotate(double a, const BasicVector3D<double> & v) {
if (a == 0) return *this;
double cx = v.x(), cy = v.y(), cz = v.z();
double ll = std::sqrt(cx*cx + cy*cy + cz*cz);
if (ll == 0) {
std::cerr << "BasicVector<double>::rotate() : zero axis" << std::endl;
return *this;
}
double cosa = std::cos(a), sina = std::sin(a);
cx /= ll; cy /= ll; cz /= ll;
double xx = cosa + (1-cosa)*cx*cx;
double xy = (1-cosa)*cx*cy - sina*cz;
double xz = (1-cosa)*cx*cz + sina*cy;
double yx = (1-cosa)*cy*cx + sina*cz;
double yy = cosa + (1-cosa)*cy*cy;
double yz = (1-cosa)*cy*cz - sina*cx;
double zx = (1-cosa)*cz*cx - sina*cy;
double zy = (1-cosa)*cz*cy + sina*cx;
double zz = cosa + (1-cosa)*cz*cz;
cx = x(); cy = y(); cz = z();
set(xx*cx+xy*cy+xz*cz, yx*cx+yy*cy+yz*cz, zx*cx+zy*cy+zz*cz);
return *this;
}
//--------------------------------------------------------------------------
std::ostream &
operator<< (std::ostream & os, const BasicVector3D<double> & a)
{
return os << "(" << a.x() << "," << a.y() << "," << a.z() << ")";
}
//--------------------------------------------------------------------------
std::istream &
operator>> (std::istream & is, BasicVector3D<double> & a)
{
// Required format is ( a, b, c ) that is, three numbers, preceded by
// (, followed by ), and separated by commas. The three numbers are
// taken as x, y, z.
double x, y, z;
char c;
is >> std::ws >> c;
// ws is defined to invoke eatwhite(istream & )
// see (Stroustrup gray book) page 333 and 345.
if (is.fail() || c != '(' ) {
std::cerr
<< "Could not find required opening parenthesis "
<< "in input of a BasicVector3D<double>"
<< std::endl;
return is;
}
is >> x >> std::ws >> c;
if (is.fail() || c != ',' ) {
std::cerr
<< "Could not find x value and required trailing comma "
<< "in input of a BasicVector3D<double>"
<< std::endl;
return is;
}
is >> y >> std::ws >> c;
if (is.fail() || c != ',' ) {
std::cerr
<< "Could not find y value and required trailing comma "
<< "in input of a BasicVector3D<double>"
<< std::endl;
return is;
}
is >> z >> std::ws >> c;
if (is.fail() || c != ')' ) {
std::cerr
<< "Could not find z value and required close parenthesis "
<< "in input of a BasicVector3D<double>"
<< std::endl;
return is;
}
a.setX(x);
a.setY(y);
a.setZ(z);
return is;
}
} /* namespace HepGeom */