static libmv::Marker ProjectMarker(const libmv::EuclideanPoint &point, const libmv::EuclideanCamera &camera, const libmv::CameraIntrinsics &intrinsics) { libmv::Vec3 projected = camera.R * point.X + camera.t; projected /= projected(2); libmv::Marker reprojected_marker; intrinsics.ApplyIntrinsics(projected(0), projected(1), &reprojected_marker.x, &reprojected_marker.y); reprojected_marker.image = camera.image; reprojected_marker.track = point.track; return reprojected_marker; }
void extract_convex(pcl_cloud::Ptr cloud_in, pcl::PointIndices::Ptr inliers, pcl::ModelCoefficients::Ptr coefficients, pcl_cloud::Ptr cloud_hull, pcl_cloud::Ptr cloud_cave) { pcl_cloud::Ptr projected(new pcl_cloud()); pcl::ProjectInliers<Point> proj; proj.setModelType (pcl::SACMODEL_PLANE); proj.setIndices (inliers); proj.setInputCloud (cloud_in); proj.setModelCoefficients (coefficients); proj.filter (*projected); pcl::ConvexHull<Point> chull; chull.setInputCloud (projected); chull.reconstruct (*cloud_hull); pcl::ConcaveHull<Point> cavehull; cavehull.setAlpha(0.1); cavehull.setInputCloud (projected); cavehull.reconstruct (*cloud_cave); }
void PointAnnotationImpl::updateLayer(const CanonicalTileID& tileID, AnnotationTileLayer& layer) const { std::unordered_map<std::string, std::string> featureProperties; featureProperties.emplace("sprite", point.icon.empty() ? std::string("default_marker") : point.icon); // Clamp to the latitude limits of Web Mercator. const double constrainedLatitude = util::clamp(point.position.latitude, -util::LATITUDE_MAX, util::LATITUDE_MAX); // Project a coordinate into unit space in a square map. const double sine = std::sin(constrainedLatitude * util::DEG2RAD); const double x = point.position.longitude / util::DEGREES_MAX + 0.5; const double y = 0.5 - 0.25 * std::log((1.0 + sine) / (1.0 - sine)) / M_PI; Point<double> projected(x, y); projected *= std::pow(2, tileID.z); projected.x = std::fmod(projected.x, 1); projected.y = std::fmod(projected.y, 1); projected *= double(util::EXTENT); layer.features.emplace_back( std::make_shared<const AnnotationTileFeature>(FeatureType::Point, GeometryCollection {{ {{ convertPoint<int16_t>(projected) }} }}, featureProperties)); }
void AnalyzerTest::testResiduals() { debug(LOG_DEBUG, DEBUG_LOG, 0, "testResiduals() begin"); // read the chart image FITSinfile<float> chart("testimages/deneb-chart.fits"); Image<float> *image1 = chart.read(); TypeReductionAdapter<double, float> base(*image1); // read the projected image FITSinfile<double> projected("testimages/deneb-projected.fits"); Image<double> *image2 = projected.read(); // compute the residuals Analyzer analyzer(base); std::vector<Residual> residuals = analyzer(*image2); debug(LOG_DEBUG, DEBUG_LOG, 0, "%d residuals", residuals.size()); std::vector<Residual>::const_iterator r; for (r = residuals.begin(); r != residuals.end(); r++) { // std::cout << r->first << " -> " << r->second << std::endl; } debug(LOG_DEBUG, DEBUG_LOG, 0, "testResiduals() end"); }
Line SegmentStitching::extractLineFromMeasurements(pcl::PointCloud<pcl::PointXYZ>::Ptr measurements, float ransacThreshold, std::vector<int>* inliers){ // Create the sample consensus object for the received cloud pcl::SampleConsensusModelLine<pcl::PointXYZ>::Ptr modelLine(new pcl::SampleConsensusModelLine<pcl::PointXYZ>(measurements)); pcl::RandomSampleConsensus<pcl::PointXYZ> ransac(modelLine); ransac.setDistanceThreshold(ransacThreshold); ransac.computeModel(); ransac.getInliers(*inliers); // Vector of 6 points // see http://docs.pointclouds.org/trunk/classpcl_1_1_sample_consensus_model_line.html Eigen::VectorXf coeff; ransac.getModelCoefficients(coeff); for (int i = 0; i < coeff.size(); i++){ ROS_INFO("Coeff %d: %f", i, coeff[i]); } ROS_INFO("#Inliers: %d", (int)inliers->size()); // Project inliers onto the line so that we end up with a cloud where // min+max can be found in order to define a line segment pcl::PointCloud<pcl::PointXYZ>::Ptr projected(new pcl::PointCloud<pcl::PointXYZ>); // project the inliers onto the model, without copying non-inliers over modelLine->projectPoints(*inliers, coeff, *projected, false); ROS_INFO("Projected size: %d", (int)projected->size()); pcl::PointCloud<pcl::PointXYZ>::iterator it = projected->begin(); // Segments have start and end points. A point is at the start or end of the // line if one of its coordinates corresponds to the minimum or maximum // value of either of the coordinate axes int xmaxInd = -1; int xminInd = -1; int ymaxInd = -1; int yminInd = -1; float xmax = -std::numeric_limits<float>::max(); float ymax = -std::numeric_limits<float>::max(); float xmin = std::numeric_limits<float>::max(); float ymin = std::numeric_limits<float>::max(); for (; it != projected->end(); it++) { // ROS_INFO_STREAM("Point " << (int)(it - projected->begin()) << ": " << *it); // std::cout << "x: " << it->x << ", max: " << xmax << " x bigger? " << (it->x > xmax) << std::endl; if (it->x > xmax){ xmax = it->x; // index of this point is xmaxInd = it - projected->begin(); //ROS_INFO("X max ind: %d with val %f", xmaxInd, xmax); } if (it->y > ymax){ ymax = it->y; // index of this point is ymaxInd = it - projected->begin(); //ROS_INFO("Y max ind: %d with val %f", ymaxInd, ymax); } if (it->x < xmin){ xmin = it->x; // index of this point is xminInd = it - projected->begin(); //ROS_INFO("X min ind: %d with val %f", xminInd, xmin); } if (it->y < ymin){ ymin = it->y; // index of this point is yminInd = it - projected->begin(); //ROS_INFO("Y min ind: %d with val %f", yminInd, ymin); } } ROS_INFO("xmin ind %d, xmax ind %d, ymin ind %d, ymax ind %d", xminInd, xmaxInd, yminInd, ymaxInd); ROS_INFO("xmin %f, xmax %f, ymin %f, ymax %f", xmin, xmax, ymin, ymax); // If the x or y coordinates are identical, then you have a vertical or // horizontal line - define start and end points of the line with the value // of xmin or max, and then assign values for the other coordinate to the // start and end point arbitrarily. You should be able to do this min/max // comparison based on the indices of xmin and xmax - they should be the same // if lines are horizontal or vertical if (xminInd == xmaxInd){ return Line(pcl::PointXYZ(xmin, ymin, 0), pcl::PointXYZ(xmin, ymax, 0)); } else if (yminInd == ymaxInd){ return Line(pcl::PointXYZ(xmin, ymin, 0), pcl::PointXYZ(xmax, ymin, 0)); } else { // TODO: Make sure this works correctly // This is a line which is not horizontal or vertical - the indices of // xmin,ymin or xmax, ymax should match. if (xminInd == yminInd && xmaxInd == ymaxInd){ return Line(pcl::PointXYZ(xmin, ymin, 0), pcl::PointXYZ(xmax, ymax, 0)); } else if (xmaxInd == yminInd && xminInd == ymaxInd){ return Line(pcl::PointXYZ(xmax, ymin, 0), pcl::PointXYZ(xmin, ymax, 0)); } } ROS_ERROR("Reached end of extract line without getting anything!"); }
void MeshViewerWindow::fileDrop(int pathCount, const char** paths) { bool meshLoadedThisDrop = false; for (int pathIndex = 0; pathIndex < pathCount; ++pathIndex) { if (gtf::StaticMeshLoader::isMeshFile(paths[pathIndex])) { if (!meshLoadedThisDrop && m_meshLoader.loadFromFile(paths[pathIndex], m_mesh)) { m_texturedShapes.clear(); //reset camera m_frame.scale = 1.0f; m_frame.position = glm::vec3(0.0f); m_frame.viewPosition = glm::vec3(0.0f, 0.0f, -150.0f); m_frame.rotation = glm::vec3(0.0f); m_frame.scaleFactor = 1.0f; m_projectionMatrix = glm::perspective(220.0f, (float)m_windowWidth / glm::max(1.0f, (float)m_windowHeight), 1.0f, 1000.0f); m_modelMatrix = glm::mat4(1.0); m_viewMatrix = glm::translate(glm::mat4(1.0), m_frame.viewPosition); glm::vec2 topLeft(0, 0), bottomRight(0, 0); float midZ = 0.0f; glm::vec4 viewport(0, 0, m_windowWidth, m_windowHeight); glm::mat4 vpMatrix = m_projectionMatrix * m_viewMatrix; glm::mat4 ivpMatrix = glm::inverse(vpMatrix); int shapeCount = m_mesh.getShapeCount(); for (int s = 0; s < shapeCount; ++s) { gtf::StaticMesh::Shape const * shape = m_mesh.getShape(s); std::shared_ptr<gtf::RHIVAO> newVAO(gtf::GRHI->createVertexBufferObject()); newVAO->setup(m_attrList, shape->data, shape->vertexCount); //m_vaos.push_back(newVAO); TexturedShape texturedShape; texturedShape.name = shape->name; texturedShape.vao = newVAO; m_texturedShapes.push_back(texturedShape); //trying to calculate a default transformation to fid the viewport for (size_t vc = 0; vc < shape->vertexCount; vc++) { glm::vec4 projected(shape->data[vc].posX, shape->data[vc].posY, shape->data[vc].posZ, 1.0f); projected = vpMatrix * projected; projected /= projected.w; if (vc == 0) { topLeft.x = projected.x; topLeft.y = projected.y; bottomRight.x = projected.x; bottomRight.y = projected.y; } else { if (projected.x < topLeft.x) topLeft.x = projected.x; if (projected.x > bottomRight.x) bottomRight.x = projected.x; if (projected.y > topLeft.y) topLeft.y = projected.y; if (projected.y < bottomRight.y) bottomRight.y = projected.y; } midZ += projected.z; } midZ /= float(shape->vertexCount); } std::cout << "topLeft = (" << topLeft.x << ", " << topLeft.y << ")" << std::endl; std::cout << "bottomRight = (" << bottomRight.x << ", " << bottomRight.y << ")" << std::endl; float fixX = (bottomRight.x + topLeft.x) * 0.5f; float fixY = (bottomRight.y + topLeft.y) * 0.5f; glm::vec4 fixTranslate(fixX, -fixY, midZ, 1.0f); std::cout << "fixTranslate preProj = (" << fixTranslate.x << ", " << fixTranslate.y << ")" << std::endl; fixTranslate = ivpMatrix * fixTranslate; fixTranslate /= fixTranslate.w; fixTranslate.z = 0; std::cout << "fixTranslate = (" << fixTranslate.x << ", " << fixTranslate.y << ")" << std::endl; topLeft += glm::vec2(fixX, -fixY); bottomRight += glm::vec2(fixX, -fixY); float fixScale = 1.0f; if (glm::abs(topLeft.x) > glm::abs(bottomRight.x)) { if (glm::abs(topLeft.x) > glm::abs(topLeft.y)) { fixScale = 0.75f / glm::abs(topLeft.x); } else { fixScale = 0.75f / glm::abs(topLeft.y); } } else { if (glm::abs(bottomRight.x) > glm::abs(bottomRight.y)) { fixScale = 0.75f / glm::abs(bottomRight.x); } else { fixScale = 0.75f / glm::abs(bottomRight.y); } } std::cout << "fixScale = " << fixScale << std::endl; m_frame.scale = fixScale; m_frame.scaleFactor = fixScale; m_frame.position = glm::vec3(fixTranslate); } } } }
bool Box::testHit(Brick* brick) const { ofVec3f projected(brick->getHitPolygon().getPlane().project(getCenter())); bool result = brick->getHitPolygon().isInPolygon(projected); return result; }
SOrientedBoundingBox * SOrientedBoundingBox::buildOBB(std::vector<SPoint3> &vertices) { #if defined(HAVE_MESH) int num_vertices = vertices.size(); // First organize the data std::set<SPoint3> unique; unique.insert(vertices.begin(), vertices.end()); num_vertices = unique.size(); fullMatrix<double> data(3, num_vertices); fullVector<double> mean(3); fullVector<double> vmins(3); fullVector<double> vmaxs(3); mean.setAll(0); vmins.setAll(DBL_MAX); vmaxs.setAll(-DBL_MAX); size_t idx = 0; for(std::set<SPoint3>::iterator uIter = unique.begin(); uIter != unique.end(); ++uIter) { const SPoint3 &pp = *uIter; for(int d = 0; d < 3; d++) { data(d, idx) = pp[d]; vmins(d) = std::min(vmins(d), pp[d]); vmaxs(d) = std::max(vmaxs(d), pp[d]); mean(d) += pp[d]; } idx++; } for(int i = 0; i < 3; i++) { mean(i) /= num_vertices; } // Get the deviation from the mean fullMatrix<double> B(3, num_vertices); for(int i = 0; i < 3; i++) { for(int j = 0; j < num_vertices; j++) { B(i, j) = data(i, j) - mean(i); } } // Compute the covariance matrix fullMatrix<double> covariance(3, 3); B.mult(B.transpose(), covariance); covariance.scale(1. / (num_vertices - 1)); /* Msg::Debug("Covariance matrix"); Msg::Debug("%f %f %f", covariance(0,0),covariance(0,1),covariance(0,2) ); Msg::Debug("%f %f %f", covariance(1,0),covariance(1,1),covariance(1,2) ); Msg::Debug("%f %f %f", covariance(2,0),covariance(2,1),covariance(2,2) ); */ for(int i = 0; i < 3; i++) { for(int j = 0; j < 3; j++) { if(std::abs(covariance(i, j)) < 10e-16) covariance(i, j) = 0; } } fullMatrix<double> left_eigv(3, 3); fullMatrix<double> right_eigv(3, 3); fullVector<double> real_eig(3); fullVector<double> img_eig(3); covariance.eig(real_eig, img_eig, left_eigv, right_eigv, true); // Now, project the data in the new basis. fullMatrix<double> projected(3, num_vertices); left_eigv.transpose().mult(data, projected); // Get the size of the box in the new direction fullVector<double> mins(3); fullVector<double> maxs(3); for(int i = 0; i < 3; i++) { mins(i) = DBL_MAX; maxs(i) = -DBL_MAX; for(int j = 0; j < num_vertices; j++) { maxs(i) = std::max(maxs(i), projected(i, j)); mins(i) = std::min(mins(i), projected(i, j)); } } // double means[3]; double sizes[3]; // Note: the size is computed in the box's coordinates! for(int i = 0; i < 3; i++) { sizes[i] = maxs(i) - mins(i); // means[i] = (maxs(i) - mins(i)) / 2.; } if(sizes[0] == 0 && sizes[1] == 0) { // Entity is a straight line... SVector3 center; SVector3 Axis1; SVector3 Axis2; SVector3 Axis3; Axis1[0] = left_eigv(0, 0); Axis1[1] = left_eigv(1, 0); Axis1[2] = left_eigv(2, 0); Axis2[0] = left_eigv(0, 1); Axis2[1] = left_eigv(1, 1); Axis2[2] = left_eigv(2, 1); Axis3[0] = left_eigv(0, 2); Axis3[1] = left_eigv(1, 2); Axis3[2] = left_eigv(2, 2); center[0] = (vmaxs(0) + vmins(0)) / 2.0; center[1] = (vmaxs(1) + vmins(1)) / 2.0; center[2] = (vmaxs(2) + vmins(2)) / 2.0; return new SOrientedBoundingBox(center, sizes[0], sizes[1], sizes[2], Axis1, Axis2, Axis3); } // We take the smallest component, then project the data on the plane defined // by the other twos int smallest_comp = 0; if(sizes[0] <= sizes[1] && sizes[0] <= sizes[2]) smallest_comp = 0; else if(sizes[1] <= sizes[0] && sizes[1] <= sizes[2]) smallest_comp = 1; else if(sizes[2] <= sizes[0] && sizes[2] <= sizes[1]) smallest_comp = 2; // The projection has been done circa line 161. // We just ignore the coordinate corresponding to smallest_comp. std::vector<SPoint2 *> points; for(int i = 0; i < num_vertices; i++) { SPoint2 *p = new SPoint2(projected(smallest_comp == 0 ? 1 : 0, i), projected(smallest_comp == 2 ? 1 : 2, i)); bool keep = true; for(std::vector<SPoint2 *>::iterator point = points.begin(); point != points.end(); point++) { if(std::abs((*p)[0] - (**point)[0]) < 10e-10 && std::abs((*p)[1] - (**point)[1]) < 10e-10) { keep = false; break; } } if(keep) { points.push_back(p); } else { delete p; } } // Find the convex hull from a delaunay triangulation of the points DocRecord record(points.size()); record.numPoints = points.size(); srand((unsigned)time(0)); for(std::size_t i = 0; i < points.size(); i++) { record.points[i].where.h = points[i]->x() + (10e-6) * sizes[smallest_comp == 0 ? 1 : 0] * (-0.5 + ((double)rand()) / RAND_MAX); record.points[i].where.v = points[i]->y() + (10e-6) * sizes[smallest_comp == 2 ? 1 : 0] * (-0.5 + ((double)rand()) / RAND_MAX); record.points[i].adjacent = NULL; } try { record.MakeMeshWithPoints(); } catch(const char *err) { Msg::Error("%s", err); } std::vector<Segment> convex_hull; for(int i = 0; i < record.numTriangles; i++) { Segment segs[3]; segs[0].from = record.triangles[i].a; segs[0].to = record.triangles[i].b; segs[1].from = record.triangles[i].b; segs[1].to = record.triangles[i].c; segs[2].from = record.triangles[i].c; segs[2].to = record.triangles[i].a; for(int j = 0; j < 3; j++) { bool okay = true; for(std::vector<Segment>::iterator seg = convex_hull.begin(); seg != convex_hull.end(); seg++) { if(((*seg).from == segs[j].from && (*seg).from == segs[j].to) // FIXME: // || ((*seg).from == segs[j].to && (*seg).from == segs[j].from) ) { convex_hull.erase(seg); okay = false; break; } } if(okay) { convex_hull.push_back(segs[j]); } } } // Now, examinate all the directions given by the edges of the convex hull // to find the one that lets us build the least-area bounding rectangle for // then points. fullVector<double> axis(2); axis(0) = 1; axis(1) = 0; fullVector<double> axis2(2); axis2(0) = 0; axis2(1) = 1; SOrientedBoundingRectangle least_rectangle; least_rectangle.center[0] = 0.0; least_rectangle.center[1] = 0.0; least_rectangle.size[0] = -1.0; least_rectangle.size[1] = 1.0; fullVector<double> segment(2); fullMatrix<double> rotation(2, 2); for(std::vector<Segment>::iterator seg = convex_hull.begin(); seg != convex_hull.end(); seg++) { // segment(0) = record.points[(*seg).from].where.h - // record.points[(*seg).to].where.h; segment(1) = // record.points[(*seg).from].where.v - record.points[(*seg).to].where.v; segment(0) = points[(*seg).from]->x() - points[(*seg).to]->x(); segment(1) = points[(*seg).from]->y() - points[(*seg).to]->y(); segment.scale(1.0 / segment.norm()); double cosine = axis(0) * segment(0) + segment(1) * axis(1); double sine = axis(1) * segment(0) - segment(1) * axis(0); // double sine = axis(0)*segment(1) - segment(0)*axis(1); rotation(0, 0) = cosine; rotation(0, 1) = sine; rotation(1, 0) = -sine; rotation(1, 1) = cosine; // TODO C++11 std::numeric_limits<double> double max_x = -DBL_MAX; double min_x = DBL_MAX; double max_y = -DBL_MAX; double min_y = DBL_MAX; for(int i = 0; i < record.numPoints; i++) { fullVector<double> pnt(2); // pnt(0) = record.points[i].where.h; // pnt(1) = record.points[i].where.v; pnt(0) = points[i]->x(); pnt(1) = points[i]->y(); fullVector<double> rot_pnt(2); rotation.mult(pnt, rot_pnt); if(rot_pnt(0) < min_x) min_x = rot_pnt(0); if(rot_pnt(0) > max_x) max_x = rot_pnt(0); if(rot_pnt(1) < min_y) min_y = rot_pnt(1); if(rot_pnt(1) > max_y) max_y = rot_pnt(1); } /**/ fullVector<double> center_rot(2); fullVector<double> center_before_rot(2); center_before_rot(0) = (max_x + min_x) / 2.0; center_before_rot(1) = (max_y + min_y) / 2.0; fullMatrix<double> rotation_inv(2, 2); rotation_inv(0, 0) = cosine; rotation_inv(0, 1) = -sine; rotation_inv(1, 0) = sine; rotation_inv(1, 1) = cosine; rotation_inv.mult(center_before_rot, center_rot); fullVector<double> axis_rot1(2); fullVector<double> axis_rot2(2); rotation_inv.mult(axis, axis_rot1); rotation_inv.mult(axis2, axis_rot2); if((least_rectangle.area() == -1) || (max_x - min_x) * (max_y - min_y) < least_rectangle.area()) { least_rectangle.size[0] = max_x - min_x; least_rectangle.size[1] = max_y - min_y; least_rectangle.center[0] = (max_x + min_x) / 2.0; least_rectangle.center[1] = (max_y + min_y) / 2.0; least_rectangle.center[0] = center_rot(0); least_rectangle.center[1] = center_rot(1); least_rectangle.axisX[0] = axis_rot1(0); least_rectangle.axisX[1] = axis_rot1(1); // least_rectangle.axisX[0] = segment(0); // least_rectangle.axisX[1] = segment(1); least_rectangle.axisY[0] = axis_rot2(0); least_rectangle.axisY[1] = axis_rot2(1); } } // TODO C++11 std::numeric_limits<double>::min() / max() double min_pca = DBL_MAX; double max_pca = -DBL_MAX; for(int i = 0; i < num_vertices; i++) { min_pca = std::min(min_pca, projected(smallest_comp, i)); max_pca = std::max(max_pca, projected(smallest_comp, i)); } double center_pca = (max_pca + min_pca) / 2.0; double size_pca = (max_pca - min_pca); double raw_data[3][5]; raw_data[0][0] = size_pca; raw_data[1][0] = least_rectangle.size[0]; raw_data[2][0] = least_rectangle.size[1]; raw_data[0][1] = center_pca; raw_data[1][1] = least_rectangle.center[0]; raw_data[2][1] = least_rectangle.center[1]; for(int i = 0; i < 3; i++) { raw_data[0][2 + i] = left_eigv(i, smallest_comp); raw_data[1][2 + i] = least_rectangle.axisX[0] * left_eigv(i, smallest_comp == 0 ? 1 : 0) + least_rectangle.axisX[1] * left_eigv(i, smallest_comp == 2 ? 1 : 2); raw_data[2][2 + i] = least_rectangle.axisY[0] * left_eigv(i, smallest_comp == 0 ? 1 : 0) + least_rectangle.axisY[1] * left_eigv(i, smallest_comp == 2 ? 1 : 2); } // Msg::Info("Test 1 : %f // %f",least_rectangle.center[0],least_rectangle.center[1]); // Msg::Info("Test 2 : %f // %f",least_rectangle.axisY[0],least_rectangle.axisY[1]); int tri[3]; if(size_pca > least_rectangle.size[0]) { // P > R0 if(size_pca > least_rectangle.size[1]) { // P > R1 tri[0] = 0; if(least_rectangle.size[0] > least_rectangle.size[1]) { // R0 > R1 tri[1] = 1; tri[2] = 2; } else { // R1 > R0 tri[1] = 2; tri[2] = 1; } } else { // P < R1 tri[0] = 2; tri[1] = 0; tri[2] = 1; } } else { // P < R0 if(size_pca < least_rectangle.size[1]) { // P < R1 tri[2] = 0; if(least_rectangle.size[0] > least_rectangle.size[1]) { tri[0] = 1; tri[1] = 2; } else { tri[0] = 2; tri[1] = 1; } } else { tri[0] = 1; tri[1] = 0; tri[2] = 2; } } SVector3 size; SVector3 center; SVector3 Axis1; SVector3 Axis2; SVector3 Axis3; for(int i = 0; i < 3; i++) { size[i] = raw_data[tri[i]][0]; center[i] = raw_data[tri[i]][1]; Axis1[i] = raw_data[tri[0]][2 + i]; Axis2[i] = raw_data[tri[1]][2 + i]; Axis3[i] = raw_data[tri[2]][2 + i]; } SVector3 aux1; SVector3 aux2; SVector3 aux3; for(int i = 0; i < 3; i++) { aux1(i) = left_eigv(i, smallest_comp); aux2(i) = left_eigv(i, smallest_comp == 0 ? 1 : 0); aux3(i) = left_eigv(i, smallest_comp == 2 ? 1 : 2); } center = aux1 * center_pca + aux2 * least_rectangle.center[0] + aux3 * least_rectangle.center[1]; // center[1] = -center[1]; /* Msg::Info("Box center : %f %f %f",center[0],center[1],center[2]); Msg::Info("Box size : %f %f %f",size[0],size[1],size[2]); Msg::Info("Box axis 1 : %f %f %f",Axis1[0],Axis1[1],Axis1[2]); Msg::Info("Box axis 2 : %f %f %f",Axis2[0],Axis2[1],Axis2[2]); Msg::Info("Box axis 3 : %f %f %f",Axis3[0],Axis3[1],Axis3[2]); Msg::Info("Volume : %f", size[0]*size[1]*size[2]); */ return new SOrientedBoundingBox(center, size[0], size[1], size[2], Axis1, Axis2, Axis3); #else Msg::Error("SOrientedBoundingBox requires mesh module"); return 0; #endif }