Вычисления собственного вектора для сбоя OBB на втором проходе через "Утверждение не выполнено"

Извините, если название не достаточно ясно, я не был уверен, как суммировать эту проблему, так как она очень конкретная и странная. По сути, у меня есть сетка, которую я нарисовал, и я пытаюсь вычислить ориентированную ограничивающую рамку. Для этого я использовал Принципиальный компонентный анализ. После вычисления собственных векторов я нахожу матрицу вращения, которая преобразует собственные векторы на оси x, y и z соответственно. Затем я трансформирую сетку с помощью этой матрицы вращения, вычисляю ограничивающий прямоугольник, выровненный по оси, а затем поворачиваю сетку и блок на обратную матрицу вращения. Когда я запускаю программу, она успешно проходит через функцию ограничивающего прямоугольника один раз, хотя ни одного поля не видно, но при втором запуске функции отображения она вылетает при попытке вычислить ограничивающий прямоугольник. Я определил линию, которая вызывает сбой, и она является частью расчетов собственного вектора. Однако, поскольку я использую библиотеку, которую мне дали для вычисления собственных векторов, я не совсем уверен, что происходит в функции, и я не могу определить, почему она не работает. Когда это терпит крах, это дает ошибку "утверждение не удалось", сопровождаемый путем файла моей программы и строкой.

Моя функция для вычисления ковариаций здесь:

std::array<std::array<double, 3>, 3> covarianceCalc2()
{
   std::array<std::array<double, 3>, 3> sum = {{{0, 0, 0}, {0, 0, 0}, {0, 0, 0,}}};
   std::array<double, 3> tempVec;
   double mean;
   for(int i = 0; i < meshVertices.size(); i++)
   {
     mean = (meshVertices[i].x + meshVertices[i].y + meshVertices[i].z)/3;
     tempVec[0] = meshVertices[i].x - mean;
     tempVec[1] = meshVertices[i].y - mean;
     tempVec[2] = meshVertices[i].z - mean;
     sum = matrixAdd(sum, vectorTranposeMult(tempVec));
   }
 sum = matrixMultNum(sum, 1/(meshVertices.size()));
 return sum;
}

Вот код, который вычисляет собственные векторы и вращает их:

 Compute_EigenV(covarianceCalc2(), eigenValues, eigenVectors_1, eigenVectors_2, eigenVectors_3);
 std::array<double, 3> x = {1, 0, 0};
 std::array<double, 3> y = {0, 1, 0};
 std::array<double, 3> z = {0, 0, 1};
 std::array<std::array<double, 3>, 3> transformX = findRotation(eigenVectors_1, x);
 std::array<std::array<double, 3>, 3> transformY = findRotation(eigenVectors_2, y);
 std::array<std::array<double, 3>, 3> transformZ = findRotation(eigenVectors_3, z);


 memcpy(transformX, axisRotateX, sizeof(double) * 3 * 3);
 memcpy(transformY, axisRotateY, sizeof(double) * 3 * 3);
 memcpy(transformZ, axisRotateZ, sizeof(double) * 3 * 3);

Первая строка этого раздела - это строка, которая вызывает сбой. Функция Compute_Eigen выглядит следующим образом:

void Compute_EigenV(std::array<std::array<double, 3>, 3> covariance, std::array<double, 3> eigenValues, std::array<double, 3> eigenVectors_1, std::array<double, 3> eigenVectors_2, std::array<double, 3> eigenVectors_3)
{
    printf("Matrix Stuff\n");
    MatrixXd m(3, 3);
    m << covariance[0][0], covariance[0][1], covariance[0][2],
         covariance[1][0], covariance[1][1], covariance[1][2],
         covariance[2][0], covariance[2][1], covariance[2][2];

    // volving SVD
    printf("EigenSolver\n");
    EigenSolver<MatrixXd> solver(m);
    MatrixXd all_eigenVectors = solver.eigenvectors().real();
    MatrixXd all_eigenValues = solver.eigenvalues().real();

    // find the max index
    printf("Find Max Index\n");
    int INDEX[3];
    double max;
    max=all_eigenValues(0,0);
    int index=0;
    for (int i=1;i<3;i++){
        if (max<all_eigenValues(i,0)){
            max=all_eigenValues(i,0);
            index=i;
        }
    }
    INDEX[0]=index;

    // find the min index
    printf("Find Min Index\n");
    double min;
    min=all_eigenValues(0,0);

    index=0;
    for (int i=1;i<3;i++){
        if (min>all_eigenValues(i,0)){
            min=all_eigenValues(i,0);
            index=i;
        }
    }
    INDEX[1]=3-index-INDEX[0];
    INDEX[2]=index;

    // giave eigenvalues and eien vectors to matrix
    printf("Give values and vector to matrix\n");
    eigenValues[0]=all_eigenValues(INDEX[0],0);
    printf("1");
    eigenValues[1]=all_eigenValues(INDEX[1],0);
    printf("1\n");
    eigenValues[2]=all_eigenValues(INDEX[2],0);

    printf("Vector 1\n");
    VectorXd featureVector_1 = all_eigenVectors.col(INDEX[0]);
    eigenVectors_1[0]=featureVector_1(0);
    eigenVectors_1[1]=featureVector_1(1);
    eigenVectors_1[2]=featureVector_1(2);

    printf("Vector 2\n");
    VectorXd featureVector_2 = all_eigenVectors.col(INDEX[1]);
    eigenVectors_2[0]=featureVector_2(0);
    eigenVectors_2[1]=featureVector_2(1);
    eigenVectors_2[2]=featureVector_2(2);

    printf("Vector 3\n");
    VectorXd featureVector_3 = all_eigenVectors.col(INDEX[2]);
    eigenVectors_3[0]=featureVector_3(0);
    eigenVectors_3[1]=featureVector_3(1);
    eigenVectors_3[2]=featureVector_3(2);

}

Конкретный раздел, в котором происходит сбой программы:

    eigenValues[0]=all_eigenValues(INDEX[0],0);
    eigenValues[1]=all_eigenValues(INDEX[1],0);
    eigenValues[2]=all_eigenValues(INDEX[2],0);

Использование перехода к определению для all_eigenValues ​​показывает этот раздел кода:

/** \returns a reference to the coefficient at given the given row and column.
  *
  * \sa operator[](Index)
  */

EIGEN_STRONG_INLINE Scalar&
operator()(Index row, Index col)
{
  eigen_assert(row >= 0 && row < rows()
      && col >= 0 && col < cols());
  return derived().coeffRef(row, col);
}

К сожалению, я не достаточно опытен с C, чтобы действительно выяснить, что является причиной ошибки здесь. Поскольку это может быть актуально, вот моя функция, которая вычисляет матрицу вращения:

std::array<std::array<double, 3>, 3> findRotation(std::array<double, 3> vec1, std::array<double, 3> vec2)
{
std::array<std::array<double, 3>, 3> tempMatrix, tempMatrix2;
std::array<double, 3> crossProd = crossProduct(vec1, vec2);
double dotProd = dotProduct(vec1, vec2);
double sinAngle = modVector(crossProd)/(modVector(vec1) * modVector(vec2));
std::array<std::array<double, 3>, 3> xProdMatrix = {{{0, crossProd[2] * -1, crossProd[1]}, {crossProd[2], 0, crossProd[0] * -1}, {crossProd[1] * -1, crossProd[0], 0}}}; 
tempMatrix = matrixAdd(iMatrix, xProdMatrix);
tempMatrix2 = matrixMult(xProdMatrix, xProdMatrix);
tempMatrix2 = matrixMultNum(tempMatrix2, (1 - dotProd)/pow(sinAngle, 2));
tempMatrix = matrixAdd(tempMatrix, tempMatrix2);
return tempMatrix;
}

Если вам нужно больше сегментов кода, которые я могу предоставить, я столкнулся с этой проблемой и не добился прогресса в течение нескольких часов, поэтому любая помощь будет признательна.

Я предполагаю, что, поскольку собственное вычисление происходит из библиотеки, ошибка принадлежит мне, а не функции, и если бы мне пришлось угадывать, где моя ошибка, это было бы при вычислении матрицы вращения, но я не смог определить ошибка сама, если она там.

Изменить: Хорошо, я исправил проблему с моими расчетами ковариации, я надеюсь, но, к сожалению, тот же сбой все еще происходит. Я также изменил все свои массивы на std::arrays согласно совету другого комментатора. Я занимаюсь этим уже 7 часов.

1 ответ

Решение

Я верю, что нашел твою проблему.

Вам нужно еще раз проверить теорию! Насколько я помню, у вас есть ковариация, определенная в теории как:

C=1/M \Sum ( (p-pmean)*(p-pmean)^t )

Ну, вы можете заметить, что С является 3x3 матрица, а не значение. Поэтому, когда вы звоните Compute_EigenV и он пытается сделать СВД из 3x3 Матрица, вылетает.

РЕДАКТИРОВАТЬ Выглядит, что вы решили и объяснили эту часть немного, очень хорошо. Утверждение является частью eigen библиотека и как вы можете видеть:

  eigen_assert(row >= 0 && row < rows()   &&  col >= 0 && col < cols());

Просто убедитесь, что на входе матрица 3х3 (в вашем случае). Почему-то этого не происходит. Я уверен, что код Compute_EigenV работает без изменений, потому что мой коллега написал это, и я попробовал, поэтому должно быть что-то не так с тем, как вы объявили переменные, которые вы ввели в функцию.


Опять же, этот код выглядит знакомым;).

Другие вопросы по тегам