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
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
28static 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
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
43{
44 VECTOR2D r = Apply( VECTOR2D( aPoint ) );
45 return VECTOR2I( KiROUND( r.x ), KiROUND( r.y ) );
46}
47
48
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
58{
59 VECTOR2D r = InverseApply( VECTOR2D( aPoint ) );
60 return VECTOR2I( KiROUND( r.x ), KiROUND( r.y ) );
61}
62
63
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
89{
90 return m_translate == VECTOR2I( 0, 0 ) && m_rotate.IsZero() && HasUnitScale();
91}
92
93
95{
96 return sameScale( m_scaleX, m_scaleY );
97}
98
99
101{
102 return sameScale( m_scaleX, 1.0 ) && sameScale( m_scaleY, 1.0 );
103}
104
105
106double 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
114double 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
122bool 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}
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
Definition box2.h:982
VECTOR2I InverseApply(const VECTOR2I &aPoint) const
bool HasUnitScale() const
True when both scales are 1, ignoring rounding.
bool IsUniformScale() const
Scales that differ only by rounding count as equal, so a pure rotation stays uniform.
VECTOR2I Apply(const VECTOR2I &aPoint) const
EDA_ANGLE m_rotate
double ApplyLinearScale(double aLength) const
TRANSFORM_TRS RescaleAround(const VECTOR2I &aFixedPoint, double aSx, double aSy) const
bool operator==(const TRANSFORM_TRS &aOther) const
double InverseApplyLinearScale(double aLength) const
bool IsIdentity() const
VECTOR2I m_translate
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
Definition eda_angle.h:437
const int scale
wxString result
Test unit parsing edge cases and error handling.
static bool sameScale(double aA, double aB)
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
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:708
VECTOR2< double > VECTOR2D
Definition vector2d.h:707