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

Point boundaries #414

Open
tsturzl opened this issue Jan 17, 2020 · 5 comments
Open

Point boundaries #414

tsturzl opened this issue Jan 17, 2020 · 5 comments

Comments

@tsturzl
Copy link

tsturzl commented Jan 17, 2020

I've been using this crate recently for some robotics path planning experiments. I've done similar work using python and shapely, and the fact that this crate offers a lot of the features shapely does I felt like it was a great fit(thanks for making this crate). One thing I haven't figure out how to do is create a circle with a radius. In shapely you do this by adding a boundary to a circle(see here for example), and then if you intersect a line with this point it intersects this boundary. I don't see any way to do this in geo currently. It would be nice to be able to either have a Circle geo-type, or similar to shapely have a point that can have a defined boundary of a given radius which can be intersected and used for Contains trait. I'm not sure if this is implemented, or a proper way of doing this exists. If not I can see if I can create a PR if anyone would offer a little guidance on getting started.

For anyone else with this same issue my current workaround is to create a polygon which represents the circle. I do this by plotting points around the circumference radius length from the center like so(code isn't tested):

use std::f64::consts::PI;

fn create_circle(center: Coordinate<f64>, radius: f64) -> Polygon<f64> {
    let (cx, cy) = center.x_y();
    let circum = 2.0 * PI * radius;
    // this controls how many points to create by dividing circum by 10 units of measurement
    let n = (circum / 10.0).ceil();
    let mut points = Vec::<(f64, f64)>::new();
    for _x in 0..n as usize + 1 {
        let x = _x as f64;
        
        points.push( (((2.0 * PI / n * x).cos() * radius) + cx, ((2.0 * PI / n *x).sin() * radius) + cy) )
    }

    Polygon::new(LineString::from(points), vec![])
}
@tsturzl tsturzl changed the title Intersecting a point by a given radius Point boundaries Jan 18, 2020
@urschrei
Copy link
Member

The issue for us is that we don't yet have a way of buffering geometries (which is what creates the boundary, in the case of a circle). It's a fairly complex algorithm and implementation (do we include different end cap styles in the public API etc). I know that https://github.com/lelongg/geo-offset provides some (or all? I haven't had a chance to look at it properly) of the functionality using the Martinez-Rueda algorithm, and uses geo-types for primitives, so it may be useful to you…

@urschrei
Copy link
Member

(I should also note thatgeo-offset makes use of geo-clipper for its boolean operations, which in turn requires the use of Clipper, which may or may not be a deal-breaker for you)

@tsturzl
Copy link
Author

tsturzl commented Jan 20, 2020

I appreciate the quick response. I had no idea the complexity was so high on this. My work around is working. I'm just making "circles" from Polygons. I thought with a lot of circles this wouldn't scale well, but I'm happy to report that's not the case.

@schoenenberg
Copy link

Let me share my implementation for creating a circle with a radius in meter:

pub fn generate_geo_circle(location: &geo::Point<f64>, radius: f64) -> geo::Polygon<f64> {
    // generate a point in distance in every 10 degree bearing
    let points: Vec<geo::Point<f64>> = (0..=36)
        .map(|i| location.haversine_destination(i as f64 * 10_f64, radius))
        .collect();

    geo::Polygon::new(geo::LineString::from(points), Vec::new())
}

@frewsxcv
Copy link
Member

See also #935

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

4 participants