Measurement: Circles filtering (part 1)

This commit is contained in:
Lukas Matena 2022-11-03 15:10:47 +01:00
parent 76064fc2ba
commit 4b9630c23b

View File

@ -196,14 +196,17 @@ void MeasuringImpl::update_planes()
if (last_border.size() == 1)
m_planes[plane_id].borders.pop_back();
else {
assert(m_planes[plane_id].borders.front() == m_planes[plane_id].borders.back());
}
}
}
continue; // There was no failure.
PLANE_FAILURE:
m_planes[plane_id].borders.clear();
}
}
@ -233,15 +236,16 @@ void MeasuringImpl::extract_features()
for (const std::vector<Vec3d>& border : plane.borders) {
if (border.size() <= 1)
continue;
assert(border.front() == border.back());
int start_idx = -1;
// First calculate angles at all the vertices.
angles.clear();
lengths.clear();
for (int i=0; i<int(border.size()); ++i) {
const Vec3d& v2 = (i == 0 ? border[0] - border[border.size()-1]
for (int i=0; i<int(border.size()); ++i) { // front is the same as back, hence the weird indexing
const Vec3d& v2 = (i == 0 ? border[0] - border[border.size()-2]
: border[i] - border[i-1]);
const Vec3d& v1 = i == (int)border.size()-1 ? border[0] - border.back()
const Vec3d& v1 = i == (int)border.size()-1 ? border[1] - border.back()
: border[i+1] - border[i];
double angle = atan2(-normal.dot(v1.cross(v2)), -v1.dot(v2)) + M_PI;
if (angle > M_PI)
@ -268,10 +272,24 @@ void MeasuringImpl::extract_features()
}
} else {
if (circle) {
// Add the circle and remember indices into borders.
// Anything made up of less than 4 points shall not be considered a circle.
if (i-start_idx > 3) {
// This may be just a partial circle, maybe a small one generated by two short edges.
// To qualify as a circle, it should cover at least one quadrant. Check this now.
const auto& [center, radius] = get_center_and_radius(border, start_idx, i, trafo);
const Vec3d& p1 = border[start_idx];
const Vec3d& p2 = border[i];
const Vec3d& p3 = border[size_t(start_idx+i)/2];
// Measure angle between the first and the second radiuses. If smaller than 90 deg, measure angle
// between first radius and one corresponding to the middle of the circle.
if ((p1-center).normalized().dot((p2-center).normalized()) < 0.05 // exactly 90 deg might get rejected
|| (p1-center).normalized().dot((p3-center).normalized()) < 0.) {
// Add the circle and remember indices into borders.
circles_idxs.emplace_back(start_idx, i);
circles.emplace_back(SurfaceFeature(SurfaceFeatureType::Circle, center, plane.normal, std::nullopt, radius));
}
}
circle = false;
}
}