Function trySegmentIntersectionPoint

Constructs the unique intersection point of two closed segments.

bool trySegmentIntersectionPoint(T, R)(
  Segment2!T first,
  Segment2!T second,
  out Point2!R point
) pure nothrow @nogc @safe
if (isIntersectionScalar!T && is(R == IntersectionScalar!T));

Returns true exactly when:

segmentIntersectionKind(first, second) == SegmentIntersectionKind.point

Supported input scalar types:

int long float double

The constructed point uses IntersectionScalar!T, which is currently double for every supported input scalar.

Topology and construction deliberately remain separate:

- segmentIntersectionKind() determines the exact topology; - endpoint contacts reuse the known input endpoint; - proper interior/interior crossings are constructed from exact dyadic determinant weights and correctly rounded to binary64.

For floating-point coordinates all endpoints must be finite.

Returns false for:

- disjoint segments; - positive-length overlaps.

Because point is an out parameter, false leaves it at Point2!R.init.

The returned rounded point is construction data. It must not be fed back into exact predicates as evidence of the already established topology.

No allocation is performed.

Complexity

time O(1) space O(1)

Example

Example using the public package API.

import geo;

alias P = Point2!int;
alias S = Segment2!int;

const first =
    S(
        P(0, 0),
        P(10, 10)
    );

const second =
    S(
        P(0, 10),
        P(10, 0)
    );

assert(
    segmentIntersectionKind(
        first,
        second
    ) == SegmentIntersectionKind.point
);

Point2!double point;

assert(
    trySegmentIntersectionPoint(
        first,
        second,
        point
    )
);

assert(
    point ==
    Point2!double(
        5.0,
        5.0
    )
);