// convert to human-friendly format void CMappingDefinition::ToUI(CMappingDefinitionUI &mdui) const { // make a copy of parameters FLOAT fUoS = md_fUoS; FLOAT fUoT = md_fUoT; FLOAT fVoS = md_fVoS; FLOAT fVoT = md_fVoT; // find size of mapping vectors FLOAT fUSize = FLOAT(sqrt(fUoS*fUoS+fUoT*fUoT)); FLOAT fVSize = FLOAT(sqrt(fVoS*fVoS+fVoT*fVoT)); // find rotation of both vectors ANGLE aURot = -(ATan2(fVoT, fVoS)-90.0f); ANGLE aVRot = -(ATan2(fUoT, fUoS)); // use the found values Snap(aURot, 0.001f); Snap(aVRot, 0.001f); mdui.mdui_aURotation= NormalizeAngle(aURot); mdui.mdui_aVRotation= NormalizeAngle(aVRot); mdui.mdui_fUStretch = 1/fUSize; mdui.mdui_fVStretch = 1/fVSize; mdui.mdui_fUOffset = md_fUOffset; mdui.mdui_fVOffset = md_fVOffset; }
// NOTE: for derivation of the algorithm, see mathlib.doc void operator^=(ANGLE3D &a3dAngles, const DOUBLEmatrix3D &t3dRotation) { ANGLE &h=a3dAngles(1); // heading ANGLE &p=a3dAngles(2); // pitch ANGLE &b=a3dAngles(3); // banking DOUBLE a; // temporary // calculate pitch p = ASin(-t3dRotation(2,3)); a = sqrt(1-t3dRotation(2,3)*t3dRotation(2,3)); // if pitch makes banking beeing the same as heading if (a<0.0001) { // we choose to have banking of 0 b = 0; // and calculate heading for that ASSERT(Abs(t3dRotation(2,3))>0.5); // must be around 1, what is far from 0 h = ATan2(t3dRotation(1,2)/(-t3dRotation(2,3)), t3dRotation(1,1)); // no division by 0 // otherwise } else { // calculate banking and heading normally b = ATan2(t3dRotation(2,1)/a, t3dRotation(2,2)/a); h = ATan2(t3dRotation(1,3)/a, t3dRotation(3,3)/a); } // snap angles to compensate for errors when converting to and from matrix notation Snap(h, ANGLE_SNAP); Snap(p, ANGLE_SNAP); Snap(b, ANGLE_SNAP); }
// NOTE: for derivation of the algorithm, see mathlib.doc void DecomposeRotationMatrixNoSnap(ANGLE3D &a3dAngles, const FLOATmatrix3D &t3dRotation) { ANGLE &h=a3dAngles(1); // heading ANGLE &p=a3dAngles(2); // pitch ANGLE &b=a3dAngles(3); // banking FLOAT a; // temporary // calculate pitch FLOAT f23 = t3dRotation(2,3); p = ASin(-f23); a = Sqrt(1.0f-f23*f23); // if pitch makes banking beeing the same as heading if (a<0.001) { // we choose to have banking of 0 b = 0; // and calculate heading for that ASSERT(Abs(t3dRotation(2,3))>0.5); // must be around 1, what is far from 0 h = ATan2(t3dRotation(1,2)/(-t3dRotation(2,3)), t3dRotation(1,1)); // no division by 0 // otherwise } else { // calculate banking and heading normally b = ATan2(t3dRotation(2,1), t3dRotation(2,2)); h = ATan2(t3dRotation(1,3), t3dRotation(3,3)); } }
inline CVector3 CVector3::ToAngle() const { if (x == 0.f && y == 0.f) return CVector3(z > 0.f ? -90.f : 90.f, 0.f, 0.f); return CVector3(-RAD2DEG(ASin(z / (Length() + M_EPSILON))), RAD2DEG(ATan2(y, x)), 0.f); }
/* * Create angles in 3D from direction vector(ignoring banking). */ void DirectionVectorToAnglesNoSnap(const FLOAT3D &vDirection, ANGLE3D &a3dAngles) { // now calculate the angles ANGLE &h = a3dAngles(1); ANGLE &p = a3dAngles(2); ANGLE &b = a3dAngles(3); const FLOAT &x = vDirection(1); const FLOAT &y = vDirection(2); const FLOAT &z = vDirection(3); // banking is always irrelevant b = 0; // calculate pitch p = ASin(y); // if y is near +1 or -1 if (y>0.99 || y<-0.99) { // heading is irrelevant h = 0; // otherwise } else { // calculate heading h = ATan2(-x, -z); } }
inline Vector3 QuaternionGetEulerAnglesInRadians(const Quaternion &quat) { const float poleTest = 2.f * (quat.y * quat.w - quat.x * quat.z); const float errorMarginTest = 0.0001f; if(IsNear(poleTest, 1.f, errorMarginTest)) { const float x = 0; const float y = QuartTau(); const float z = -2.f * ATan2(quat.x, quat.w); const Vector3 retVec = {x, y, z}; return retVec; } else if(IsNear(poleTest, -1.f, errorMarginTest)) { const float x = 0; const float y = -QuartTau(); const float z = 2.f * ATan2(quat.x, quat.w); const Vector3 retVec = {x, y, z}; return retVec; } else { const float wSq = quat.w * quat.w; const float xSq = quat.x * quat.x; const float ySq = quat.y * quat.y; const float zSq = quat.z * quat.z; const float x = ATan2(2.f * (quat.y * quat.z + quat.x * quat.w), (-xSq - ySq + zSq + wSq)); const float y = ASin(Clamp(poleTest, -1.f, 1.f)); const float z = ATan2(2.f * (quat.x * quat.y + quat.z * quat.w), (xSq - ySq - zSq + wSq)); const Vector3 retVec = {x, y, z}; return retVec; } }
void CQTOpenGLCamera::SSettings::CalculateYFieldOfView() { CRadians cAspectRatioAngle = ATan2(3.0f, 4.0f); YFieldOfView = ToDegrees(2.0f * ATan2(0.027f * 0.5f, LensFocalLength)); }
inline float CVector2::ToAngle() const { return ATan2(y, x); }
Color Color::Convert(COLOR_SOURCE target) { double in[4], out[4]; if(m_source == target){ return *this; } for(int i=0;i<4;i++){ in[i] = m_val[i]; out[i] = 0.0; } if(m_source == COLOR_SOURCE_WHEEL){ switch (m_wheelType) { case WHEEL_TYPE_HSV: { Vector tmp = HSVToRGB(Vector(in[0],in[1],in[2])); in[0] = tmp.x; in[1] = tmp.y; in[2] = tmp.z; } break; case WHEEL_TYPE_HSB: { Vector tmp = HSLtoRGB(Vector(in[0],in[1],in[2])); in[0] = tmp.x; in[1] = tmp.y; in[2] = tmp.z; } break; case WHEEL_TYPE_LCH: { double tmp[] = {in[0],in[1],in[2]}; in[0] = tmp[2]*100.0; #ifdef _WINDOWS in[1] = tmp[1]*cos(tmp[0]*M_PI_2)*128.0; in[2] = tmp[1]*sin(tmp[0]*M_PI_2)*128.0; #else in[1] = tmp[1]*cos(tmp[0]*M_PI_2)*128.0; in[2] = tmp[1]*sin(tmp[0]*M_PI_2)*128.0; #endif } break; } if(target == COLOR_SOURCE_RGB) cmsDoTransform(m_wheelToRGB, in, out, 1); if(target == COLOR_SOURCE_CMYK) cmsDoTransform(m_wheelToCMYK, in, out, 1); if(target == COLOR_SOURCE_DISPLAY) cmsDoTransform(m_wheelToDisplay, in, out, 1); if(target == COLOR_SOURCE_LAB) cmsDoTransform(m_wheelToLAB, in, out, 1); } if(m_source == COLOR_SOURCE_RGB){ if(target == COLOR_SOURCE_WHEEL) cmsDoTransform(m_RGBToWheel, in, out, 1); if(target == COLOR_SOURCE_CMYK) cmsDoTransform(m_RGBToCMYK, in, out, 1); if(target == COLOR_SOURCE_DISPLAY) cmsDoTransform(m_RGBToDisplay, in, out, 1); if(target == COLOR_SOURCE_LAB) cmsDoTransform(m_RGBToLAB, in, out, 1); } if(m_source == COLOR_SOURCE_CMYK){ if(target == COLOR_SOURCE_WHEEL) cmsDoTransform(m_CMYKToWheel, in, out, 1); if(target == COLOR_SOURCE_RGB) cmsDoTransform(m_CMYKToRGB, in, out, 1); if(target == COLOR_SOURCE_DISPLAY) cmsDoTransform(m_CMYKToDisplay, in, out, 1); if(target == COLOR_SOURCE_LAB) cmsDoTransform(m_CMYKToLAB, in, out, 1); } if(m_source == COLOR_SOURCE_DISPLAY){ if(target == COLOR_SOURCE_WHEEL) cmsDoTransform(m_displayToWheel, in, out, 1); if(target == COLOR_SOURCE_RGB) cmsDoTransform(m_displayToRGB, in, out, 1); if(target == COLOR_SOURCE_CMYK) cmsDoTransform(m_displayToCMYK, in, out, 1); if(target == COLOR_SOURCE_LAB) cmsDoTransform(m_displayToLAB, in, out, 1); } if(m_source == COLOR_SOURCE_LAB){ if(target == COLOR_SOURCE_RGB) cmsDoTransform(m_LABToRGB, in, out, 1); if(target == COLOR_SOURCE_WHEEL) cmsDoTransform(m_LABToWheel, in, out, 1); if(target == COLOR_SOURCE_DISPLAY) cmsDoTransform(m_LABToDisplay, in, out, 1); if(target == COLOR_SOURCE_CMYK) cmsDoTransform(m_LABToCMYK, in, out, 1); } if(target == COLOR_SOURCE_WHEEL){ switch (m_wheelType) { case WHEEL_TYPE_HSV: { Vector tmp = RGBToHSV(Vector(out[0],out[1],out[2])); out[0] = tmp.x;out[1] = tmp.y;out[2] = tmp.z; } break; case WHEEL_TYPE_HSB: { Vector tmp = RGBToHSL(Vector(out[0],out[1],out[2])); out[0] = tmp.x;out[1] = tmp.y;out[2] = tmp.z; } break; case WHEEL_TYPE_LCH: { double tmp[] = {out[0],out[1],out[2]}; out[1] = Sqrt(tmp[1]*tmp[1] + tmp[2]*tmp[2])/128.0; #ifdef _WINDOWS out[0] = ATan2(tmp[2], tmp[1])/M_PI_2; #else out[0] = ATan2(tmp[2], tmp[1])/M_PI_2; #endif while(out[0] < 0.0){ out[0] += 1.0; } while(out[0] > 1.0){ out[0] -= 1.0; } out[2] = tmp[0]/100.0; } break; } } return Color(out[0], out[1], out[2], out[3]).SetSource(target); }