KiCad PCB EDA Suite
Loading...
Searching...
No Matches
transform_trs.cpp
Go to the documentation of this file.
1
/*
2
* This program source code file is part of KiCad, a free EDA CAD application.
3
*
4
* Copyright The KiCad Developers, see AUTHORS.txt for contributors.
5
*
6
* This program is free software: you can redistribute it and/or modify it
7
* under the terms of the GNU General Public License as published by the
8
* Free Software Foundation, either version 3 of the License, or (at your
9
* option) any later version.
10
*
11
* This program is distributed in the hope that it will be useful, but
12
* WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
* General Public License for more details.
15
*
16
* You should have received a copy of the GNU General Public License along
17
* with this program. If not, see <http://www.gnu.org/licenses/>.
18
*/
19
20
#include <
geometry/transform_trs.h
>
21
#include <
trigo.h
>
22
23
#include <algorithm>
24
#include <cmath>
25
26
27
// Composing and decomposing a rotation can leave a scale one unit in the last place off
28
static
bool
sameScale
(
double
aA,
double
aB )
29
{
30
return
std::abs
( aA - aB ) <= 1e-9 * std::max(
std::abs
( aA ),
std::abs
( aB ) );
31
}
32
33
34
VECTOR2D
TRANSFORM_TRS::Apply
(
const
VECTOR2D
& aPoint )
const
35
{
36
VECTOR2D
scaled( aPoint.
x
*
m_scaleX
, aPoint.
y
*
m_scaleY
);
37
RotatePoint
( scaled,
m_rotate
);
38
return
scaled +
VECTOR2D
(
m_translate
);
39
}
40
41
42
VECTOR2I
TRANSFORM_TRS::Apply
(
const
VECTOR2I
& aPoint )
const
43
{
44
VECTOR2D
r =
Apply
(
VECTOR2D
( aPoint ) );
45
return
VECTOR2I
(
KiROUND
( r.
x
),
KiROUND
( r.
y
) );
46
}
47
48
49
VECTOR2D
TRANSFORM_TRS::InverseApply
(
const
VECTOR2D
& aPoint )
const
50
{
51
VECTOR2D
shifted = aPoint -
VECTOR2D
(
m_translate
);
52
RotatePoint
( shifted, -
m_rotate
);
53
return
VECTOR2D
( shifted.
x
/
m_scaleX
, shifted.
y
/
m_scaleY
);
54
}
55
56
57
VECTOR2I
TRANSFORM_TRS::InverseApply
(
const
VECTOR2I
& aPoint )
const
58
{
59
VECTOR2D
r =
InverseApply
(
VECTOR2D
( aPoint ) );
60
return
VECTOR2I
(
KiROUND
( r.
x
),
KiROUND
( r.
y
) );
61
}
62
63
64
TRANSFORM_TRS
TRANSFORM_TRS::RescaleAround
(
const
VECTOR2I
& aFixedPoint,
65
double
aSx,
double
aSy )
const
66
{
67
TRANSFORM_TRS
result
= *
this
;
68
69
// aSx/aSy are scale multipliers in the footprint's own frame, so the local
70
// scale factors scale directly.
71
result
.m_scaleX =
m_scaleX
* aSx;
72
result
.m_scaleY =
m_scaleY
* aSy;
73
74
// The offset from the fixed point is in board axes. Rotate it into the
75
// footprint frame, scale it there, then rotate back (R D R^-1) so the position
76
// move matches the local scaling when the footprint is rotated.
77
VECTOR2D
offset(
m_translate
.x - aFixedPoint.
x
,
m_translate
.y - aFixedPoint.
y
);
78
RotatePoint
( offset, -
m_rotate
);
79
offset.
x
*= aSx;
80
offset.
y
*= aSy;
81
RotatePoint
( offset,
m_rotate
);
82
83
result
.m_translate =
VECTOR2I
(
KiROUND
( aFixedPoint.
x
+ offset.
x
),
KiROUND
( aFixedPoint.
y
+ offset.
y
) );
84
return
result
;
85
}
86
87
88
bool
TRANSFORM_TRS::IsIdentity
()
const
89
{
90
return
m_translate
==
VECTOR2I
( 0, 0 ) &&
m_rotate
.IsZero() &&
HasUnitScale
();
91
}
92
93
94
bool
TRANSFORM_TRS::IsUniformScale
()
const
95
{
96
return
sameScale
(
m_scaleX
,
m_scaleY
);
97
}
98
99
100
bool
TRANSFORM_TRS::HasUnitScale
()
const
101
{
102
return
sameScale
(
m_scaleX
, 1.0 ) &&
sameScale
(
m_scaleY
, 1.0 );
103
}
104
105
106
double
TRANSFORM_TRS::ApplyLinearScale
(
double
aLength )
const
107
{
108
double
scale
=
IsUniformScale
() ?
m_scaleX
: (
m_scaleX
+
m_scaleY
) / 2;
109
110
return
aLength *
scale
;
111
}
112
113
114
double
TRANSFORM_TRS::InverseApplyLinearScale
(
double
aLength )
const
115
{
116
double
scale
=
IsUniformScale
() ?
m_scaleX
: (
m_scaleX
+
m_scaleY
) / 2;
117
118
return
aLength /
scale
;
119
}
120
121
122
bool
TRANSFORM_TRS::operator==
(
const
TRANSFORM_TRS
& aOther )
const
123
{
124
return
m_translate
== aOther.
m_translate
125
&&
m_rotate
== aOther.
m_rotate
126
&&
m_scaleX
== aOther.
m_scaleX
127
&&
m_scaleY
== aOther.
m_scaleY
;
128
}
KiROUND
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
Definition
box2.h:982
TRANSFORM_TRS::InverseApply
VECTOR2I InverseApply(const VECTOR2I &aPoint) const
Definition
transform_trs.cpp:57
TRANSFORM_TRS::m_scaleX
double m_scaleX
Definition
transform_trs.h:83
TRANSFORM_TRS::HasUnitScale
bool HasUnitScale() const
True when both scales are 1, ignoring rounding.
Definition
transform_trs.cpp:100
TRANSFORM_TRS::IsUniformScale
bool IsUniformScale() const
Scales that differ only by rounding count as equal, so a pure rotation stays uniform.
Definition
transform_trs.cpp:94
TRANSFORM_TRS::Apply
VECTOR2I Apply(const VECTOR2I &aPoint) const
Definition
transform_trs.cpp:42
TRANSFORM_TRS::m_rotate
EDA_ANGLE m_rotate
Definition
transform_trs.h:82
TRANSFORM_TRS::ApplyLinearScale
double ApplyLinearScale(double aLength) const
Definition
transform_trs.cpp:106
TRANSFORM_TRS::m_scaleY
double m_scaleY
Definition
transform_trs.h:84
TRANSFORM_TRS::RescaleAround
TRANSFORM_TRS RescaleAround(const VECTOR2I &aFixedPoint, double aSx, double aSy) const
Definition
transform_trs.cpp:64
TRANSFORM_TRS::operator==
bool operator==(const TRANSFORM_TRS &aOther) const
Definition
transform_trs.cpp:122
TRANSFORM_TRS::TRANSFORM_TRS
TRANSFORM_TRS()
Definition
transform_trs.h:33
TRANSFORM_TRS::InverseApplyLinearScale
double InverseApplyLinearScale(double aLength) const
Definition
transform_trs.cpp:114
TRANSFORM_TRS::IsIdentity
bool IsIdentity() const
Definition
transform_trs.cpp:88
TRANSFORM_TRS::m_translate
VECTOR2I m_translate
Definition
transform_trs.h:81
VECTOR2::x
T x
Definition
vector2d.h:75
VECTOR2::y
T y
Definition
vector2d.h:75
std::abs
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
Definition
eda_angle.h:437
scale
const int scale
Definition
spread_footprints.cpp:49
result
wxString result
Test unit parsing edge cases and error handling.
Definition
test_text_eval_numeric_compat.cpp:600
sameScale
static bool sameScale(double aA, double aB)
Definition
transform_trs.cpp:28
transform_trs.h
trigo.h
RotatePoint
void RotatePoint(int *pX, int *pY, const EDA_ANGLE &aAngle)
Calculate the new point of coord coord pX, pY, for a rotation center 0, 0.
Definition
trigo.cpp:227
VECTOR2I
VECTOR2< int32_t > VECTOR2I
Definition
vector2d.h:708
VECTOR2D
VECTOR2< double > VECTOR2D
Definition
vector2d.h:707
src
libs
kimath
src
geometry
transform_trs.cpp
Generated on Tue Oct 27 2026 00:06:29 for KiCad PCB EDA Suite by
1.13.2