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

Improve performance of the visibility sweep #4642

Commits on Jan 16, 2024

  1. Configuration menu
    Copy the full SHA
    b228249 View commit details
    Browse the repository at this point in the history
  2. Avoid JTS Geometry in vision sweep

    The sweep is now based on `LineSegment` instead of `LineString` as it is a bit easer to work with and avoids some of the
    cost associated with `Geometry`.
    
    The intersection check for whether to include a blocking segments is now against the vision bounding box rather than the
    precise vision geometry. There is a tradeoff here as more segments can be excluded the more precise we are, but in
    practice the extra precision does not gain us nearly as much as it costs.
    
    `VisibilityProblem` is now responsible for collecting and organizing segments. `VisionBlockingAccumulator` only decides
    how to treat each topology type, but otherwise forwards to `VisibilityProblem`. This avoids some expense around building
    large lists of segments.
    kwvanderlinde committed Jan 16, 2024
    Configuration menu
    Copy the full SHA
    cb75dd0 View commit details
    Browse the repository at this point in the history
  3. Better visibility graph representation

    A new `EndpointSet` class is responsible for maintaining the endpoints and walls for the visibility sweep. It avoids any
    use of endpoint hashing in favour of retroactively merging the few duplicated endpoints we
    receive. `VisibilitySweepEndpoint` now references other `VisibilitySweepEndpoint` to define walls instead of using
    `LineSegment`, which saves on some redundancy and make it really easy to validate the graph.
    kwvanderlinde committed Jan 16, 2024
    Configuration menu
    Copy the full SHA
    35d2638 View commit details
    Browse the repository at this point in the history
  4. Avoid unnecssary intersection calculations in visibility sweep

    This change moves much closer to Asano's original algorithm as described in section 3.2 of "Efficient Computation of
    Visibility Polygons" ([arXiv:1403.3905](https://arxiv.org/abs/1403.3905)). The critical difference is in how we find the
    nearest wall, in particular:
    1. Keeping the open walls ordered by distance to the origin, so that the nearest one is always at the front.
    2. Using a cheaper orientation-based comparator for the open walls that does not depend on any finding any
       intersections.
    
    Since we don't have to intersect walls in order to find the nearest one, we can now limit ourselves to a single nearest
    wall check per iteration, as opposed to the two that used to be used. Intersections are only calculated when we need to
    add a point to the result that does not lie on one of the input endpoints.
    kwvanderlinde committed Jan 16, 2024
    Configuration menu
    Copy the full SHA
    8e49d15 View commit details
    Browse the repository at this point in the history
  5. Avoid adding open walls that are occluded by the nearest wall

    There are plenty of cases where a wall is completely hidden behind other open walls and therefore cannot contribute to
    the result. Instead of marking these as open, we can skip them completely and avoid a lot of expense during the sweep.
    
    In order to keep the check cheap, walls are only checked against the nearest wall, not against all open walls that might
    hide them.
    kwvanderlinde committed Jan 16, 2024
    Configuration menu
    Copy the full SHA
    cb407a5 View commit details
    Browse the repository at this point in the history
  6. General clean up and improved robustness

    A lot of things have been documented, names improved, and `VisibilityProblem` has been rearraanged to keep the core
    public stuff first. There are also fewer assumptions and `assert` checks made in several places, instead opting for
    being able to handle a wider variety of situations. If the sweep ever fails, an exception is thrown rather than
    returning a null (no blocking) result - `FogUtil` handles this and simply does not expose any area in this case while
    logging the error.
    kwvanderlinde committed Jan 16, 2024
    Configuration menu
    Copy the full SHA
    44045ab View commit details
    Browse the repository at this point in the history
  7. Improve endpoint sorting performance

    The new comparator is based on point orientation around the origin rather than directly depending on angle. This is much
    cheaper, and means we don't have to cache calculations on `VisibilitySweepEndpoint` thus making it simpler.
    
    `EndpointSet` also buckets endpoints according to which eighth of the plane the point is in. Sorting can be done on one
    bucket at a time which reduces the number of comparisons needed. The buckets also remove the need for some special cases
    in the comparator, further streamlining the sort.
    kwvanderlinde committed Jan 16, 2024
    Configuration menu
    Copy the full SHA
    c60e5b3 View commit details
    Browse the repository at this point in the history