/** Convert physical position to UV projection * * @param pos :: position in 3D * @param u :: set to U * @param v :: set to V * @param uscale :: scaling for u direction * @param vscale :: scaling for v direction */ void UnwrappedCylinder::project(const Mantid::Kernel::V3D &pos, double &u, double &v, double &uscale, double &vscale) const { // projection to cylinder axis v = pos.scalar_prod(m_zaxis); double x = pos.scalar_prod(m_xaxis); double y = pos.scalar_prod(m_yaxis); u = applyUCorrection(-atan2(y, x)); uscale = 1. / sqrt(x * x + y * y); vscale = 1.; }
/** Convert physical position to UV projection * * @param u :: set to U * @param v :: set to V * @param uscale :: scaling for u direction * @param vscale :: scaling for v direction * @param pos :: position in 3D */ void UnwrappedSphere::project(double & u, double & v, double & uscale, double & vscale, const Mantid::Kernel::V3D & pos) const { // projection to cylinder axis v = pos.scalar_prod(m_zaxis); double x = pos.scalar_prod(m_xaxis); double y = pos.scalar_prod(m_yaxis); double r = sqrt(x*x+y*y+v*v); uscale = 1./sqrt(x*x+y*y); vscale = 1./r; u = applyUCorrection( -atan2(y,x) ); v = -acos(v/r); }
void UnwrappedSphere::calcUV(UnwrappedDetector& udet) { //static const double pi2 = 2*acos(-1.); Mantid::Kernel::V3D pos = udet.detector->getPos() - m_pos; // projection to cylinder axis udet.v = pos.scalar_prod(m_zaxis); double x = pos.scalar_prod(m_xaxis); double y = pos.scalar_prod(m_yaxis); double r = sqrt(x*x+y*y+udet.v*udet.v); udet.uscale = 1./sqrt(x*x+y*y); udet.vscale = 1./r; udet.u = -atan2(y,x); udet.v = -acos(udet.v/r); calcSize(udet,Mantid::Kernel::V3D(-1,0,0),Mantid::Kernel::V3D(0,1,0)); }
void UnwrappedCylinder::rotate(const UnwrappedDetector &udet, Mantid::Kernel::Quat &R) const { // direction in which to look Mantid::Kernel::V3D eye; const auto &componentInfo = m_instrActor->componentInfo(); // rotation from the global axes to those where // the z axis points to the detector Mantid::Kernel::Quat R1; eye = m_pos - componentInfo.position(udet.detIndex); if (!eye.nullVector()) { // eye must point towards the detector and be perpendicular to the // cylinder's axis Mantid::Kernel::V3D up = m_zaxis; up.normalize(); eye = eye - up * eye.scalar_prod(up); if (!eye.nullVector()) { eye.normalize(); InstrumentActor::rotateToLookAt(eye, up, R1); } } // add detector's own rotation R = R1 * componentInfo.rotation(udet.detIndex); }
/** * Find a rotation from one orthonormal basis set (Xfrom,Yfrom,Zfrom) to * another orthonormal basis set (Xto,Yto,Zto). Both sets must be right-handed * (or same-handed, I didn't check). The method doesn't check the sets for orthogonality * or normality. The result is a rotation quaternion such that: * R.rotate(Xfrom) == Xto * R.rotate(Yfrom) == Yto * R.rotate(Zfrom) == Zto * @param Xfrom :: The X axis of the original basis set * @param Yfrom :: The Y axis of the original basis set * @param Zfrom :: The Z axis of the original basis set * @param Xto :: The X axis of the final basis set * @param Yto :: The Y axis of the final basis set * @param Zto :: The Z axis of the final basis set * @param R :: The output rotation as a quaternion * @param out :: Debug printout flag */ void InstrumentActor::BasisRotation(const Mantid::Kernel::V3D& Xfrom, const Mantid::Kernel::V3D& Yfrom, const Mantid::Kernel::V3D& Zfrom, const Mantid::Kernel::V3D& Xto, const Mantid::Kernel::V3D& Yto, const Mantid::Kernel::V3D& Zto, Mantid::Kernel::Quat& R, bool out ) { // Find transformation from (X,Y,Z) to (XX,YY,ZZ) // R = R1*R2*R3, where R1, R2, and R3 are Euler rotations // std::cerr<<"RCRotation-----------------------------\n"; // std::cerr<<"From "<<Xfrom<<Yfrom<<Zfrom<<'\n'; // std::cerr<<"To "<<Xto<<Yto<<Zto<<'\n'; double sZ = Zfrom.scalar_prod(Zto); if (fabs(sZ - 1) < m_tolerance) // vectors the same { double sX = Xfrom.scalar_prod(Xto); if (fabs(sX - 1) < m_tolerance) { R = Mantid::Kernel::Quat(); } else if (fabs(sX + 1) < m_tolerance) { R = Mantid::Kernel::Quat(180,Zfrom); } else { R = Mantid::Kernel::Quat(Xfrom,Xto); } } else if(fabs(sZ + 1) < m_tolerance) // rotated by 180 degrees { if (fabs(Xfrom.scalar_prod(Xto)-1) < m_tolerance) { R = Mantid::Kernel::Quat(180.,Xfrom); } else if (fabs(Yfrom.scalar_prod(Yto)-1) < m_tolerance) { R = Mantid::Kernel::Quat(180.,Yfrom); } else { R = Mantid::Kernel::Quat(180.,Xto)*Mantid::Kernel::Quat(Xfrom,Xto); } } else { // Rotation R1 of system (X,Y,Z) around Z by alpha Mantid::Kernel::V3D X1; Mantid::Kernel::Quat R1; X1 = Zfrom.cross_prod(Zto); X1.normalize(); double sX = Xfrom.scalar_prod(Xto); if (fabs(sX - 1) < m_tolerance) { R = Mantid::Kernel::Quat(Zfrom,Zto); return; } sX = Xfrom.scalar_prod(X1); if (fabs(sX - 1) < m_tolerance) { R1 = Mantid::Kernel::Quat(); } else if (fabs(sX + 1) < m_tolerance) // 180 degree rotation { R1 = Mantid::Kernel::Quat(180.,Zfrom); } else { R1 = Mantid::Kernel::Quat(Xfrom,X1); } if (out) std::cerr<<"R1="<<R1<<'\n'; // Rotation R2 around X1 by beta Mantid::Kernel::Quat R2(Zfrom,Zto); // vectors are different if (out) std::cerr<<"R2="<<R2<<'\n'; // Rotation R3 around ZZ by gamma Mantid::Kernel::Quat R3; sX = Xto.scalar_prod(X1); if (fabs(sX - 1) < m_tolerance) { R3 = Mantid::Kernel::Quat(); } else if (fabs(sX + 1) < m_tolerance) // 180 degree rotation { R3 = Mantid::Kernel::Quat(180.,Zto); } else { R3 = Mantid::Kernel::Quat(X1,Xto); } if (out) std::cerr<<"R3="<<R3<<'\n'; // Combined rotation R = R3*R2*R1; } }