Fixing issue #1747 (signed coordinate transformations with Trans/DTrans/CplxTrans etc.)

This commit is contained in:
Matthias Koefferlein 2024-06-22 23:25:45 +02:00
parent 4e430ff38f
commit 61e2758bbb
2 changed files with 78 additions and 12 deletions

View File

@ -33,6 +33,43 @@
namespace gsi
{
// ---------------------------------------------------------------
// A helper for the single-coordinate/distance transformation
namespace
{
template <class C> struct long_coord;
template<> struct long_coord<int32_t>
{
typedef int64_t type;
static type rounded (double v)
{
return type (v > 0 ? v + 0.5 : v - 0.5);
}
};
template<> struct long_coord<int64_t>
{
typedef int64_t type;
static type rounded (double v)
{
return type (v > 0 ? v + 0.5 : v - 0.5);
}
};
template<> struct long_coord<double>
{
typedef double type;
static type rounded (double v)
{
return v;
}
};
}
// ---------------------------------------------------------------
// simple_trans binding
@ -111,6 +148,11 @@ struct trans_defs
*trans = C (trans->angle (), mirror, trans->disp ());
}
static typename long_coord<coord_type>::type trans_coord (const C * /*t*/, typename long_coord<coord_type>::type c)
{
return long_coord<coord_type>::rounded (double (c));
}
static db::edge<coord_type> trans_edge (const C *t, const db::edge<coord_type> &edge)
{
return edge.transformed (*t);
@ -219,18 +261,18 @@ struct trans_defs
"\n"
"@return The inverted transformation\n"
) +
method ("ctrans|*", &C::ctrans, arg ("d"),
"@brief Transforms a distance\n"
method_ext ("ctrans|*", &trans_coord, arg ("d"),
"@brief Transforms a single distance\n"
"\n"
"The \"ctrans\" method transforms the given distance.\n"
"e = t(d). For the simple transformations, there\n"
"is no magnification and no modification of the distance\n"
"therefore.\n"
"This is equivalent to multiplying with the magnification. For the simple transformations, there\n"
"is no magnification and no modification of the distance.\n"
"\n"
"@param d The distance to transform\n"
"@return The transformed distance\n"
"\n"
"The product '*' has been added as a synonym in version 0.28."
"The product '*' has been added as a synonym in version 0.28. "
"The distance can be signed since version 0.29.3."
) +
method ("trans|*", (point_type (C::*) (const point_type &) const) &C::trans, arg ("p"),
"@brief Transforms a point\n"
@ -604,6 +646,11 @@ struct cplx_trans_defs
return new C (mag, r, mirrx, displacement_type (x, y));
}
static typename long_coord<target_coord_type>::type trans_coord (const C *t, typename long_coord<coord_type>::type c)
{
return long_coord<target_coord_type>::rounded (t->mag () * double (c));
}
static simple_trans_type s_trans (const C *cplx_trans)
{
return simple_trans_type (db::complex_trans<coord_type, coord_type> (*cplx_trans));
@ -729,18 +776,18 @@ struct cplx_trans_defs
"\n"
"@return The inverted transformation\n"
) +
method ("ctrans|*", &C::ctrans, arg ("d"),
"@brief Transforms a distance\n"
method_ext ("ctrans|*", &trans_coord, arg ("d"),
"@brief Transforms a single distance\n"
"\n"
"The \"ctrans\" method transforms the given distance.\n"
"e = t(d). For the simple transformations, there\n"
"is no magnification and no modification of the distance\n"
"therefore.\n"
"This is equivalent to multiplying with the magnification. For the simple transformations, there\n"
"is no magnification and no modification of the distance.\n"
"\n"
"@param d The distance to transform\n"
"@return The transformed distance\n"
"\n"
"The product '*' has been added as a synonym in version 0.28."
"The product '*' has been added as a synonym in version 0.28. "
"The distance can be signed since version 0.29.3."
) +
method ("trans|*", (target_point_type (C::*) (const point_type &) const) &C::trans, arg ("p"),
"@brief Transforms a point\n"

View File

@ -81,7 +81,9 @@ class DBTrans_TestClass < TestBase
assert_equal( RBA::Trans::new(RBA::Trans::R180).to_s, "r180 0,0" )
assert_equal( e.ctrans( 2.0 ), 2.0 )
assert_equal( e.ctrans( -2.0 ), -2.0 )
assert_equal( e * 2.0, 2.0 )
assert_equal( e * -2.0, -2.0 )
assert_equal( e.trans( RBA::Edge::new(0, 1, 2, 3) ).to_s, "(-3,-2;-1,0)" )
assert_equal( ( e * RBA::Edge::new(0, 1, 2, 3) ).to_s, "(-3,-2;-1,0)" )
assert_equal( e.trans( RBA::Box::new(0, 1, 2, 3) ).to_s, "(-3,-2;-1,0)" )
@ -142,9 +144,13 @@ class DBTrans_TestClass < TestBase
assert_equal( mb.trans( RBA::DPoint::new( 1, 0 )).to_s, "17,3" )
assert_equal( mb.ctrans(2).to_s, "4.0" )
assert_equal( mb.ctrans(-2).to_s, "-4.0" )
assert_equal( (mb * 2).to_s, "4.0" )
assert_equal( (mb * -2).to_s, "-4.0" )
assert_equal( i.ctrans(2).to_s, "1.0" )
assert_equal( i.ctrans(-2).to_s, "-1.0" )
assert_equal( (i * 2).to_s, "1.0" )
assert_equal( (i * -2).to_s, "-1.0" )
end
@ -203,7 +209,9 @@ class DBTrans_TestClass < TestBase
assert_equal( (c.angle - 45).abs < 1e-10, true )
assert_equal( c.ctrans( 5 ).to_s, "3.75" )
assert_equal( c.ctrans( -5 ).to_s, "-3.75" )
assert_equal( (c * 5).to_s, "3.75" )
assert_equal( (c * -5).to_s, "-3.75" )
assert_equal( c.trans( RBA::DPoint::new( 12, 16 ) ).to_s, "17.3492424049,-14.6213203436" )
assert_equal( RBA::DCplxTrans::new.to_s, "r0 *1 0,0" )
@ -270,6 +278,11 @@ class DBTrans_TestClass < TestBase
c.mirror = true
assert_equal( c.to_s, "m135 1,7" )
assert_equal( e.ctrans( 2 ), 2 )
assert_equal( e.ctrans( -2 ), -2 )
assert_equal( e * 2, 2 )
assert_equal( e * -2, -2 )
assert_equal( e.trans( RBA::Edge::new(0, 1, 2, 3) ).to_s, "(-3,-2;-1,0)" )
assert_equal( ( e * RBA::Edge::new(0, 1, 2, 3) ).to_s, "(-3,-2;-1,0)" )
assert_equal( e.trans( RBA::Box::new(0, 1, 2, 3) ).to_s, "(-3,-2;-1,0)" )
@ -311,9 +324,13 @@ class DBTrans_TestClass < TestBase
assert_equal( mb.trans( RBA::Point::new( 1, 0 )).to_s, "17,3" )
assert_equal( mb.ctrans(2).to_s, "4.0" )
assert_equal( mb.ctrans(-2).to_s, "-4.0" )
assert_equal( (mb * 2).to_s, "4.0" )
assert_equal( (mb * -2).to_s, "-4.0" )
assert_equal( i.ctrans(2).to_s, "1.0" )
assert_equal( i.ctrans(-2).to_s, "-1.0" )
assert_equal( (i * 2).to_s, "1.0" )
assert_equal( (i * -2).to_s, "-1.0" )
end
@ -360,7 +377,9 @@ class DBTrans_TestClass < TestBase
assert_equal( (c.angle - 45).abs < 1e-10, true )
assert_equal( c.ctrans( 5 ).to_s, "3.75" )
assert_equal( c.ctrans( -5 ).to_s, "-3.75" )
assert_equal( (c * 5).to_s, "3.75" )
assert_equal( (c * -5).to_s, "-3.75" )
assert_equal( c.trans( RBA::Point::new( 12, 16 ) ).to_s, "17.3492424049,-14.6213203436" )
assert_equal( RBA::CplxTrans::new.to_s, "r0 *1 0,0" )