letsfindaway / OpenBoard

I'm using this fork to contribute features and fixes to the upstream project. In order to create good pull requests, I'm rebasing my feature branches, squashing and reordering commits, etc. If you fork this repository be aware that my development branches may rewrite history without prior notice.
http://openboard.ch/
GNU General Public License v3.0
9 stars 0 forks source link

Eraser sometimes does not work when completely inside a polygon #153

Closed letsfindaway closed 8 months ago

letsfindaway commented 10 months ago

Draw a broad line with the marker. Then switch to the smallest eraser and place the eraser circle completely inside the marker line. Just press and release the left mouse button without moving the mouse. In this case sometimes the eraser circle is punched out of the marker line, sometimes it is not.

This is not a big problem. As soon as you move the mouse, the eraser works after a short distance. It also always works when the eraser circle is not completely inside the marker line. But I wanted to find out what the reason is.

To investigate, I checked the situation using the gammaray tool. Here a screenshot of the situation: grafik

This is a marker line, which is rendered as two polygons. One on the left side covering most of the stroke, and a second one for the continuation to the right. I have punched a hole using the eraser in the first polygon. You see that the resulting polygon now consists of the outline of the marker polygon, then jumps to the eraser circle, goes round and jumps back to the outside.

The eraser hole is however still filled and not white. Why?

The polygon uses the fill rule "Winding fill". I found out that if I switch to "OIddEven", then the hole is punched out. But this has other drawbacks, so I further analyzed why the two fill rules give different results.

The reason is the orientation of the outlines. The outline polygons are created by UBGeometryUtils::lineToPolygon. This function creates a outline walking clockwise around the shape. In this situation, both the marker outline and the eraser outline are traversed clockwise. If you read how the Winding Fill rule works, it is obvious that the eraser hole is still considered "inside". From the Qt documentation:

Specifies that the region is filled using the non zero winding rule. With this rule, we determine whether a point is inside the shape by using the following method. Draw a horizontal line from the point to a location outside the shape. Determine whether the direction of the line at each intersection point is up or down. The winding number is determined by summing the direction of each intersection. If the number is non zero, the point is inside the shape. This fill mode can also in most cases be considered as the intersection of closed shapes.

Here the line at both intersections points in the same direction.

The solution is to reverse the eraser path before subtracting it from the marker path.