Oriented Bounding Box ist falsch und die falsche Größe in OpenGL

Ich schreibe ein Programm in OpenGL, um ein Netz zu laden und einen orientierten Begrenzungsrahmen um das Netz zu zeichnen. Das Netz wird korrekt geladen, aber wenn ich den Begrenzungsrahmen zeichne, hat der Rahmen die falsche Form und ist viel zu klein.

Das Verfahren, mit dem ich diese Box berechnet habe, bestand darin, mithilfe der Hauptkomponentenanalyse eine Kovarianzmatrix zu finden. Ich habe dann die Eigenvektoren dieser Matrix erhalten und diese als lokales Koordinatensystem verwendet, um die 8 Eckpunkte des Würfels zu finden. Dann habe ich eine Transformation berechnet, um den Würfel vom lokalen Koordinatensystem zum globalen Koordinatensystem zu verschieben.

Der Code zur Berechnung der Kovarianz ist hier:

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 = 0;
 for(int i = 0; i < meshVertices.size(); i++)
 {
     mean += meshVertices[i].x;
     mean += meshVertices[i].y;
     mean += meshVertices[i].z;
 }
 mean = mean/(meshVertices.size() * 3);

 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,(double) 1/(meshVertices.size()));
 return sum;
 }

Der Code zur Berechnung der Eigenvektoren ist hier:

void Compute_EigenV(std::array<std::array<double, 3>, 3> covariance, double eigenValues[3], double eigenVectors_1[3], double eigenVectors_2[3], double eigenVectors_3[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);

}

Der Code, der die globalen Koordinaten findet, lautet wie folgt:

std::array<double, 3> localToGlobal(std::array<double, 3> vec, double eigenVector1[3], double eigenVector2[3], double eigenVector3[3], double mean)
{
std::array<double, 3> tempVec;
std::array<std::array<double, 3>, 3> eigenArray;
eigenArray[0][0] = eigenVector1[0]; eigenArray[0][1] = eigenVector2[0]; eigenArray[0][2] = eigenVector3[0];
eigenArray[1][0] = eigenVector1[1]; eigenArray[1][1] = eigenVector2[1]; eigenArray[1][2] = eigenVector3[1];
eigenArray[2][0] = eigenVector1[2]; eigenArray[2][1] = eigenVector2[2]; eigenArray[2][2] = eigenVector3[2];

tempVec = matrixVectorMult(eigenArray, vec);
tempVec[0] += mean;
tempVec[1] += mean;
tempVec[2] += mean;

return tempVec;
}

Der Code, der all dies aufruft und die Box zeichnet, lautet:

void obbBoundingBox()
{

double eigenValues[3] = {0, 0, 0};
double eigenVectors_1[3] = {0, 0, 0}, eigenVectors_2[3] = {0, 0, 0}, eigenVectors_3[3] = {0, 0, 0};

Compute_EigenV(covarianceCalc2(), eigenValues, eigenVectors_1, eigenVectors_2, eigenVectors_3);


std::array<double, 3> point1 = {findVectorMax(eigenVectors_1), findVectorMax(eigenVectors_2), findVectorMax(eigenVectors_3)};
std::array<double, 3> point2 = {findVectorMax(eigenVectors_1), findVectorMax(eigenVectors_2), findVectorMin(eigenVectors_3)};
std::array<double, 3> point3 = {findVectorMax(eigenVectors_1), findVectorMin(eigenVectors_2), findVectorMin(eigenVectors_3)};
std::array<double, 3> point4 = {findVectorMax(eigenVectors_1), findVectorMin(eigenVectors_2), findVectorMin(eigenVectors_3)};
std::array<double, 3> point5 = {findVectorMin(eigenVectors_1), findVectorMax(eigenVectors_2), findVectorMax(eigenVectors_3)};
std::array<double, 3> point6 = {findVectorMin(eigenVectors_1), findVectorMax(eigenVectors_2), findVectorMin(eigenVectors_3)};
std::array<double, 3> point7 = {findVectorMin(eigenVectors_1), findVectorMin(eigenVectors_2), findVectorMax(eigenVectors_3)};
std::array<double, 3> point8 = {findVectorMin(eigenVectors_1), findVectorMin(eigenVectors_2), findVectorMin(eigenVectors_3)};


 double mean = 0;
 for(int i = 0; i < meshVertices.size(); i++)
 {
     mean += meshVertices[i].x;
     mean += meshVertices[i].y;
     mean += meshVertices[i].z;
 }
 mean = mean/(meshVertices.size() * 3);

point1 = localToGlobal(point1, eigenVectors_1, eigenVectors_2, eigenVectors_3, mean);
point2 = localToGlobal(point2, eigenVectors_1, eigenVectors_2, eigenVectors_3, mean);
point3 = localToGlobal(point3, eigenVectors_1, eigenVectors_2, eigenVectors_3, mean);
point4 = localToGlobal(point4, eigenVectors_1, eigenVectors_2, eigenVectors_3, mean);
point5 = localToGlobal(point5, eigenVectors_1, eigenVectors_2, eigenVectors_3, mean);
point6 = localToGlobal(point6, eigenVectors_1, eigenVectors_2, eigenVectors_3, mean);
point7 = localToGlobal(point7, eigenVectors_1, eigenVectors_2, eigenVectors_3, mean);
point8 = localToGlobal(point8, eigenVectors_1, eigenVectors_2, eigenVectors_3, mean);


glEnable(GL_BLEND);
 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 glColor4f(1.0f, 1.0f, 1.0f, 0.5f);

glBegin(GL_QUADS);
//Front Face
    glVertex3f(point1[0], point1[1], point1[2]);
    glVertex3f(point3[0], point3[1], point3[2]);
    glVertex3f(point7[0], point7[1], point7[2]);
    glVertex3f(point5[0], point5[1], point5[2]);
glEnd();

glBegin(GL_QUADS);
//Left Face
    glVertex3f(point5[0], point5[1], point5[2]);
    glVertex3f(point7[0], point7[1], point7[2]);
    glVertex3f(point8[0], point8[1], point8[2]);
    glVertex3f(point6[0], point6[1], point6[2]);
glEnd();

glBegin(GL_QUADS);
//Back Face
    glVertex3f(point6[0], point6[1], point6[2]);
    glVertex3f(point8[0], point8[1], point8[2]);
    glVertex3f(point4[0], point4[1], point4[2]);
    glVertex3f(point2[0], point2[1], point2[2]);
glEnd();

glBegin(GL_QUADS);
//Right Face
    glVertex3f(point2[0], point2[1], point2[2]);
    glVertex3f(point4[0], point4[1], point4[2]);
    glVertex3f(point3[0], point3[1], point3[2]);
    glVertex3f(point1[0], point1[1], point1[2]);
glEnd();

glBegin(GL_QUADS);
//Top Face
    glVertex3f(point2[0], point2[1], point2[2]);
    glVertex3f(point1[0], point1[1], point1[2]);
    glVertex3f(point5[0], point5[1], point5[2]);
    glVertex3f(point6[0], point6[1], point6[2]);
glEnd();

glBegin(GL_QUADS);
//Bottom Face
    glVertex3f(point4[0], point4[1], point4[2]);
    glVertex3f(point3[0], point3[1], point3[2]);
    glVertex3f(point7[0], point7[1], point7[2]);
    glVertex3f(point8[0], point8[1], point8[2]);
glEnd();




 }

Antworten auf die Frage(2)

Ihre Antwort auf die Frage