bool GEOObjects::mergePoints(std::vector<std::string> const & geo_names, std::string & merged_geo_name, std::vector<std::size_t> &pnt_offsets) { const std::size_t n_geo_names(geo_names.size()); std::vector<GeoLib::Point*>* merged_points (new std::vector<GeoLib::Point*>); std::map<std::string, std::size_t>* merged_pnt_names(new std::map<std::string, std::size_t>); for (std::size_t j(0); j < n_geo_names; j++) { const std::vector<GeoLib::Point*>* pnts(this->getPointVec(geo_names[j])); if (pnts) { std::size_t n_pnts(0); // do not consider stations if (!dynamic_cast<GeoLib::Station*>((*pnts)[0])) { std::string tmp_name; n_pnts = pnts->size(); for (std::size_t k(0); k < n_pnts; k++) { merged_points->push_back(new GeoLib::Point(((*pnts)[k])->getCoords())); if (this->getPointVecObj(geo_names[j])->getNameOfElementByID(k, tmp_name)) { merged_pnt_names->insert( std::pair<std::string, std::size_t>(tmp_name, pnt_offsets[j] + k)); } } } if (n_geo_names - 1 > j) { pnt_offsets[j + 1] = n_pnts + pnt_offsets[j]; } } else return false; //if no points for a given geometry are found, something is fundamentally wrong } addPointVec (merged_points, merged_geo_name, merged_pnt_names, 1e-6); return true; }
void Polygon::ensureCCWOrientation () { // *** pre processing: rotate points to xy-plan // *** copy points to vector - last point is identical to the first std::size_t n_pnts (this->getNumberOfPoints() - 1); std::vector<GeoLib::Point*> tmp_polygon_pnts; for (std::size_t k(0); k < n_pnts; k++) tmp_polygon_pnts.push_back (new GeoLib::Point (*(this->getPoint(k)))); // rotate copied points into x-y-plane GeoLib::rotatePointsToXY(tmp_polygon_pnts); for (auto & tmp_polygon_pnt : tmp_polygon_pnts) (*tmp_polygon_pnt)[2] = 0.0; // should be -= d but there are numerical errors // *** get the left most upper point std::size_t min_x_max_y_idx (0); // for orientation check for (std::size_t k(0); k < n_pnts; k++) if ((*(tmp_polygon_pnts[k]))[0] <= (*(tmp_polygon_pnts[min_x_max_y_idx]))[0]) { if ((*(tmp_polygon_pnts[k]))[0] < (*(tmp_polygon_pnts[min_x_max_y_idx]))[0]) min_x_max_y_idx = k; else if ((*(tmp_polygon_pnts[k]))[1] > (*(tmp_polygon_pnts[min_x_max_y_idx]))[1]) min_x_max_y_idx = k; } // *** determine orientation GeoLib::Orientation orient; if (0 < min_x_max_y_idx && min_x_max_y_idx < n_pnts - 2) orient = GeoLib::getOrientation ( tmp_polygon_pnts[min_x_max_y_idx - 1], tmp_polygon_pnts[min_x_max_y_idx], tmp_polygon_pnts[min_x_max_y_idx + 1]); else { if (0 == min_x_max_y_idx) orient = GeoLib::getOrientation ( tmp_polygon_pnts[n_pnts - 1], tmp_polygon_pnts[0], tmp_polygon_pnts[1]); else orient = GeoLib::getOrientation ( tmp_polygon_pnts[n_pnts - 2], tmp_polygon_pnts[n_pnts - 1], tmp_polygon_pnts[0]); } if (orient != GeoLib::CCW) { // switch orientation std::size_t tmp_n_pnts (n_pnts); tmp_n_pnts++; // include last point of polygon (which is identical to the first) for (std::size_t k(0); k < tmp_n_pnts / 2; k++) std::swap (_ply_pnt_ids[k], _ply_pnt_ids[tmp_n_pnts - 1 - k]); } for (std::size_t k(0); k < n_pnts; k++) delete tmp_polygon_pnts[k]; }
void EarClippingTriangulation::copyPolygonPoints (const GEOLIB::Polygon* polygon) { // copy points - last point is identical to the first size_t n_pnts (polygon->getNumberOfPoints() - 1); for (size_t k(0); k < n_pnts; k++) _pnts.push_back (new GEOLIB::Point (*(polygon->getPoint(k)))); }
void EarClippingTriangulation::ensureCWOrientation () { size_t n_pnts (_pnts.size()); // get the left most upper point size_t min_x_max_y_idx (0); // for orientation check for (size_t k(0); k<n_pnts; k++) { if ((*(_pnts[k]))[0] <= (*(_pnts[min_x_max_y_idx]))[0]) { if ((*(_pnts[k]))[0] < (*(_pnts[min_x_max_y_idx]))[0]) { min_x_max_y_idx = k; } else { if ((*(_pnts[k]))[1] > (*(_pnts[min_x_max_y_idx]))[1]) { min_x_max_y_idx = k; } } } } // determine orientation if (0 < min_x_max_y_idx && min_x_max_y_idx < n_pnts-1) { _original_orient = MathLib::getOrientation ( _pnts[min_x_max_y_idx-1], _pnts[min_x_max_y_idx], _pnts[min_x_max_y_idx+1]); } else { if (0 == min_x_max_y_idx) { _original_orient = MathLib::getOrientation (_pnts[n_pnts-1], _pnts[0], _pnts[1]); } else { _original_orient = MathLib::getOrientation (_pnts[n_pnts-2], _pnts[n_pnts-1], _pnts[0]); } } if (_original_orient == MathLib::CCW) { // switch orientation for (size_t k(0); k<n_pnts/2; k++) { BaseLib::swap (_pnts[k], _pnts[n_pnts-1-k]); } } }
EarClippingTriangulation::EarClippingTriangulation(const GEOLIB::Polygon* polygon, std::list<GEOLIB::Triangle> &triangles, bool rot) { copyPolygonPoints (polygon); if (rot) { rotate (); ensureCWOrientation (); } initVertexList (); initLists (); clipEars (); std::vector<GEOLIB::Point*> const& ref_pnts_vec (polygon->getPointsVec()); std::list<GEOLIB::Triangle>::const_iterator it (_triangles.begin()); if (_original_orient == MathLib::CW) { while (it != _triangles.end()) { const size_t i0 (polygon->getPointID ((*it)[0])); const size_t i1 (polygon->getPointID ((*it)[1])); const size_t i2 (polygon->getPointID ((*it)[2])); triangles.push_back (GEOLIB::Triangle (ref_pnts_vec, i0, i1, i2)); it++; } } else { size_t n_pnts (_pnts.size()-1); while (it != _triangles.end()) { const size_t i0 (polygon->getPointID (n_pnts-(*it)[0])); const size_t i1 (polygon->getPointID (n_pnts-(*it)[1])); const size_t i2 (polygon->getPointID (n_pnts-(*it)[2])); triangles.push_back (GEOLIB::Triangle (ref_pnts_vec, i0, i1, i2)); it++; } } }
void GMSHAdaptiveMeshDensity::init(std::vector<GeoLib::Point const*> const& pnts) { // *** QuadTree - determining bounding box DBUG("GMSHAdaptiveMeshDensity::init(): computing axis aligned bounding box (2D) for quadtree."); GeoLib::Point min(*pnts[0]), max(*pnts[0]); std::size_t n_pnts(pnts.size()); for (std::size_t k(1); k<n_pnts; k++) { for (std::size_t j(0); j < 2; j++) if ((*(pnts[k]))[j] < min[j]) min[j] = (*(pnts[k]))[j]; for (std::size_t j(0); j < 2; j++) if ((*(pnts[k]))[j] > max[j]) max[j] = (*(pnts[k]))[j]; } min[2] = 0.0; max[2] = 0.0; DBUG("GMSHAdaptiveMeshDensity::init(): \tok"); // *** QuadTree - create object DBUG("GMSHAdaptiveMeshDensity::init(): Creating quadtree."); _quad_tree = new GeoLib::QuadTree<GeoLib::Point> (min, max, _max_pnts_per_leaf); DBUG("GMSHAdaptiveMeshDensity::init(): \tok."); // *** QuadTree - insert points addPoints(pnts); }
void Polyline::addPoint(size_t pnt_id) { assert(pnt_id < _ply_pnts.size()); size_t n_pnts(_ply_pnt_ids.size()); _ply_pnt_ids.push_back(pnt_id); if (n_pnts > 0) { double act_dist(sqrt(MathLib::sqrDist(_ply_pnts[_ply_pnt_ids[n_pnts - 1]], _ply_pnts[pnt_id]))); double dist_until_now(0.0); if (n_pnts > 1) dist_until_now = _length[n_pnts - 1]; _length.push_back(dist_until_now + act_dist); } }
void GEOObjects::mergeGeometries (std::vector<std::string> const & geo_names, std::string &merged_geo_name) { const size_t n_geo_names(geo_names.size()); std::vector<size_t> pnt_offsets(n_geo_names, 0); // *** merge points std::vector<GeoLib::Point*>* merged_points (new std::vector<GeoLib::Point*>); for (size_t j(0); j < n_geo_names; j++) { const std::vector<GeoLib::Point*>* pnts (this->getPointVec(geo_names[j])); if (pnts) { size_t n_pnts(0); // do not consider stations if (dynamic_cast<GeoLib::Station*>((*pnts)[0]) == NULL) { n_pnts = pnts->size(); for (size_t k(0); k < n_pnts; k++) merged_points->push_back (new GeoLib::Point (((*pnts)[k])->getCoords())); } if (n_geo_names - 1 > j) { pnt_offsets[j + 1] = n_pnts + pnt_offsets[j]; } } } addPointVec (merged_points, merged_geo_name, NULL, 1e-6); std::vector<size_t> const& id_map (this->getPointVecObj(merged_geo_name)->getIDMap ()); // *** merge polylines std::vector<GeoLib::Polyline*>* merged_polylines (new std::vector<GeoLib::Polyline*>); for (size_t j(0); j < n_geo_names; j++) { const std::vector<GeoLib::Polyline*>* plys (this->getPolylineVec(geo_names[j])); if (plys) { for (size_t k(0); k < plys->size(); k++) { GeoLib::Polyline* kth_ply_new(new GeoLib::Polyline (*merged_points)); GeoLib::Polyline const* const kth_ply_old ((*plys)[k]); const size_t size_of_kth_ply (kth_ply_old->getNumberOfPoints()); // copy point ids from old ply to new ply (considering the offset) for (size_t i(0); i < size_of_kth_ply; i++) { kth_ply_new->addPoint (id_map[pnt_offsets[j] + kth_ply_old->getPointID(i)]); } merged_polylines->push_back (kth_ply_new); } } } this->addPolylineVec (merged_polylines, merged_geo_name); // *** merge surfaces std::vector<GeoLib::Surface*>* merged_sfcs (new std::vector<GeoLib::Surface*>); for (size_t j(0); j < n_geo_names; j++) { const std::vector<GeoLib::Surface*>* sfcs (this->getSurfaceVec(geo_names[j])); if (sfcs) { for (size_t k(0); k < sfcs->size(); k++) { GeoLib::Surface* kth_sfc_new(new GeoLib::Surface (*merged_points)); GeoLib::Surface const* const kth_sfc_old ((*sfcs)[k]); const size_t size_of_kth_sfc (kth_sfc_old->getNTriangles()); // copy point ids from old ply to new ply (considering the offset) for (size_t i(0); i < size_of_kth_sfc; i++) { const GeoLib::Triangle* tri ((*kth_sfc_old)[i]); const size_t id0 (id_map[pnt_offsets[j] + (*tri)[0]]); const size_t id1 (id_map[pnt_offsets[j] + (*tri)[1]]); const size_t id2 (id_map[pnt_offsets[j] + (*tri)[2]]); kth_sfc_new->addTriangle (id0, id1, id2); } merged_sfcs->push_back (kth_sfc_new); } } } this->addSurfaceVec (merged_sfcs, merged_geo_name); }
void EarClippingTriangulation::initVertexList () { size_t n_pnts (_pnts.size()); for (size_t k(0); k < n_pnts; k++) _vertex_list.push_back (k); }