FloatPoint TransformationMatrix::projectPoint(const FloatPoint& p) const { // This is basically raytracing. We have a point in the destination // plane with z=0, and we cast a ray parallel to the z-axis from that // point to find the z-position at which it intersects the z=0 plane // with the transform applied. Once we have that point we apply the // inverse transform to find the corresponding point in the source // space. // // Given a plane with normal Pn, and a ray starting at point R0 and // with direction defined by the vector Rd, we can find the // intersection point as a distance d from R0 in units of Rd by: // // d = -dot (Pn', R0) / dot (Pn', Rd) double x = p.x(); double y = p.y(); double z = -(m13() * x + m23() * y + m43()) / m33(); double outX = x * m11() + y * m21() + z * m31() + m41(); double outY = x * m12() + y * m22() + z * m32() + m42(); double w = x * m14() + y * m24() + z * m34() + m44(); if (w != 1 && w != 0) { outX /= w; outY /= w; } return FloatPoint(static_cast<float>(outX), static_cast<float>(outY)); }
const String DOMMatrixReadOnly::toString() const { std::stringstream stream; if (is2D()) { stream << "matrix(" << a() << ", " << b() << ", " << c() << ", " << d() << ", " << e() << ", " << f(); } else { stream << "matrix3d(" << m11() << ", " << m12() << ", " << m13() << ", " << m14() << ", " << m21() << ", " << m22() << ", " << m23() << ", " << m24() << ", " << m31() << ", " << m32() << ", " << m33() << ", " << m34() << ", " << m41() << ", " << m42() << ", " << m43() << ", " << m44(); } stream << ")"; return String(stream.str().c_str()); }
CSSFunctionValue* MatrixTransformComponent::toCSSValue() const { CSSFunctionValue* result = CSSFunctionValue::create(m_is2D ? CSSValueMatrix : CSSValueMatrix3d); if (m_is2D) { double values[6] = {a(), b(), c(), d(), e(), f()}; for (double value : values) { result->append(cssValuePool().createValue(value, CSSPrimitiveValue::UnitType::Number)); } } else { double values[16] = {m11(), m12(), m13(), m14(), m21(), m22(), m23(), m24(), m31(), m32(), m33(), m34(), m41(), m42(), m43(), m44() }; for (double value : values) { result->append(cssValuePool().createValue(value, CSSPrimitiveValue::UnitType::Number)); } } return result; }
TransformationMatrix::operator CATransform3D() const { CATransform3D toT3D; toT3D.m11 = narrowPrecisionToFloat(m11()); toT3D.m12 = narrowPrecisionToFloat(m12()); toT3D.m13 = narrowPrecisionToFloat(m13()); toT3D.m14 = narrowPrecisionToFloat(m14()); toT3D.m21 = narrowPrecisionToFloat(m21()); toT3D.m22 = narrowPrecisionToFloat(m22()); toT3D.m23 = narrowPrecisionToFloat(m23()); toT3D.m24 = narrowPrecisionToFloat(m24()); toT3D.m31 = narrowPrecisionToFloat(m31()); toT3D.m32 = narrowPrecisionToFloat(m32()); toT3D.m33 = narrowPrecisionToFloat(m33()); toT3D.m34 = narrowPrecisionToFloat(m34()); toT3D.m41 = narrowPrecisionToFloat(m41()); toT3D.m42 = narrowPrecisionToFloat(m42()); toT3D.m43 = narrowPrecisionToFloat(m43()); toT3D.m44 = narrowPrecisionToFloat(m44()); return toT3D; }
ResoResults calc_cn(const CNParams& cn) { ResoResults res; res.Q_avg.resize(4); res.Q_avg[0] = cn.Q * angs; res.Q_avg[1] = 0.; res.Q_avg[2] = 0.; res.Q_avg[3] = cn.E / meV; angle coll_h_pre_mono = cn.coll_h_pre_mono; angle coll_v_pre_mono = cn.coll_v_pre_mono; // ------------------------------------------------------------------------- // transformation matrix angle thetaa = cn.thetaa * cn.dana_sense; angle thetam = cn.thetam * cn.dmono_sense; angle ki_Q = cn.angle_ki_Q; angle kf_Q = cn.angle_kf_Q; ki_Q *= cn.dsample_sense; kf_Q *= cn.dsample_sense; t_mat Ti = tl::rotation_matrix_2d(ki_Q/rads); t_mat Tf = -tl::rotation_matrix_2d(kf_Q/rads); t_mat U = ublas::zero_matrix<t_real>(6,6); tl::submatrix_copy(U, Ti, 0, 0); tl::submatrix_copy(U, Tf, 0, 3); U(2,2) = 1.; U(2,5) = -1.; U(3,0) = +t_real(2)*cn.ki * tl::get_KSQ2E<t_real>() * angs; U(3,3) = -t_real(2)*cn.kf * tl::get_KSQ2E<t_real>() * angs; U(4,0) = 1.; U(5,2) = 1.; t_mat V(6,6); if(!tl::inverse(U, V)) { res.bOk = false; res.strErr = "Transformation matrix cannot be inverted."; return res; } // ------------------------------------------------------------------------- // ------------------------------------------------------------------------- // resolution matrix t_vec pm(2); pm[0] = units::tan(thetam); pm[1] = 1.; pm /= cn.ki*angs * cn.mono_mosaic/rads; t_vec pa(2); pa[0] = -units::tan(thetaa); pa[1] = 1.; pa /= cn.kf*angs * cn.ana_mosaic/rads; t_vec palf0(2); palf0[0] = 2.*units::tan(thetam); palf0[1] = 1.; palf0 /= (cn.ki*angs * coll_h_pre_mono/rads); t_vec palf1(2); palf1[0] = 0; palf1[1] = 1.; palf1 /= (cn.ki*angs * cn.coll_h_pre_sample/rads); t_vec palf2(2); palf2[0] = -2.*units::tan(thetaa); palf2[1] = 1.; palf2 /= (cn.kf*angs * cn.coll_h_post_ana/rads); t_vec palf3(2); palf3[0] = 0; palf3[1] = 1.; palf3 /= (cn.kf*angs * cn.coll_h_post_sample/rads); t_mat m01(2,2); m01 = ublas::outer_prod(pm,pm) + ublas::outer_prod(palf0,palf0) + ublas::outer_prod(palf1,palf1); t_mat m34(2,2); m34 = ublas::outer_prod(pa,pa) + ublas::outer_prod(palf2,palf2) + ublas::outer_prod(palf3,palf3); t_mat M = ublas::zero_matrix<t_real>(6,6); tl::submatrix_copy(M, m01, 0, 0); tl::submatrix_copy(M, m34, 3, 3); M(2,2) = t_real(1)/(cn.ki*cn.ki * angs*angs) * rads*rads * ( t_real(1)/(cn.coll_v_pre_sample*cn.coll_v_pre_sample) + t_real(1)/((t_real(2)*units::sin(thetam)*cn.mono_mosaic)* (t_real(2)*units::sin(thetam)*cn.mono_mosaic) + coll_v_pre_mono*coll_v_pre_mono) ); M(5,5) = t_real(1)/(cn.kf*cn.kf * angs*angs) * rads*rads * ( t_real(1) / (cn.coll_v_post_sample*cn.coll_v_post_sample) + t_real(1) / ((t_real(2)*units::sin(thetaa)*cn.ana_mosaic)* (t_real(2)*units::sin(thetaa)*cn.ana_mosaic) + cn.coll_v_post_ana*cn.coll_v_post_ana) ); // ------------------------------------------------------------------------- t_mat N = tl::transform(M, V, 1); N = ellipsoid_gauss_int(N, 5); N = ellipsoid_gauss_int(N, 4); t_vec vec1 = tl::get_column<t_vec>(N, 1); res.reso = N - ublas::outer_prod(vec1,vec1) / (1./((cn.sample_mosaic/rads * cn.Q*angs) * (cn.sample_mosaic/rads * cn.Q*angs)) + N(1,1)); res.reso(2,2) = N(2,2); res.reso *= tl::SIGMA2FWHM*tl::SIGMA2FWHM; res.reso_v = ublas::zero_vector<t_real>(4); res.reso_s = 0.; if(cn.dsample_sense < 0.) { // mirror Q_perp t_mat matMirror = tl::mirror_matrix<t_mat>(res.reso.size1(), 1); res.reso = tl::transform(res.reso, matMirror, true); res.reso_v[1] = -res.reso_v[1]; } // ------------------------------------------------------------------------- res.dResVol = tl::get_ellipsoid_volume(res.reso); res.dR0 = chess_R0(cn.ki,cn.kf, thetam, thetaa, cn.twotheta, cn.mono_mosaic, cn.ana_mosaic, cn.coll_v_pre_mono, cn.coll_v_post_ana, cn.dmono_refl, cn.dana_effic); // Bragg widths for(unsigned int i=0; i<4; ++i) res.dBraggFWHMs[i] = tl::SIGMA2FWHM/sqrt(res.reso(i,i)); if(tl::is_nan_or_inf(res.dR0) || tl::is_nan_or_inf(res.reso)) { res.strErr = "Invalid result."; res.bOk = false; return res; } res.bOk = true; return res; }