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));
}
示例#2
0
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());
}
示例#3
0
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;
}
示例#5
0
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;
}