Beispiel #1
0
void PointVec::makePntsUnique (std::vector<GeoLib::Point*>* pnt_vec,
                               std::vector<size_t> &pnt_id_map, double eps)
{
	size_t n_pnts_in_file (pnt_vec->size());
	std::vector<size_t> perm;
	pnt_id_map.reserve (n_pnts_in_file);
	for (size_t k(0); k < n_pnts_in_file; k++)
	{
		perm.push_back (k);
		pnt_id_map.push_back(k);
	}

	// sort the points
	BaseLib::Quicksort<GeoLib::Point*> (*pnt_vec, 0, n_pnts_in_file, perm);

	// unfortunately quicksort is not stable -
	// sort identical points by id - to make sorting stable
	// determine intervals with identical points to resort for stability of sorting
	std::vector<size_t> identical_pnts_interval;
	bool identical (false);
	for (size_t k = 0; k < n_pnts_in_file - 1; k++)
	{
		if ( fabs((*((*pnt_vec)[k + 1]))[0] - (*((*pnt_vec)[k]))[0]) < eps
		     &&  fabs( (*((*pnt_vec)[k + 1]))[1] - (*((*pnt_vec)[k]))[1]) < eps
		     &&  fabs( (*((*pnt_vec)[k + 1]))[2] - (*((*pnt_vec)[k]))[2]) < eps)
		{
			// points are identical, sort by id
			if (!identical)
				identical_pnts_interval.push_back (k);
			identical = true;
		}
		else
		{
			if (identical)
				identical_pnts_interval.push_back (k + 1);
			identical = false;
		}
	}
	if (identical)
		identical_pnts_interval.push_back (n_pnts_in_file);

	for (size_t i(0); i < identical_pnts_interval.size() / 2; i++)
	{
		// bubble sort by id
		size_t beg (identical_pnts_interval[2 * i]);
		size_t end (identical_pnts_interval[2 * i + 1]);
		for (size_t j (beg); j < end; j++)
			for (size_t k (beg); k < end - 1; k++)
				if (perm[k] > perm[k + 1])
					std::swap (perm[k], perm[k + 1]);

	}

	// check if there are identical points
	for (size_t k = 0; k < n_pnts_in_file - 1; k++)
		if ( fabs((*((*pnt_vec)[k + 1]))[0] - (*((*pnt_vec)[k]))[0]) < eps
		     &&  fabs( (*((*pnt_vec)[k + 1]))[1] - (*((*pnt_vec)[k]))[1]) < eps
		     &&  fabs( (*((*pnt_vec)[k + 1]))[2] - (*((*pnt_vec)[k]))[2]) < eps)
			pnt_id_map[perm[k + 1]] = pnt_id_map[perm[k]];

	// reverse permutation
	BaseLib::Quicksort<GeoLib::Point*> (perm, 0, n_pnts_in_file, *pnt_vec);

	// remove the second, third, ... occurrence from vector
	for (size_t k(0); k < n_pnts_in_file; k++)
		if (pnt_id_map[k] < k)
		{
			delete (*pnt_vec)[k];
			(*pnt_vec)[k] = NULL;
		}
	// remove NULL-ptr from vector
	for (std::vector<GeoLib::Point*>::iterator it(pnt_vec->begin()); it != pnt_vec->end(); )
	{
		if (*it == NULL)
			it = pnt_vec->erase (it);
		else
			it++;
	}

	// renumber id-mapping
	size_t cnt (0);
	for (size_t k(0); k < n_pnts_in_file; k++)
	{
		if (pnt_id_map[k] == k) // point not removed, if necessary: id change
		{
			pnt_id_map[k] = cnt;
			cnt++;
		}
		else
			pnt_id_map[k] = pnt_id_map[pnt_id_map[k]];
	}

	// KR correct renumbering of indices
//	size_t cnt(0);
//	std::map<size_t, size_t> reg_ids;
//	for (size_t k(0); k < n_pnts_in_file; k++) {
//		if (pnt_id_map[k] == k) {
//			reg_ids.insert(std::pair<size_t, size_t>(k, cnt));
//			cnt++;
//		} else reg_ids.insert(std::pair<size_t, size_t>(k, reg_ids[pnt_id_map[k]]));
//	}
//	for (size_t k(0); k < n_pnts_in_file; k++)
//		pnt_id_map[k] = reg_ids[k];
}
Beispiel #2
0
void PointVec::makePntsUnique (std::vector<GeoLib::Point*>* pnt_vec,
                               std::vector<std::size_t> &pnt_id_map, double eps)
{
	std::size_t n_pnts_in_file(pnt_vec->size());
	std::vector<std::size_t> perm;
	pnt_id_map.reserve(n_pnts_in_file);
	for (std::size_t k(0); k < n_pnts_in_file; k++) {
		perm.push_back(k);
		pnt_id_map.push_back(k);
	}

	// sort the points
	BaseLib::Quicksort<GeoLib::Point*>(*pnt_vec, 0, n_pnts_in_file, perm);

	// unfortunately quicksort is not stable -
	// sort identical points by id - to make sorting stable
	// determine intervals with identical points to resort for stability of sorting
	std::vector<std::size_t> identical_pnts_interval;
	bool identical(false);
	for (std::size_t k = 0; k < n_pnts_in_file - 1; k++)
	{
		if (MathLib::maxNormDist((*pnt_vec)[k + 1], (*pnt_vec)[k]) <= eps)
		{
			// points are identical, sort by id
			if (!identical)
				identical_pnts_interval.push_back(k);
			identical = true;
		} else {
			if (identical)
				identical_pnts_interval.push_back(k + 1);
			identical = false;
		}
	}
	if (identical)
		identical_pnts_interval.push_back(n_pnts_in_file);

	for (std::size_t i(0); i < identical_pnts_interval.size() / 2; i++) {
		// bubble sort by id
		std::size_t beg(identical_pnts_interval[2 * i]);
		std::size_t end(identical_pnts_interval[2 * i + 1]);
		for (std::size_t j(beg); j < end; j++)
			for (std::size_t k(beg); k < end - 1; k++)
				if (perm[k] > perm[k + 1])
					std::swap(perm[k], perm[k + 1]);

	}

	// check if there are identical points
	for (std::size_t k = 0; k < n_pnts_in_file - 1; k++)
		if (MathLib::maxNormDist((*pnt_vec)[k + 1], (*pnt_vec)[k]) <= eps)
			pnt_id_map[perm[k + 1]] = pnt_id_map[perm[k]];

	// reverse permutation
	BaseLib::Quicksort<std::size_t, GeoLib::Point*>(perm, 0, n_pnts_in_file, *pnt_vec);

	// remove the second, third, ... occurrence from vector
	std::size_t cnt(0); // counts the points that are deleted
	for (std::size_t k(0); k < n_pnts_in_file; k++) {
		if (pnt_id_map[k] < k) {
			delete (*pnt_vec)[k];
			(*pnt_vec)[k] = nullptr;
			cnt++;
		}
	}

	auto const pnt_vec_end = std::remove(pnt_vec->begin(), pnt_vec->end(), nullptr);
	pnt_vec->erase(pnt_vec_end, pnt_vec->end());

	// renumber id-mapping
	cnt = 0;
	for (std::size_t k(0); k < n_pnts_in_file; k++) {
		if (pnt_id_map[k] == k) { // point not removed, if necessary: id change
			pnt_id_map[k] = cnt;
			cnt++;
		} else {
			pnt_id_map[k] = pnt_id_map[pnt_id_map[k]];
		}
	}
}