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

MultiPolygon::rotate should use centroid as pivot #412

Closed
anlumo opened this issue Jan 9, 2020 · 10 comments
Closed

MultiPolygon::rotate should use centroid as pivot #412

anlumo opened this issue Jan 9, 2020 · 10 comments

Comments

@anlumo
Copy link

anlumo commented Jan 9, 2020

Right now, MultiPolygon::rotate rotates all its polygons individually. However, I'd expect it to rotate them around its own centroid. Otherwise, I'd just iterate over the inner polygons and rotate them myself.

Obviously, this would be a breaking change, so it'd probably be better to add a separate function for this. Ideally, it'd be nice to have a variant where you just pass the pivot explicitly.

@urschrei
Copy link
Member

urschrei commented Jan 9, 2020

I could have sworn we used the same logic as Shapely when we implemented this. Hmm.

it'd be nice to have a variant where you just pass the pivot explicitly.

Does https://docs.rs/geo/0.12.2/geo/algorithm/rotate/trait.RotatePoint.html work for you?

@anlumo
Copy link
Author

anlumo commented Jan 9, 2020

Yes, that one does exactly what I need, thank you! So, disregard the second paragraph.

The point about rotate arguably not behaving as you'd expect still stands, though.

@andrei-papou
Copy link

Is something like this sufficient?

pub trait RotateCentroid<T>: RotatePoint<T> + Centroid {
    fn rotate_around_centroid(&self, angle: T) -> <Self as Centroid>::Output
    where
        T: Float,
        <Self as Centroid>::Output: Float,
    {
        self.rotate_around_point(angle, self.centroid())
    }
}

Seems like it gives the ability to rotate the multipolygon around the centroid.

@frewsxcv
Copy link
Member

@andrei-papou that looks good to me!

a couple relevant links: #151 #287

martinfrances107 added a commit to martinfrances107/geo that referenced this issue Dec 8, 2020
@martinfrances107
Copy link
Contributor

The code fragment form above does not compile

#412 (comment)

<Self as Centroid>::Output: Float,

Float is a 1-D scalar type, the value is needed is a 2D type like Point .. but that also errors out a as Trait is needed struct type given.

the solution is listed below .. I have bundled this up with a test and I am about to post a PR.

pub trait RotateCentroid<T: CoordinateType>: RotatePoint<T> + Centroid<Output = Point<T>> {
    fn rotate_around_centroid(&self, angle: T) -> Self
    where
        T: Float,
        Self: Sized,
    {
        self.rotate_around_point(angle, self.centroid())
    }
}

@michaelkirk
Copy link
Member

michaelkirk commented Dec 8, 2020

I know I'm late to be giving design input - sorry.

Obviously, this would be a breaking change, so it'd probably be better to add a separate function for this. Ideally, it'd be nice to have a variant where you just pass the pivot explicitly.

I appreciate the sensitivity towards "breaking" the existing API, but I actually believe the current behavior is a bug, and we should fix it rather than introduce another trait.

At least one person was surprised by the existing behavior, and more will be in the future.

Having a profusion of options makes things harder for people. Why do I want to think about rotate vs rotate_centroid?

And probably more importantly from my perspective - it seems like other libraries do it this way (rotate everything in the collection around the collections centroid). I think there is a lot of value in being familiar to people coming from other environments.

If there is anyone who thinks the existing behavior is correct and worth keeping, I'm open to more discussion, but otherwise I'd say change the existing implementation rather than add a new trait.

@michaelkirk
Copy link
Member

🦗

Unless I hear something to the contrary soon - I'm going to assume people are ok with "fixing" the legacy API to behave like other libs rather than keeping our idiosyncratic version and adding some secondary conventional API.

@urschrei
Copy link
Member

Happy for the "fix" to merge for compat / "in line with user expectations" reasons!

mapoulos added a commit to mapoulos/geo that referenced this issue Jul 13, 2021
@mapoulos
Copy link
Contributor

I'm putting together a PR with a test or two "fixing" of the legacy API.

michaelkirk pushed a commit that referenced this issue Jul 19, 2021
…olygon individually.

PR:  #651 

squash of:

* rotate a multipolygon around its centroid, instead of rotating each polygon individually. #412

* todo: add test

* adding a test

* change entry w/ PR link

* cleanup

* more cleanup

* suggestion from PR

* adding comment

* adding comment

* error test

* whitespace cleanup
@michaelkirk
Copy link
Member

Fixed in b0a6752

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

No branches or pull requests

7 participants