forked from 1b-agent/opencadstudio-upstream
fix(properties): measure bulged polylines
Merge PR #808 and use kernel area, length, and centroid measurements.
This commit is contained in:
commit
afd4c96a78
3 files changed
+16
-28
No files matched your search
+14
-26
@@ -1053,32 +1053,20 @@ impl crate::entities::traits::MassPropsCalc for acadrust::entities::LwPolyline {
|
||||
cy: 0.0,
|
||||
};
|
||||
}
|
||||
// Shoelace area + perimeter
|
||||
let mut area_sum = 0.0f64;
|
||||
let mut perimeter = 0.0f64;
|
||||
let mut cx_sum = 0.0f64;
|
||||
let mut cy_sum = 0.0f64;
|
||||
let n_segs = if p.is_closed { n } else { n - 1 };
|
||||
for idx in 0..n_segs {
|
||||
let v0 = &p.vertices[idx];
|
||||
let v1 = &p.vertices[(idx + 1) % n];
|
||||
let x0 = v0.location.x;
|
||||
let y0 = v0.location.y;
|
||||
let x1 = v1.location.x;
|
||||
let y1 = v1.location.y;
|
||||
area_sum += x0 * y1 - x1 * y0;
|
||||
perimeter += ((x1 - x0).powi(2) + (y1 - y0).powi(2)).sqrt();
|
||||
cx_sum += (x0 + x1) * (x0 * y1 - x1 * y0);
|
||||
cy_sum += (y0 + y1) * (x0 * y1 - x1 * y0);
|
||||
}
|
||||
let area = (area_sum / 2.0).abs();
|
||||
let (cx, cy) = if area > 1e-12 {
|
||||
(cx_sum / (6.0 * area), cy_sum / (6.0 * area))
|
||||
} else {
|
||||
let sx: f64 = p.vertices.iter().map(|v| v.location.x).sum::<f64>() / n as f64;
|
||||
let sy: f64 = p.vertices.iter().map(|v| v.location.y).sum::<f64>() / n as f64;
|
||||
(sx, sy)
|
||||
};
|
||||
// Kernel measurement includes bulges and closes open curves only for area.
|
||||
let curve = crate::entities::curve::lwpolyline_curve(p)
|
||||
.expect("an LwPolyline with at least two vertices has a planar curve");
|
||||
let area = curve.curve.enclosed_area().abs();
|
||||
let perimeter = curve.length();
|
||||
let (cx, cy) = curve
|
||||
.curve
|
||||
.enclosed_centroid()
|
||||
.map(|point| (point[0], point[1]))
|
||||
.unwrap_or_else(|| {
|
||||
let x = p.vertices.iter().map(|v| v.location.x).sum::<f64>() / n as f64;
|
||||
let y = p.vertices.iter().map(|v| v.location.y).sum::<f64>() / n as f64;
|
||||
(x, y)
|
||||
});
|
||||
crate::entities::traits::MassProps {
|
||||
area,
|
||||
perimeter,
|
||||
|
||||
Reference in new issue
Block a user