|
|
|||
File indexing completed on 2026-04-09 07:49:12
0001 #pragma once 0002 0003 0004 #if defined(__CUDACC__) || defined(__CUDABE__) 0005 #define QUTIL_METHOD __device__ 0006 #else 0007 #define QUTIL_METHOD 0008 #endif 0009 0010 0011 struct qutil 0012 { 0013 QUTIL_METHOD static void rotateUz(float3& d, const float3& u ); 0014 }; 0015 0016 0017 /** 0018 qutil::rotateUz 0019 ----------------- 0020 0021 This rotates the reference frame of a vector such that the original Z-axis will lie in the 0022 direction of *u*. Many rotations would accomplish this; the one selected 0023 uses *u* as its third column and is given by the below matrix. 0024 0025 The below CUDA implementation follows the CLHEP implementation used by Geant4:: 0026 0027 // geant4.10.00.p01/source/externals/clhep/src/ThreeVector.cc 0028 72 Hep3Vector & Hep3Vector::rotateUz(const Hep3Vector& NewUzVector) { 0029 73 // NewUzVector must be normalized ! 0030 74 0031 75 double u1 = NewUzVector.x(); 0032 76 double u2 = NewUzVector.y(); 0033 77 double u3 = NewUzVector.z(); 0034 78 double up = u1*u1 + u2*u2; 0035 79 0036 80 if (up>0) { 0037 81 up = std::sqrt(up); 0038 82 double px = dx, py = dy, pz = dz; 0039 83 dx = (u1*u3*px - u2*py)/up + u1*pz; 0040 84 dy = (u2*u3*px + u1*py)/up + u2*pz; 0041 85 dz = -up*px + u3*pz; 0042 86 } 0043 87 else if (u3 < 0.) { dx = -dx; dz = -dz; } // phi=0 teta=pi 0044 88 else {}; 0045 89 return *this; 0046 90 } 0047 0048 This implements rotation of (px,py,pz) vector into (dx,dy,dz) 0049 using the below rotation matrix, the columns of which must be 0050 orthogonal unit vectors.:: 0051 0052 | u.x * u.z / up -u.y / up u.x | 0053 d = | u.y * u.z / up +u.x / up u.y | p 0054 | -up 0. u.z | 0055 0056 Taking dot products between and within columns shows that to 0057 be the case for normalized u. See oxrap/rotateUz.h for the algebra. 0058 0059 Special cases: 0060 0061 u = [0,0,1] (up=0.) 0062 does nothing, effectively identity matrix 0063 0064 u = [0,0,-1] (up=0., u.z<0. ) 0065 flip x, and z which is a rotation of pi/2 about y 0066 0067 | -1 0 0 | 0068 d = | 0 1 0 | p 0069 | 0 0 -1 | 0070 0071 **/ 0072 0073 inline QUTIL_METHOD void qutil::rotateUz(float3& d, const float3& u ) 0074 { 0075 float up = u.x*u.x + u.y*u.y ; 0076 if (up>0.f) 0077 { 0078 up = sqrt(up); 0079 float px = d.x ; 0080 float py = d.y ; 0081 float pz = d.z ; 0082 d.x = (u.x*u.z*px - u.y*py)/up + u.x*pz; 0083 d.y = (u.y*u.z*px + u.x*py)/up + u.y*pz; 0084 d.z = -up*px + u.z*pz; 0085 } 0086 else if (u.z < 0.f ) 0087 { 0088 d.x = -d.x; 0089 d.z = -d.z; 0090 } 0091 } 0092 0093 0094
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|