Measurement: Circles filtering (part 1)
This commit is contained in:
parent
76064fc2ba
commit
4b9630c23b
@ -196,14 +196,17 @@ void MeasuringImpl::update_planes()
|
|||||||
|
|
||||||
if (last_border.size() == 1)
|
if (last_border.size() == 1)
|
||||||
m_planes[plane_id].borders.pop_back();
|
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.
|
continue; // There was no failure.
|
||||||
|
|
||||||
PLANE_FAILURE:
|
PLANE_FAILURE:
|
||||||
m_planes[plane_id].borders.clear();
|
m_planes[plane_id].borders.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -233,15 +236,16 @@ void MeasuringImpl::extract_features()
|
|||||||
for (const std::vector<Vec3d>& border : plane.borders) {
|
for (const std::vector<Vec3d>& border : plane.borders) {
|
||||||
if (border.size() <= 1)
|
if (border.size() <= 1)
|
||||||
continue;
|
continue;
|
||||||
|
assert(border.front() == border.back());
|
||||||
int start_idx = -1;
|
int start_idx = -1;
|
||||||
|
|
||||||
// First calculate angles at all the vertices.
|
// First calculate angles at all the vertices.
|
||||||
angles.clear();
|
angles.clear();
|
||||||
lengths.clear();
|
lengths.clear();
|
||||||
for (int i=0; i<int(border.size()); ++i) {
|
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()-1]
|
const Vec3d& v2 = (i == 0 ? border[0] - border[border.size()-2]
|
||||||
: border[i] - border[i-1]);
|
: 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];
|
: border[i+1] - border[i];
|
||||||
double angle = atan2(-normal.dot(v1.cross(v2)), -v1.dot(v2)) + M_PI;
|
double angle = atan2(-normal.dot(v1.cross(v2)), -v1.dot(v2)) + M_PI;
|
||||||
if (angle > M_PI)
|
if (angle > M_PI)
|
||||||
@ -268,10 +272,24 @@ void MeasuringImpl::extract_features()
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (circle) {
|
if (circle) {
|
||||||
// Add the circle and remember indices into borders.
|
// Anything made up of less than 4 points shall not be considered a circle.
|
||||||
const auto& [center, radius] = get_center_and_radius(border, start_idx, i, trafo);
|
if (i-start_idx > 3) {
|
||||||
circles_idxs.emplace_back(start_idx, i);
|
// This may be just a partial circle, maybe a small one generated by two short edges.
|
||||||
circles.emplace_back(SurfaceFeature(SurfaceFeatureType::Circle, center, plane.normal, std::nullopt, radius));
|
// 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;
|
circle = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user