46 const std::vector<VECTOR2I>& aPtsB )
const
48 wxCHECK_MSG( aPtsA.size() == aPtsB.size(), std::nullopt,
"Point lists must be the same length" );
52 std::optional<EDA_ANGLE> bestRotation;
55 for(
size_t firstPtIdx = 0; firstPtIdx < aPtsA.size(); firstPtIdx++ )
57 for(
size_t secondPtIdx = firstPtIdx; secondPtIdx < aPtsA.size(); secondPtIdx++ )
59 const VECTOR2I& ptA1 = aPtsA[firstPtIdx];
60 const VECTOR2I& ptA2 = aPtsA[secondPtIdx];
61 const VECTOR2I candidateBaselineA = ptA2 - ptA1;
63 const VECTOR2I& ptB1 = aPtsB[firstPtIdx];
64 const VECTOR2I& ptB2 = aPtsB[secondPtIdx];
65 const VECTOR2I candidateBaselineB = ptB2 - ptB1;
79 if( bestRotation.has_value() )
84 if( !bestRotation.has_value() )
92 std::vector<VECTOR2I> rotatedPtsB = aPtsB;
106 std::optional<size_t> bestPadIdx;
107 size_t bestPadMatches = 0;
109 for(
size_t padIdx = 0; padIdx < aPtsA.size(); padIdx++ )
111 const VECTOR2I translation = aPtsA[padIdx] - rotatedPtsB[padIdx];
114 for(
size_t i = 0; i < aPtsA.size(); i++ )
116 if( ( aPtsA[i] - ( rotatedPtsB[i] + translation ) ).EuclideanNorm() <
epsilon )
120 if( matches > bestPadMatches )
122 bestPadMatches = matches;
127 if( bestPadMatches > aPtsA.size() / 2 )
130 const VECTOR2I translation = aPtsA[*bestPadIdx] - rotatedPtsB[*bestPadIdx];
131 return TRANSFORM{ *bestRotation, translation };
140 VECTOR2I totalDisplacement = { 0, 0 };
141 for(
size_t i = 0; i < aPtsA.size(); i++ )
143 totalDisplacement += aPtsA[i] - rotatedPtsB[i];
146 VECTOR2I minErrorTranslation = totalDisplacement /
static_cast<int>( aPtsA.size() );
148 return TRANSFORM{ *bestRotation, minErrorTranslation };
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.