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

Извините, если название не достаточно ясно, я не был уверен, как суммировать эту проблему, поскольку она очень конкретная и странная. По сути, у меня есть сетка, которую я нарисовал, и я пытаюсь вычислить ориентированную ограничивающую рамку. Для этого я использовал Принципиальный компонентный анализ. После вычисления собственных векторов я нахожу матрицу вращения, которая преобразует собственные векторы на оси 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 часов.

0

Решение

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

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

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

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

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

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

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


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

0

Другие решения


По вопросам рекламы [email protected]