TEST( fitTests, fitTest_ApplyFit)
{
- // шаблон - применять готовое наложение
+ RVec mid1, mid2, x1, y1, z1, x2, y2, z2;
+
+ x1[0] = 1; x1[1] = 0; x1[2] = 0;
+ y1[0] = 0; y1[1] = 1; y1[2] = 0;
+ z1[0] = 0; z1[1] = 0; z1[2] = 1;
+
+ x2[0] = -1; x2[1] = 0; x2[2] = 0;
+ y2[0] = 0; y2[1] = -1; y2[2] = 0;
+ z2[0] = 0; z2[1] = 0; z2[2] = -1;
+
+ std::vector< RVec > testFrame1, testFrame2, testFrame3;
+ testFrame1.resize(0);
+ testFrame2.resize(0);
+ std::vector< std::pair< unsigned int, unsigned int > > testPairs;
+ testPairs.resize(0);
+
+ for (unsigned int i = 0; i < 27; i++) {
+ testFrame1.push_back(x1 * static_cast< float >(i % 3) + y1 * static_cast< float >((i % 9) / 3) + z1 * static_cast< float >(i / 9));
+ testFrame2.push_back(x2 * static_cast< float >(i % 3) + y2 * static_cast< float >((i % 9) / 3) + z2 * static_cast< float >(i / 9));
+ testPairs.push_back(std::make_pair(i, i));
+ }
+
+ testFrame3.resize(0);
+ testFrame3 = testFrame2;
+ ApplyFit(testFrame3, 2, 2, 2, 0, 0, 0);
+ CalcMid(testFrame1, testFrame3, mid1, mid2, testPairs);
+ ASSERT_NEAR((mid1 - mid2).norm(), 0, 0.000001);
+
+ testFrame3.resize(0);
+ testFrame3 = testFrame1;
+ ApplyFit(testFrame3, 0, 0, 0, M_PI, 0, -M_PI / 2);
+ CalcMid(testFrame2, testFrame3, mid1, mid2, testPairs);
+ ASSERT_NEAR((mid1 - mid2).norm(), 0, 0.000001);
+
+ testFrame3.resize(0);
+ testFrame3 = testFrame1;
+ ApplyFit(testFrame3, 0, 0, 0, 0, M_PI, M_PI / 2);
+ CalcMid(testFrame2, testFrame3, mid1, mid2, testPairs);
+ ASSERT_NEAR((mid1 - mid2).norm(), 0, 0.000001);
+
+ testFrame3.resize(0);
+ testFrame3 = testFrame1;
+ ApplyFit(testFrame3, 0, 0, 0, M_PI, M_PI / 2, 0);
+ CalcMid(testFrame2, testFrame3, mid1, mid2, testPairs);
+ ASSERT_NEAR((mid1 - mid2).norm(), 0, 0.000001);
+
+ testFrame3.resize(0);
+ testFrame3 = testFrame1;
+ ApplyFit(testFrame3, 0, 0, 0, 3 * M_PI / 2, M_PI / 2, M_PI / 2);
+ CalcMid(testFrame2, testFrame3, mid1, mid2, testPairs);
+ ASSERT_NEAR((mid1 - mid2).norm(), 0, 0.000001);
+
+ testFrame3.resize(0);
+ testFrame3 = testFrame1;
+ ApplyFit(testFrame1, -1, -1, -1, M_PI, 0, -M_PI / 2);
+ ApplyFit(testFrame3, 0, 0, 0, M_PI, 0, -M_PI / 2);
+ ApplyFit(testFrame3, 1, 1, 1, 0, 0, 0);
+ ApplyFit(testFrame1, 2, 4, 8, M_PI / 6, M_PI / 6, M_PI / 6);
+ ApplyFit(testFrame3, 2, 4, 8, M_PI / 6, M_PI / 6, M_PI / 6);
+ CalcMid(testFrame1, testFrame3, mid1, mid2, testPairs);
+ ASSERT_NEAR((mid1 - mid2).norm(), 0, 0.000001);
+ double testF = 0;
+ for (unsigned int i = 0; i < testFrame1.size(); i++) {
+ testF += F(testFrame1[i][0], testFrame1[i][1], testFrame1[i][2], testFrame3[i][0], testFrame3[i][1], testFrame3[i][2], 0, 0, 0);
+ }
+ ASSERT_NEAR(testF, 0, 0.000001);
}
TEST( fitTests, fitTest_CalcMid)
{
- // шаблон - проверка функции
+ RVec mid1, mid2, x1, y1, z1, x2, y2, z2;
+
+ x1[0] = 1; x1[1] = 0; x1[2] = 0;
+ y1[0] = 0; y1[1] = 1; y1[2] = 0;
+ z1[0] = 0; z1[1] = 0; z1[2] = 1;
+
+ x2[0] = -1; x2[1] = 0; x2[2] = 0;
+ y2[0] = 0; y2[1] = -1; y2[2] = 0;
+ z2[0] = 0; z2[1] = 0; z2[2] = -1;
+
+ std::vector< RVec > testFrame1, testFrame2;
+ testFrame1.resize(0);
+ testFrame2.resize(0);
+ std::vector< std::pair< unsigned int, unsigned int > > testPairs;
+ testPairs.resize(0);
+
+ for (unsigned int i = 0; i < 27; i++) {
+ testFrame1.push_back(x1 * static_cast< float >(i % 3) + y1 * static_cast< float >((i % 9) / 3) + z1 * static_cast< float >(i / 9));
+ testFrame2.push_back(x2 * static_cast< float >(i % 3) + y2 * static_cast< float >((i % 9) / 3) + z2 * static_cast< float >(i / 9));
+ testPairs.push_back(std::make_pair(i, i));
+ }
+
+ CalcMid(testFrame1, testFrame1, mid1, mid2, testPairs);
+ ASSERT_NEAR((mid1 - mid2).norm(), 0, 0.000001);
+
+ CalcMid(testFrame2, testFrame2, mid1, mid2, testPairs);
+ ASSERT_NEAR((mid1 - mid2).norm(), 0, 0.000001);
+
+ CalcMid(testFrame1, testFrame2, mid1, mid2, testPairs);
+ ASSERT_NEAR((mid1 - mid2).norm(), 2 * std::sqrt(3), 0.000001);
}
TEST( fitTests, fitTest_MyFitNew)
{
- // шаблон - глобальное применение
+ RVec a, x1, y1, z1;
+
+ x1[0] = 1; x1[1] = 0; x1[2] = 0;
+ y1[0] = 0; y1[1] = 1; y1[2] = 0;
+ z1[0] = 0; z1[1] = 0; z1[2] = 1;
+
+ a[0] = -2; a[1] = -2; a[2] = -2;
+
+ std::vector< RVec > testFrame1, testFrame2, testFrame3;
+ testFrame1.resize(0);
+ testFrame2.resize(0);
+ testFrame3.resize(0);
+ std::vector< std::pair< unsigned int, unsigned int > > testPairs;
+ testPairs.resize(0);
+
+ for (unsigned int i = 0; i < 27; i++) {
+ testFrame1.push_back(x1 * static_cast< float >(i % 3) + y1 * static_cast< float >((i % 9) / 3) + z1 * static_cast< float >(i / 9));
+ testFrame2.push_back(testFrame1.back() + a);
+ testPairs.push_back(std::make_pair(i, i));
+ }
+
+ testFrame3 = testFrame2;
+ MyFitNew(testFrame1, testFrame3, testPairs, 0);
+ double testF = 0;
+ for (unsigned int i = 0; i < testFrame1.size(); i++) {
+ testF += F(testFrame1[i][0], testFrame1[i][1], testFrame1[i][2], testFrame3[i][0], testFrame3[i][1], testFrame3[i][2], 0, 0, 0);
+ }
+ ASSERT_NEAR(testF, 0, 0.000001);
+
+ testFrame3.resize(0);
+ testFrame3 = testFrame2;
+ ApplyFit(testFrame3, 7.1534, 0.5591, -3.1415, M_PI / 23, M_PI / 17, M_PI / 2.2);
+ MyFitNew(testFrame1, testFrame3, testPairs, 0.000001);
+ testF = 0;
+ for (unsigned int i = 0; i < testFrame1.size(); i++) {
+ testF += F(testFrame1[i][0], testFrame1[i][1], testFrame1[i][2], testFrame3[i][0], testFrame3[i][1], testFrame3[i][2], 0, 0, 0);
+ }
+ ASSERT_NEAR(testF, 0, 0.01);
+
+ testFrame3.resize(0);
+ testFrame3 = testFrame2;
+ ApplyFit(testFrame3, 7.1534, 0.5591, -3.1415, M_PI / 23, M_PI / 17, M_PI / 2.2);
+ MyFitNew(testFrame1, testFrame3, testPairs, 0.0000001);
+ testF = 0;
+ for (unsigned int i = 0; i < testFrame1.size(); i++) {
+ testF += F(testFrame1[i][0], testFrame1[i][1], testFrame1[i][2], testFrame3[i][0], testFrame3[i][1], testFrame3[i][2], 0, 0, 0);
+ }
+ ASSERT_NEAR(testF, 0, 0.001);
+
+ testFrame3.resize(0);
+ testFrame3 = testFrame2;
+ ApplyFit(testFrame3, 7.1534, 0.5591, -3.1415, M_PI / 23, M_PI / 17, M_PI / 2.2);
+ MyFitNew(testFrame1, testFrame3, testPairs, 0.0000001);
+ testF = 0;
+ for (unsigned int i = 0; i < testFrame1.size(); i++) {
+ testF += F(testFrame1[i][0], testFrame1[i][1], testFrame1[i][2], testFrame3[i][0], testFrame3[i][1], testFrame3[i][2], 0, 0, 0);
+ }
+ ASSERT_NEAR(testF, 0, 0.0001);
+
+ testFrame3.resize(0);
+ testFrame3 = testFrame2;
+ ApplyFit(testFrame3, 7.1534, 0.5591, -3.1415, M_PI / 23, M_PI / 17, M_PI / 2.2);
+ MyFitNew(testFrame1, testFrame3, testPairs, 0.00000001);
+ testF = 0;
+ for (unsigned int i = 0; i < testFrame1.size(); i++) {
+ testF += F(testFrame1[i][0], testFrame1[i][1], testFrame1[i][2], testFrame3[i][0], testFrame3[i][1], testFrame3[i][2], 0, 0, 0);
+ }
+ ASSERT_NEAR(testF, 0, 0.00001);
+
}
// т.к. домены это класс с кучей приватных функций ещё под вопросом как их тестить
}
int main(int argc, char *argv[]) {
+
+ /*RVec a, x1, y1, z1;
+
+ x1[0] = 1; x1[1] = 0; x1[2] = 0;
+ y1[0] = 0; y1[1] = 1; y1[2] = 0;
+ z1[0] = 0; z1[1] = 0; z1[2] = 1;
+
+ a[0] = -2; a[1] = -2; a[2] = -2;
+
+ std::vector< RVec > testFrame1, testFrame2;
+ testFrame1.resize(0);
+ testFrame2.resize(0);
+ std::vector< std::pair< unsigned int, unsigned int > > testPairs;
+ testPairs.resize(0);
+
+ for (unsigned int i = 0; i < 27; i++) {
+ testFrame1.push_back(x1 * static_cast< float >(i % 3) + y1 * static_cast< float >((i % 9) / 3) + z1 * static_cast< float >(i / 9));
+ testFrame2.push_back(testFrame1.back() + a);
+ testPairs.push_back(std::make_pair(i, i));
+ }
+
+ ApplyFit(testFrame2, 7.1534, 0.5591, -3.1415, M_PI / 23, M_PI / 17, M_PI / 2.2);
+ MyFitNew(testFrame1, testFrame2, testPairs, 0.000000001);
+
+ std::cout << "\n";
+ for (unsigned int i = 0; i < 27; i++) {
+ std::cout << testFrame1[i][0] << " " << testFrame1[i][1] << " " << testFrame1[i][2] << " ";
+ std::cout << testFrame2[i][0] << " " << testFrame2[i][1] << " " << testFrame2[i][2] << "\n";
+ }
+ std::cout << "\n";
+
+ double testF = 0;
+ for (unsigned int i = 0; i < testFrame1.size(); i++) {
+ testF += F(testFrame1[i][0], testFrame1[i][1], testFrame1[i][2], testFrame2[i][0], testFrame2[i][1], testFrame2[i][2], 0, 0, 0);
+ }
+
+ std::cout << testF << "\n\n";*/
+
::testing::InitGoogleTest( &argc, argv );
return RUN_ALL_TESTS();
}
}
// вычисление функции F и её частных производных
-void searchF0xyzabc (double &F, double &Fx, double &Fy, double &Fz, double &Fa, double &Fb, double &Fc, double aix, double aiy, double aiz, double bix_plus_x, double biy_plus_y, double biz_plus_z, double A, double B, double C) {
+void searchF0xyzabc (long double &F, double &Fx, double &Fy, double &Fz, double &Fa, double &Fb, double &Fc, double aix, double aiy, double aiz, double bix_plus_x, double biy_plus_y, double biz_plus_z, double A, double B, double C) {
double t01, t02, t03, t04, t05, t06, t07;
t01 = pow(aix + biy_plus_y * (cos(A) * sin(C) - cos(C) * sin(A) * sin(B)) - biz_plus_z * (sin(A) * sin(C) + cos(A) * cos(C) * sin(B)) - cos(B) * cos(C) * bix_plus_x, 2);
t02 = pow(aiy - biy_plus_y * (cos(A) * cos(C) + sin(A) * sin(B) * sin(C)) + biz_plus_z * (cos(C) * sin(A) - cos(A) * sin(B) * sin(C)) - cos(B) * sin(C) * bix_plus_x, 2);
}
// функция фитирования фрейма b на фрейм a на основе пар pairs с "точностью" FtCnst
-void MyFitNew (std::vector< RVec > a, std::vector< RVec > &b, std::vector< std::pair< unsigned int, unsigned int > > pairs, double FtCnst) {
- double f1 = 0, f2 = 0, fx = 0, fy = 0, fz = 0, fa = 0, fb = 0, fc = 0, l = 1;
+void MyFitNew (std::vector< RVec > a, std::vector< RVec > &b, std::vector< std::pair< unsigned int, unsigned int > > pairs, long double FtCnst) {
+ double fx = 0, fy = 0, fz = 0, fa = 0, fb = 0, fc = 0;
+ long double f1 = 0, f2 = 0, l = 1;
RVec ma, mb;
CalcMid(a, b, ma, mb, pairs);
ma -= mb;
static_cast< double >(b[pairs[i].second][0]) + x, static_cast< double >(b[pairs[i].second][1]) + y, static_cast< double >(b[pairs[i].second][2]) + z, A, B, C);
}
if (FtCnst == 0) {
- FtCnst = 0.00001;
+ FtCnst = 0.0000001;
}
if (f1 == 0) {
+ ApplyFit(b, x, y, z, A, B, C);
return;
} else {
// поиск оптимального геометрического преобразования методом градиентного спуска
}
if (f2 < f1) {
x -= l * fx; y -= l * fy; z -= l * fz; A -= l * fa; B -= l * fb; C -= l * fc;
- fx = 0; fy = 0; fz = 0; fa = 0; fb = 0; fc = 0;
break;
} else {
// по факту существует минимальное значение переменной типа double