mirror of
https://github.com/PX4/PX4-Autopilot.git
synced 2026-05-22 06:14:14 +08:00
perf: optimise segmentsIntersects with more early returns
most cases will be two completely disjoint lines. these early returns allow us to catch most of these cases at the start of the function, half of them without even evaluating half the orient2d's. as we are targeting embedded systems I think this should translate to saved time (no branch prediction footguns). to be verified.
This commit is contained in:
@@ -106,11 +106,23 @@ enum class SegSegResult {
|
||||
inline SegSegResult segmentsIntersect(int32_t ax, int32_t ay, int32_t bx, int32_t by,
|
||||
int32_t cx, int32_t cy, int32_t dx, int32_t dy)
|
||||
{
|
||||
// These two early returns are logically not necessary (would catch the
|
||||
// case in the end) but improve performance, as most segment pairs are
|
||||
// expected to be completely disjoint. If both c and d are strictly on
|
||||
// the same side of a-b (first check, second vice versa) we can already
|
||||
// conclude the segments are disjoint. This does not detect _all_
|
||||
// disjoint cases so the final return stays.
|
||||
|
||||
const int o1 = orient2d(ax, ay, bx, by, cx, cy);
|
||||
const int o2 = orient2d(ax, ay, bx, by, dx, dy);
|
||||
|
||||
if (o1 != 0 && o1 == o2) { return SegSegResult::Disjoint; }
|
||||
|
||||
const int o3 = orient2d(cx, cy, dx, dy, ax, ay);
|
||||
const int o4 = orient2d(cx, cy, dx, dy, bx, by);
|
||||
|
||||
if (o3 != 0 && o3 == o4) { return SegSegResult::Disjoint; }
|
||||
|
||||
if (o1 && o2 && o3 && o4 && o1 != o2 && o3 != o4) { return SegSegResult::Cross; }
|
||||
|
||||
if (!o1 && !o2 && !o3 && !o4) { return SegSegResult::Collinear; }
|
||||
|
||||
Reference in New Issue
Block a user