Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LW_POLYLINE total length #62

Open
KhalilSelyan opened this issue Feb 23, 2024 · 1 comment
Open

LW_POLYLINE total length #62

KhalilSelyan opened this issue Feb 23, 2024 · 1 comment

Comments

@KhalilSelyan
Copy link

I'm not really sure where to ask i did some googling etc but i couldn't find a decent way to get the right calculation, this is my current code for it but if anyone has a better solution please help.

Practically all i'm looking for is a way to calculate the total length of a lw_polyline with segments and arcs

fn calculate_lwpolyline_radius(bulge: f64, chord_length: f64) -> f64 {
    let radius = (chord_length * (1.0 + bulge.powi(2))) / (4.0 * bulge.abs());
    radius
}

fn lw_polyline_length(polyline: &dxf::entities::LwPolyline) -> f64 {
    let mut total_length = 0.0;

    for i in 0..polyline.vertices.len() - 1 {
        let start_vertex = &polyline.vertices[i];
        let end_vertex = &polyline.vertices[i + 1];

        // Calculate straight line segment length
        let line_length = ((end_vertex.x - start_vertex.x).powi(2)
            + (end_vertex.y - start_vertex.y).powi(2))
        .sqrt();

        // If the segment is an arc, calculate the arc length
        let bulge = start_vertex.bulge;
        if bulge != 0.0 {
            let theta = 4.0 * bulge.atan();
            let r = calculate_lwpolyline_radius(bulge, line_length);
            let arc_length = r * theta.abs();
            total_length += arc_length;
        } else {
            total_length += line_length;
        }
    }

    total_length
}

If this is seems correct please let me know 😅

@brettfo
Copy link
Member

brettfo commented Feb 23, 2024

I don't know enough geometry to comment on calculate_lwpolyline_radius(bulge, chord_length), so I'll leave that aside.

I think you'll need to change the calculation of arc_length. A few lines above where you calculate let theta = 4.0 * bulge.atan(); looks correct and that gets you the included angle of the arc, so from there you'd want to find the ratio of that to the entire circle's circumference, 2 * pi, so I would do:

let theta = 4.0 * bulge.atan(); // this is correct; theta is the included angle
let r = calculate_lwpolyline_radius(bulge, line_length); // <-- this is the part I'm not sure about, so I'll leave it alone
let full_circle_circumference = 2.0 * std::f64::consts::PI * r; // this is the circumference of the full circle (if it wasn't an arc)
let arc_fraction = theta / (2.0 * std::f64::consts::PI); // this is how much of the circle we actually have: theta / 2pi
let arc_length = arc_fraction * full_circle_circumference; // we only have a fraction of the full circle's circumference

Finally, the LWPOLYLINE might be closed, which means there's an additional segment between polyline.vertices[polyline.vertices.len() - 1] and polyline.vertices[0]. I think there's a polyline.is_closed flag or similar that you can check.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants