mirror of https://github.com/KLayout/klayout.git
Fixing issue #1747 (signed coordinate transformations with Trans/DTrans/CplxTrans etc.)
This commit is contained in:
parent
4e430ff38f
commit
61e2758bbb
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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" )
|
||||
|
|
|
|||
Loading…
Reference in New Issue