Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

cedeber
Copy link

@cedeber cedeber commented Oct 11, 2022

Thank you for helping out with embedded-graphics development! Please:

  • Check that you've added passing tests and documentation
  • Add a CHANGELOG.md entry in the Unreleased section under the appropriate heading (Added, Fixed, etc) if your changes affect the public API
  • Run rustfmt on the project
  • Run just build (Linux/macOS only) and make sure it passes. If you use Windows, check that CI passes once you've opened the PR.

PR description

Fix #405 Bounding boxes for Arc and Sector don't take the angles into account.

@cedeber cedeber marked this pull request as draft October 11, 2022 20:09
@cedeber cedeber changed the title [WIP] Bounding boxes for Arc and Sector Bounding boxes for Arc and Sector Oct 11, 2022
@cedeber
Copy link
Author

cedeber commented Oct 14, 2022

@jamwaffles I think I've got something for the Arc bounding box. I also try to copy / migrate what you did in #441 and #524.
Can you have a look if it's ok for you like this so that I can add some tests and continue for the styled version. And same for the Sector.

@jamwaffles jamwaffles requested a review from rfuest October 16, 2022 15:55
Copy link
Member

@jamwaffles jamwaffles left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm by no means an expert on the arc/sector code, nor the algorithms behind it, so I've asked @rfuest to give it a check over. Superficially, to me it looks quite clean but my gut tells me there are some optimisations to be made somewhere.

It also looks like there are some regressions in the tests - please check the CI output or cargo test locally if you can't get into CircleCI.

Comment on lines 126 to 127
let center = self.center();
let radius = self.radius();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To get accurate results you'll need to use Circle::center_2x instead of center and scale all coordinates by 2. center does round the center point to the nearest integer, which isn't accurate for circles/arcs with even diameters. The radius in the scaled up coordinate system is then equal to diameter.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like dividing the returned Point by 2 will have the same effect, isn't it?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Which Point do you mean? The result of point_from_angle?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. I feel I could avoid to work with the radius on the bounding_box function and simply reuse top_left + diameter, etc.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm still not sure I understand what you mean. But you could get rid of using Real for the radius function by scaling the coordinate system up by a factor of 2.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not easy sweat_smile

No it's not, the half pixel offset that creeps into many calculations can get really confusing.

The BB isn't correct for some negative start angles:
grafik

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Negative sweep angles are also broken:
grafik

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, completely forgot to test the negatives angles 😅
But I've seen that I forgot to normalize the angles during the refactoring, which is probably why it's broken. (hopefully)

Copy link
Author

@cedeber cedeber Oct 19, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I fixed it by using the PlaneSector that @jamwaffles introduced on the other PR. Although it's not always pixel perfect.

With the debug tools, the stroke size pushes the bounding box in a weird way. Shouldn't it stay the same, disregarding the stroke width?
Capture d’écran 2022-10-19 à 22 03 40

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I fixed it by using the PlaneSector that @jamwaffles introduced on the other PR. Although it's not always pixel perfect.

Getting a pixel perfect result will be hard to achieve. If it isn't possible to implement this in a reasonable way we should at least try to make sure that the bounding box will never be smaller than the content. IMO an additional row or column of empty pixels inside the BB is less of an issue than pixels outside the BB, which would get clipped or overlap other drawn elements.

With the debug tools, the stroke size pushes the bounding box in a weird way. Shouldn't it stay the same, disregarding the stroke width?

There are two different bounding boxes: Arc::bounding_box and Styled<Arc, PrimitveStyle<C>>::bounding_box. The unstyled BB is constant, but the styled bounding box must include the stroke width and stroke alignment.

@rfuest
Copy link
Member

rfuest commented Oct 16, 2022

I only did take a quick look at the code, but the general concept looks good. If you haven't already noticed it I would also like to point you to the debug-tools repo which has tools to test the bounding box of Arc and Sector: https://github.com/embedded-graphics/debug-tools/blob/master/debug-tools/examples/arc.rs

@cedeber
Copy link
Author

cedeber commented Oct 17, 2022

It also looks like there are some regressions in the tests - please check the CI output or cargo test locally if you can't get into CircleCI.

It's because of the bounding box usage for the dimension test for instance. I fixed them by simply using the circle conversion and add other tests for the bounding box.
I still need to do the code for the styling bounding box.

@cedeber
Copy link
Author

cedeber commented Nov 16, 2022

I have the feeling that the stroke for Sector is wrong at the center. It looks twice as large as what I think it should be.
In the screenshot bellow the stroke from the center is 30px, not 15px. Isn't it wrong? (At least for an angle (sweep) lower than 90deg)
Capture d’écran 2022-11-16 à 17 51 15

@rfuest
Copy link
Member

rfuest commented Nov 16, 2022

I think it is correct, or at least the way it was designed to work. The two line segments should be drawn the same way as a Polyline with the two arc endpoints and the center point of the arc. You could verify that it behaves correctly by drawing a Polyline, but keep in mind that stroke alingment isn't supported for polylines.

@rfuest
Copy link
Member

rfuest commented Nov 16, 2022

But something definitely isn't right with some edge cases. I'll add some of my findings to #484.

@cedeber
Copy link
Author

cedeber commented Nov 16, 2022

I quickly checked how Sketch or Affinity Designer behave with polygones and large strokes. Well, it's bad too with narrow angles :-/ Definitely not an easy topic.

Now I am wondering if it wouldn't be better to offer only rounded corners instead, because it has the advantage to be consistant with every angle values. (For Sector and polygones at least)

Not sure it's easier to implement though ^_^

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

Successfully merging this pull request may close these issues.

Bounding boxes for Arc and Sector don't take the angles into account
3 participants