Source code for orient.planar

from typing import Optional as _Optional

from ground.base import (Context as _Context,
                         Location as _Location,
                         Relation as _Relation,
                         get_context as _get_context)
from ground.hints import (Contour as _Contour,
                          Multipolygon as _Multipolygon,
                          Multisegment as _Multisegment,
                          Point as _Point,
                          Polygon as _Polygon,
                          Segment as _Segment)

from .core import (contour as _contour,
                   multipolygon as _multipolygon,
                   multiregion as _multiregion,
                   multisegment as _multisegment,
                   polygon as _polygon,
                   region as _region,
                   segment as _segment)
from .hints import (Multiregion as _Multiregion,
                    Region as _Region)


[docs]def point_in_segment(point: _Point, segment: _Segment, *, context: _Optional[_Context] = None) -> _Location: """ Finds location of point in segment. Time complexity: ``O(1)`` Memory complexity: ``O(1)`` :param point: point to check for. :param segment: segment to check in. :param context: geometric context. :returns: location of point in segment. >>> from ground.base import Location, get_context >>> context = get_context() >>> Point = context.point_cls >>> Segment = context.segment_cls >>> segment = Segment(Point(0, 0), Point(2, 0)) >>> point_in_segment(Point(0, 0), segment) is Location.BOUNDARY True >>> point_in_segment(Point(1, 0), segment) is Location.BOUNDARY True >>> point_in_segment(Point(2, 0), segment) is Location.BOUNDARY True >>> point_in_segment(Point(3, 0), segment) is Location.EXTERIOR True >>> point_in_segment(Point(0, 1), segment) is Location.EXTERIOR True """ return _segment.locate_point( segment, point, _get_context() if context is None else context )
[docs]def segment_in_segment(left: _Segment, right: _Segment, *, context: _Optional[_Context] = None) -> _Relation: """ Finds relation between segments. Time complexity: ``O(1)`` Memory complexity: ``O(1)`` :param left: segment to check for. :param right: segment to check in. :param context: geometric context. :returns: relation between segments. >>> from ground.base import Relation, get_context >>> context = get_context() >>> Point = context.point_cls >>> Segment = context.segment_cls >>> segment = Segment(Point(0, 0), Point(2, 0)) >>> (segment_in_segment(Segment(Point(0, 0), Point(0, 2)), segment) ... is Relation.TOUCH) True >>> (segment_in_segment(Segment(Point(0, 0), Point(1, 0)), segment) ... is Relation.COMPONENT) True >>> (segment_in_segment(Segment(Point(0, 0), Point(2, 0)), segment) ... is Relation.EQUAL) True >>> (segment_in_segment(Segment(Point(0, 0), Point(3, 0)), segment) ... is Relation.COMPOSITE) True >>> (segment_in_segment(Segment(Point(1, 0), Point(3, 0)), segment) ... is Relation.OVERLAP) True >>> (segment_in_segment(Segment(Point(2, 0), Point(3, 0)), segment) ... is Relation.TOUCH) True >>> (segment_in_segment(Segment(Point(3, 0), Point(4, 0)), segment) ... is Relation.DISJOINT) True """ return _segment.relate_segment( right, left, _get_context() if context is None else context )
[docs]def point_in_multisegment(point: _Point, multisegment: _Multisegment, *, context: _Optional[_Context] = None) -> _Location: """ Finds location of point in multisegment. Time complexity: ``O(len(multisegment.segments))`` Memory complexity: ``O(1)`` :param point: point to check for. :param multisegment: multisegment to check in. :param context: geometric context. :returns: location of point in multisegment. >>> from ground.base import Location, get_context >>> context = get_context() >>> Multisegment = context.multisegment_cls >>> Point = context.point_cls >>> Segment = context.segment_cls >>> multisegment = Multisegment([Segment(Point(0, 0), Point(1, 0)), ... Segment(Point(3, 0), Point(5, 0))]) >>> point_in_multisegment(Point(0, 0), multisegment) is Location.BOUNDARY True >>> point_in_multisegment(Point(0, 1), multisegment) is Location.EXTERIOR True >>> point_in_multisegment(Point(1, 0), multisegment) is Location.BOUNDARY True >>> point_in_multisegment(Point(2, 0), multisegment) is Location.EXTERIOR True >>> point_in_multisegment(Point(3, 0), multisegment) is Location.BOUNDARY True >>> point_in_multisegment(Point(4, 0), multisegment) is Location.BOUNDARY True """ return _multisegment.locate_point( multisegment, point, _get_context() if context is None else context )
[docs]def segment_in_multisegment(segment: _Segment, multisegment: _Multisegment, *, context: _Optional[_Context] = None) -> _Relation: """ Finds relation between segment and multisegment. Time complexity: ``O(segments_count)`` Memory complexity: ``O(segments_count)`` where ``segments_count = len(multisegment.segments)``. :param segment: segment to check for. :param multisegment: multisegment to check in. :param context: geometric context. :returns: relation between segment and multisegment. >>> from ground.base import Relation, get_context >>> context = get_context() >>> Multisegment = context.multisegment_cls >>> Point = context.point_cls >>> Segment = context.segment_cls >>> multisegment = Multisegment([Segment(Point(0, 0), Point(1, 1)), ... Segment(Point(1, 1), Point(3, 3))]) >>> segment_in_multisegment(Segment(Point(0, 0), Point(1, 0)), ... multisegment) is Relation.TOUCH True >>> segment_in_multisegment(Segment(Point(0, 0), Point(0, 1)), ... multisegment) is Relation.TOUCH True >>> segment_in_multisegment(Segment(Point(0, 1), Point(1, 0)), ... multisegment) is Relation.CROSS True >>> segment_in_multisegment(Segment(Point(0, 0), Point(1, 1)), ... multisegment) is Relation.COMPONENT True >>> segment_in_multisegment(Segment(Point(0, 0), Point(3, 3)), ... multisegment) is Relation.EQUAL True >>> segment_in_multisegment(Segment(Point(2, 2), Point(4, 4)), ... multisegment) is Relation.OVERLAP True >>> segment_in_multisegment(Segment(Point(4, 4), Point(5, 5)), ... multisegment) is Relation.DISJOINT True """ return _multisegment.relate_segment( multisegment, segment, _get_context() if context is None else context )
[docs]def multisegment_in_multisegment(left: _Multisegment, right: _Multisegment, *, context: _Optional[_Context] = None ) -> _Relation: """ Finds relation between multisegments. Time complexity: ``O(segments_count * log segments_count)`` Memory complexity: ``O(segments_count)`` where ``segments_count = len(left.segments) + len(right.segments)``. :param left: multisegment to check for. :param right: multisegment to check in. :param context: geometric context. :returns: relation between multisegments. >>> from ground.base import Relation, get_context >>> context = get_context() >>> Multisegment = context.multisegment_cls >>> Point = context.point_cls >>> Segment = context.segment_cls >>> square_edges = [Segment(Point(0, 0), Point(4, 0)), ... Segment(Point(0, 0), Point(0, 4)), ... Segment(Point(4, 0), Point(4, 4)), ... Segment(Point(0, 4), Point(4, 4))] >>> inner_square_edges = [Segment(Point(1, 1), Point(3, 1)), ... Segment(Point(1, 3), Point(1, 1)), ... Segment(Point(3, 1), Point(3, 3)), ... Segment(Point(1, 3), Point(3, 3))] >>> square_diagonals = [Segment(Point(0, 0), Point(2, 2)), ... Segment(Point(2, 2), Point(4, 0)), ... Segment(Point(2, 2), Point(4, 4)), ... Segment(Point(0, 4), Point(2, 2))] >>> (multisegment_in_multisegment(Multisegment(inner_square_edges), ... Multisegment(square_edges)) ... is Relation.DISJOINT) True >>> (multisegment_in_multisegment(Multisegment(square_diagonals), ... Multisegment(square_edges)) ... is Relation.TOUCH) True >>> (multisegment_in_multisegment(Multisegment(square_diagonals), ... Multisegment(inner_square_edges)) ... is Relation.CROSS) True >>> (multisegment_in_multisegment(Multisegment(inner_square_edges ... + [square_edges[0]]), ... Multisegment(square_edges)) ... is Relation.OVERLAP) True >>> (multisegment_in_multisegment(Multisegment(square_edges ... + inner_square_edges), ... Multisegment(square_edges)) ... is Relation.COMPOSITE) True >>> (multisegment_in_multisegment(Multisegment(square_edges), ... Multisegment(square_edges)) ... is Relation.EQUAL) True >>> (multisegment_in_multisegment(Multisegment(square_edges), ... Multisegment(square_edges ... + inner_square_edges)) ... is Relation.COMPONENT) True """ return _multisegment.relate_multisegment( right, left, _get_context() if context is None else context )
[docs]def point_in_contour(point: _Point, contour: _Contour, *, context: _Optional[_Context] = None) -> _Location: """ Finds location of point in contour. Time complexity: ``O(len(contour.vertices))`` Memory complexity: ``O(1)`` :param point: point to check for. :param contour: contour to check in. :param context: geometric context. :returns: location of point in contour. >>> from ground.base import Location, get_context >>> context = get_context() >>> Contour = context.contour_cls >>> Point = context.point_cls >>> square = Contour([Point(0, 0), Point(2, 0), Point(2, 2), Point(0, 2)]) >>> point_in_contour(Point(0, 0), square) is Location.BOUNDARY True >>> point_in_contour(Point(1, 1), square) is Location.EXTERIOR True >>> point_in_contour(Point(2, 2), square) is Location.BOUNDARY True >>> point_in_contour(Point(3, 3), square) is Location.EXTERIOR True """ return _contour.locate_point( contour, point, _get_context() if context is None else context )
[docs]def segment_in_contour(segment: _Segment, contour: _Contour, *, context: _Optional[_Context] = None) -> _Relation: """ Finds relation between segment and contour. Time complexity: ``O(len(contour.vertices))`` Memory complexity: ``O(1)`` :param segment: segment to check for. :param contour: contour to check in. :param context: geometric context. :returns: relation between segment and contour. >>> from ground.base import Relation, get_context >>> context = get_context() >>> Contour = context.contour_cls >>> Point = context.point_cls >>> Segment = context.segment_cls >>> square = Contour([Point(0, 0), Point(3, 0), Point(3, 3), Point(0, 3)]) >>> (segment_in_contour(Segment(Point(0, 0), Point(1, 0)), square) ... is Relation.COMPONENT) True >>> (segment_in_contour(Segment(Point(0, 0), Point(3, 0)), square) ... is Relation.COMPONENT) True >>> (segment_in_contour(Segment(Point(2, 0), Point(4, 0)), square) ... is Relation.OVERLAP) True >>> (segment_in_contour(Segment(Point(4, 0), Point(5, 0)), square) ... is Relation.DISJOINT) True >>> (segment_in_contour(Segment(Point(1, 0), Point(1, 2)), square) ... is Relation.TOUCH) True >>> (segment_in_contour(Segment(Point(0, 0), Point(1, 1)), square) ... is Relation.TOUCH) True >>> (segment_in_contour(Segment(Point(1, 1), Point(2, 2)), square) ... is Relation.DISJOINT) True >>> (segment_in_contour(Segment(Point(2, 2), Point(4, 4)), square) ... is Relation.CROSS) True """ return _contour.relate_segment( contour, segment, _get_context() if context is None else context )
[docs]def multisegment_in_contour(multisegment: _Multisegment, contour: _Contour, *, context: _Optional[_Context] = None) -> _Relation: """ Finds relation between multisegment and contour. Time complexity: ``O(segments_count * log segments_count)`` Memory complexity: ``O(segments_count)`` where ``segments_count = len(left.vertices) + len(right.vertices)``. :param multisegment: multisegment to check for. :param contour: contour to check in. :param context: geometric context. :returns: relation between multisegment and contour. >>> from ground.base import Relation, get_context >>> context = get_context() >>> Contour = context.contour_cls >>> Multisegment = context.multisegment_cls >>> Point = context.point_cls >>> Segment = context.segment_cls >>> square = Contour([Point(0, 0), Point(4, 0), Point(4, 4), Point(0, 4)]) >>> inner_square = Contour([Point(1, 1), Point(3, 1), Point(3, 3), ... Point(1, 3)]) >>> square_edges = [Segment(Point(0, 0), Point(4, 0)), ... Segment(Point(0, 0), Point(0, 4)), ... Segment(Point(4, 0), Point(4, 4)), ... Segment(Point(0, 4), Point(4, 4))] >>> inner_square_edges = [Segment(Point(1, 1), Point(3, 1)), ... Segment(Point(1, 3), Point(1, 1)), ... Segment(Point(3, 1), Point(3, 3)), ... Segment(Point(1, 3), Point(3, 3))] >>> square_diagonals = [Segment(Point(0, 0), Point(2, 2)), ... Segment(Point(2, 2), Point(4, 0)), ... Segment(Point(2, 2), Point(4, 4)), ... Segment(Point(0, 4), Point(2, 2))] >>> (multisegment_in_contour(Multisegment(inner_square_edges), square) ... is Relation.DISJOINT) True >>> (multisegment_in_contour(Multisegment(square_diagonals), square) ... is Relation.TOUCH) True >>> (multisegment_in_contour(Multisegment(square_diagonals), inner_square) ... is Relation.CROSS) True >>> (multisegment_in_contour( ... Multisegment(square_diagonals + [square_edges[0]]), square) ... is Relation.OVERLAP) True >>> (multisegment_in_contour(Multisegment(square_diagonals + square_edges), ... square) ... is Relation.COMPOSITE) True >>> (multisegment_in_contour(Multisegment(square_edges), square) ... is Relation.EQUAL) True >>> (multisegment_in_contour(Multisegment(square_edges[1:]), square) ... is Relation.COMPONENT) True """ return _contour.relate_multisegment( contour, multisegment, _get_context() if context is None else context )
[docs]def contour_in_contour(left: _Contour, right: _Contour, *, context: _Optional[_Context] = None) -> _Relation: """ Finds relation between contours. Time complexity: ``O(vertices_count * log vertices_count)`` Memory complexity: ``O(vertices_count)`` where ``vertices_count = len(left.vertices) + len(right.vertices)``. :param left: contour to check for. :param right: contour to check in. :param context: geometric context. :returns: relation between contours. >>> from ground.base import Relation, get_context >>> context = get_context() >>> Contour = context.contour_cls >>> Point = context.point_cls >>> triangle = Contour([Point(0, 0), Point(1, 0), Point(0, 1)]) >>> square = Contour([Point(0, 0), Point(1, 0), Point(1, 1), Point(0, 1)]) >>> contour_in_contour(triangle, triangle) is Relation.EQUAL True >>> contour_in_contour(triangle, square) is Relation.OVERLAP True >>> contour_in_contour(square, triangle) is Relation.OVERLAP True >>> contour_in_contour(square, square) is Relation.EQUAL True """ return _contour.relate_contour( right, left, _get_context() if context is None else context )
[docs]def point_in_region(point: _Point, region: _Region, *, context: _Optional[_Context] = None) -> _Location: """ Finds location of point in region. Based on ray casting algorithm. Time complexity: ``O(len(region.vertices))`` Memory complexity: ``O(1)`` Reference: https://en.wikipedia.org/wiki/Point_in_polygon#Ray_casting_algorithm :param point: point to check for. :param region: region to check in. :param context: geometric context. :returns: location of point in region. >>> from ground.base import Location, get_context >>> context = get_context() >>> Contour = context.contour_cls >>> Point = context.point_cls >>> square = Contour([Point(0, 0), Point(2, 0), Point(2, 2), Point(0, 2)]) >>> point_in_region(Point(0, 0), square) is Location.BOUNDARY True >>> point_in_region(Point(1, 1), square) is Location.INTERIOR True >>> point_in_region(Point(2, 2), square) is Location.BOUNDARY True >>> point_in_region(Point(3, 3), square) is Location.EXTERIOR True """ return _region.locate_point(region, point, _get_context() if context is None else context)
[docs]def segment_in_region(segment: _Segment, region: _Region, *, context: _Optional[_Context] = None) -> _Relation: """ Finds relation between segment and region. Time complexity: ``O(len(region.vertices))`` Memory complexity: ``O(1)`` :param segment: segment to check for. :param region: region to check in. :param context: geometric context. :returns: relation between segment and region. >>> from ground.base import Relation, get_context >>> context = get_context() >>> Contour = context.contour_cls >>> Point = context.point_cls >>> Segment = context.segment_cls >>> square = Contour([Point(0, 0), Point(3, 0), Point(3, 3), Point(0, 3)]) >>> (segment_in_region(Segment(Point(0, 0), Point(1, 0)), square) ... is Relation.COMPONENT) True >>> (segment_in_region(Segment(Point(0, 0), Point(3, 0)), square) ... is Relation.COMPONENT) True >>> (segment_in_region(Segment(Point(2, 0), Point(4, 0)), square) ... is Relation.TOUCH) True >>> (segment_in_region(Segment(Point(4, 0), Point(5, 0)), square) ... is Relation.DISJOINT) True >>> (segment_in_region(Segment(Point(1, 0), Point(1, 2)), square) ... is Relation.ENCLOSED) True >>> (segment_in_region(Segment(Point(0, 0), Point(1, 1)), square) ... is Relation.ENCLOSED) True >>> (segment_in_region(Segment(Point(1, 1), Point(2, 2)), square) ... is Relation.WITHIN) True >>> (segment_in_region(Segment(Point(2, 2), Point(4, 4)), square) ... is Relation.CROSS) True """ return _region.relate_segment( region, segment, _get_context() if context is None else context )
[docs]def multisegment_in_region(multisegment: _Multisegment, region: _Region, *, context: _Optional[_Context] = None) -> _Relation: """ Finds relation between multisegment and region. Time complexity: ``O(segments_count * log segments_count)`` Memory complexity: ``O(segments_count)`` where ``segments_count = len(multisegment.segments)\ + len(region.vertices)``. :param multisegment: multisegment to check for. :param region: region to check in. :param context: geometric context. :returns: relation between multisegment and region. >>> from ground.base import Relation, get_context >>> context = get_context() >>> Contour = context.contour_cls >>> Multisegment = context.multisegment_cls >>> Point = context.point_cls >>> Segment = context.segment_cls >>> square = Contour([Point(0, 0), Point(4, 0), Point(4, 4), Point(0, 4)]) >>> inner_square = Contour([Point(1, 1), Point(3, 1), Point(3, 3), ... Point(1, 3)]) >>> square_edges = [Segment(Point(0, 0), Point(4, 0)), ... Segment(Point(0, 0), Point(0, 4)), ... Segment(Point(4, 0), Point(4, 4)), ... Segment(Point(0, 4), Point(4, 4))] >>> inner_square_edges = [Segment(Point(1, 1), Point(3, 1)), ... Segment(Point(1, 3), Point(1, 1)), ... Segment(Point(3, 1), Point(3, 3)), ... Segment(Point(1, 3), Point(3, 3))] >>> square_diagonals = [Segment(Point(0, 0), Point(2, 2)), ... Segment(Point(2, 2), Point(4, 0)), ... Segment(Point(2, 2), Point(4, 4)), ... Segment(Point(0, 4), Point(2, 2))] >>> (multisegment_in_region(Multisegment(square_edges), inner_square) ... is Relation.DISJOINT) True >>> (multisegment_in_region( ... Multisegment(square_edges + inner_square_edges), inner_square) ... is Relation.TOUCH) True >>> (multisegment_in_region(Multisegment(square_diagonals), inner_square) ... is Relation.CROSS) True >>> (multisegment_in_region(Multisegment(square_edges), square) ... is Relation.COMPONENT) True >>> (multisegment_in_region( ... Multisegment(square_edges + inner_square_edges), square) ... is Relation.ENCLOSED) True >>> (multisegment_in_region(Multisegment(inner_square_edges), square) ... is Relation.WITHIN) True """ return _region.relate_multisegment( region, multisegment, _get_context() if context is None else context )
[docs]def contour_in_region(contour: _Contour, region: _Region, *, context: _Optional[_Context] = None) -> _Relation: """ Finds relation between contour and region. Time complexity: ``O(vertices_count * log vertices_count)`` Memory complexity: ``O(vertices_count)`` where ``vertices_count = len(contour.vertices) + len(region.vertices)``. :param contour: contour to check for. :param region: region to check in. :param context: geometric context. :returns: relation between contour and region. >>> from ground.base import Relation, get_context >>> context = get_context() >>> Contour = context.contour_cls >>> Point = context.point_cls >>> square = Contour([Point(0, 0), Point(4, 0), Point(4, 4), Point(0, 4)]) >>> inner_square = Contour([Point(1, 1), Point(3, 1), Point(3, 3), ... Point(1, 3)]) >>> triangle = Contour([Point(0, 0), Point(4, 0), Point(0, 4)]) >>> contour_in_region(square, inner_square) is Relation.DISJOINT True >>> contour_in_region(square, triangle) is Relation.TOUCH True >>> contour_in_region(inner_square, triangle) is Relation.CROSS True >>> contour_in_region(square, square) is Relation.COMPONENT True >>> contour_in_region(triangle, square) is Relation.ENCLOSED True >>> contour_in_region(inner_square, square) is Relation.WITHIN True """ return _region.relate_contour( region, contour, _get_context() if context is None else context )
[docs]def region_in_region(left: _Region, right: _Region, *, context: _Optional[_Context] = None) -> _Relation: """ Finds relation between regions. Time complexity: ``O(vertices_count * log vertices_count)`` Memory complexity: ``O(vertices_count)`` where ``vertices_count = len(left.vertices) + len(right.vertices)``. :param left: region to check for. :param right: region to check in. :param context: geometric context. :returns: relation between regions. >>> from ground.base import Relation, get_context >>> context = get_context() >>> Contour = context.contour_cls >>> Point = context.point_cls >>> square = Contour([Point(0, 0), Point(4, 0), Point(4, 4), Point(0, 4)]) >>> neighbour_square = Contour([Point(4, 0), Point(8, 0), Point(8, 4), ... Point(4, 4)]) >>> inner_square = Contour([Point(1, 1), Point(3, 1), Point(3, 3), ... Point(1, 3)]) >>> triangle = Contour([Point(0, 0), Point(4, 0), Point(0, 4)]) >>> (region_in_region(inner_square, neighbour_square) ... is Relation.DISJOINT) True >>> region_in_region(square, neighbour_square) is Relation.TOUCH True >>> region_in_region(inner_square, triangle) is Relation.OVERLAP True >>> region_in_region(square, inner_square) is Relation.COVER True >>> region_in_region(square, triangle) is Relation.ENCLOSES True >>> region_in_region(square, square) is Relation.EQUAL True >>> region_in_region(triangle, square) is Relation.ENCLOSED True >>> region_in_region(inner_square, square) is Relation.WITHIN True """ return _region.relate_region( right, left, _get_context() if context is None else context )
[docs]def point_in_multiregion(point: _Point, multiregion: _Multiregion, *, context: _Optional[_Context] = None) -> _Location: """ Finds location of point in multiregion. Time complexity: ``O(sum(len(region.vertices) for region in multiregion))`` Memory complexity: ``O(1)`` :param point: point to check for. :param multiregion: multiregion to check in. :param context: geometric context. :returns: location of point in multiregion. >>> from ground.base import Location, get_context >>> context = get_context() >>> Contour = context.contour_cls >>> Point = context.point_cls >>> triangle = Contour([Point(0, 0), Point(2, 0), Point(0, 2)]) >>> square = Contour([Point(0, 0), Point(2, 0), Point(2, 2), Point(0, 2)]) >>> point_in_multiregion(Point(0, 0), [triangle]) is Location.BOUNDARY True >>> point_in_multiregion(Point(0, 0), [square]) is Location.BOUNDARY True >>> point_in_multiregion(Point(1, 1), [triangle]) is Location.BOUNDARY True >>> point_in_multiregion(Point(1, 1), [square]) is Location.INTERIOR True >>> point_in_multiregion(Point(2, 2), [triangle]) is Location.EXTERIOR True >>> point_in_multiregion(Point(2, 2), [square]) is Location.BOUNDARY True """ return _multiregion.locate_point( multiregion, point, _get_context() if context is None else context )
[docs]def segment_in_multiregion(segment: _Segment, multiregion: _Multiregion, *, context: _Optional[_Context] = None) -> _Relation: """ Finds relation between segment and multiregion. Time complexity: ``O(segments_count * log segments_count)`` Memory complexity: ``O(segments_count)`` where ``segments_count =\ sum(len(region.vertices) for region in multiregion)``. :param segment: segment to check for. :param multiregion: multiregion to check in. :param context: geometric context. :returns: relation between segment and multiregion. >>> from ground.base import Relation, get_context >>> context = get_context() >>> Contour = context.contour_cls >>> Point = context.point_cls >>> Segment = context.segment_cls >>> square = Contour([Point(0, 0), Point(3, 0), Point(3, 3), Point(0, 3)]) >>> (segment_in_multiregion(Segment(Point(0, 0), Point(1, 0)), []) ... is Relation.DISJOINT) True >>> (segment_in_multiregion(Segment(Point(0, 0), Point(1, 0)), [square]) ... is Relation.COMPONENT) True >>> (segment_in_multiregion(Segment(Point(0, 0), Point(3, 0)), [square]) ... is Relation.COMPONENT) True >>> (segment_in_multiregion(Segment(Point(2, 0), Point(4, 0)), [square]) ... is Relation.TOUCH) True >>> (segment_in_multiregion(Segment(Point(4, 0), Point(5, 0)), [square]) ... is Relation.DISJOINT) True >>> (segment_in_multiregion(Segment(Point(1, 0), Point(1, 2)), [square]) ... is Relation.ENCLOSED) True >>> (segment_in_multiregion(Segment(Point(0, 0), Point(1, 1)), [square]) ... is Relation.ENCLOSED) True >>> (segment_in_multiregion(Segment(Point(1, 1), Point(2, 2)), [square]) ... is Relation.WITHIN) True >>> (segment_in_multiregion(Segment(Point(2, 2), Point(4, 4)), [square]) ... is Relation.CROSS) True """ return _multiregion.relate_segment( multiregion, segment, _get_context() if context is None else context )
[docs]def multisegment_in_multiregion(multisegment: _Multisegment, multiregion: _Multiregion, *, context: _Optional[_Context] = None ) -> _Relation: """ Finds relation between multisegment and multiregion. Time complexity: ``O(segments_count * log segments_count)`` Memory complexity: ``O(segments_count)`` where ``segments_count = len(multisegment.segments)\ + sum(len(region.vertices) for region in multiregion)``. :param multisegment: multisegment to check for. :param multiregion: multiregion to check in. :param context: geometric context. :returns: relation between multisegment and multiregion. >>> from ground.base import Relation, get_context >>> context = get_context() >>> Contour = context.contour_cls >>> Multisegment = context.multisegment_cls >>> Point = context.point_cls >>> Segment = context.segment_cls >>> first_square = Contour([Point(0, 0), Point(4, 0), Point(4, 4), ... Point(0, 4)]) >>> first_inner_square = Contour([Point(1, 1), Point(3, 1), Point(3, 3), ... Point(1, 3)]) >>> second_square = Contour([Point(4, 4), Point(8, 4), Point(8, 8), ... Point(4, 8)]) >>> second_inner_square = Contour([Point(5, 5), Point(7, 5), Point(7, 7), ... Point(5, 7)]) >>> first_square_edges = [Segment(Point(0, 0), Point(4, 0)), ... Segment(Point(0, 0), Point(0, 4)), ... Segment(Point(4, 0), Point(4, 4)), ... Segment(Point(0, 4), Point(4, 4))] >>> first_inner_square_edges = [Segment(Point(1, 1), Point(3, 1)), ... Segment(Point(1, 3), Point(1, 1)), ... Segment(Point(3, 1), Point(3, 3)), ... Segment(Point(1, 3), Point(3, 3))] >>> first_square_diagonals = [Segment(Point(0, 0), Point(2, 2)), ... Segment(Point(2, 2), Point(4, 0)), ... Segment(Point(2, 2), Point(4, 4)), ... Segment(Point(0, 4), Point(2, 2))] >>> (multisegment_in_multiregion(Multisegment(first_square_edges), ... [first_inner_square, second_inner_square]) ... is Relation.DISJOINT) True >>> (multisegment_in_multiregion(Multisegment(first_square_edges ... + first_inner_square_edges), ... [first_inner_square, second_inner_square]) ... is Relation.TOUCH) True >>> (multisegment_in_multiregion(Multisegment(first_square_diagonals), ... [first_inner_square, second_inner_square]) ... is Relation.CROSS) True >>> (multisegment_in_multiregion(Multisegment(first_square_edges), ... [first_square, second_square]) ... is Relation.COMPONENT) True >>> (multisegment_in_multiregion(Multisegment(first_inner_square_edges), ... [first_square, second_square]) ... is Relation.WITHIN) True """ return _multiregion.relate_multisegment( multiregion, multisegment, _get_context() if context is None else context )
[docs]def contour_in_multiregion(contour: _Contour, multiregion: _Multiregion, *, context: _Optional[_Context] = None) -> _Relation: """ Finds relation between contour and multiregion. Time complexity: ``O(vertices_count * log vertices_count)`` Memory complexity: ``O(vertices_count)`` where ``vertices_count = len(contour.vertices)\ + sum(len(region.vertices) for region in multiregion)``. :param contour: contour to check for. :param multiregion: multiregion to check in. :param context: geometric context. :returns: relation between contour and multiregion. >>> from ground.base import Relation, get_context >>> context = get_context() >>> Contour = context.contour_cls >>> Point = context.point_cls >>> first_square = Contour([Point(0, 0), Point(4, 0), Point(4, 4), ... Point(0, 4)]) >>> second_square = Contour([Point(4, 0), Point(8, 0), Point(8, 4), ... Point(4, 4)]) >>> third_square = Contour([Point(4, 4), Point(8, 4), Point(8, 8), ... Point(4, 8)]) >>> first_inner_square = Contour([Point(1, 1), Point(3, 1), Point(3, 3), ... Point(1, 3)]) >>> second_inner_square = Contour([Point(5, 1), Point(7, 1), Point(7, 3), ... Point(5, 3)]) >>> triangle = Contour([Point(0, 0), Point(4, 0), Point(0, 4)]) >>> (contour_in_multiregion(first_square, ... [first_inner_square, second_inner_square]) ... is Relation.DISJOINT) True >>> (contour_in_multiregion(second_square, [first_square, third_square]) ... is Relation.TOUCH) True >>> (contour_in_multiregion(first_inner_square, [triangle, second_square]) ... is Relation.CROSS) True >>> (contour_in_multiregion(first_square, [first_square, third_square]) ... is Relation.COMPONENT) True >>> (contour_in_multiregion(triangle, [first_square, third_square]) ... is Relation.ENCLOSED) True >>> (contour_in_multiregion(first_inner_square, ... [first_square, third_square]) ... is Relation.WITHIN) True """ return _multiregion.relate_contour( multiregion, contour, _get_context() if context is None else context )
[docs]def region_in_multiregion(region: _Region, multiregion: _Multiregion, *, context: _Optional[_Context] = None) -> _Relation: """ Finds relation between region and multiregion. Time complexity: ``O(vertices_count * log vertices_count)`` Memory complexity: ``O(vertices_count)`` where ``vertices_count = len(region.vertices)\ + sum(len(region.vertices) for region in multiregion)``. :param region: region to check for. :param multiregion: multiregion to check in. :param context: geometric context. :returns: relation between region and multiregion. >>> from ground.base import Relation, get_context >>> context = get_context() >>> Contour = context.contour_cls >>> Point = context.point_cls >>> first_square = Contour([Point(0, 0), Point(4, 0), Point(4, 4), ... Point(0, 4)]) >>> second_square = Contour([Point(4, 0), Point(8, 0), Point(8, 4), ... Point(4, 4)]) >>> third_square = Contour([Point(4, 4), Point(8, 4), Point(8, 8), ... Point(4, 8)]) >>> first_inner_square = Contour([Point(1, 1), Point(3, 1), Point(3, 3), ... Point(1, 3)]) >>> second_inner_square = Contour([Point(5, 1), Point(7, 1), Point(7, 3), ... Point(5, 3)]) >>> outer_square = Contour([Point(0, 0), Point(8, 0), Point(8, 8), ... Point(0, 8)]) >>> triangle = Contour([Point(0, 0), Point(4, 0), Point(0, 4)]) >>> (region_in_multiregion(third_square, ... [first_inner_square, second_inner_square]) ... is Relation.DISJOINT) True >>> (region_in_multiregion(second_square, [first_square, third_square]) ... is Relation.TOUCH) True >>> (region_in_multiregion(first_square, ... [first_inner_square, second_inner_square]) ... is Relation.OVERLAP) True >>> (region_in_multiregion(outer_square, ... [first_inner_square, second_inner_square]) ... is Relation.COVER) True >>> (region_in_multiregion(outer_square, [first_square, third_square]) ... is Relation.ENCLOSES) True >>> (region_in_multiregion(triangle, [first_square, third_square]) ... is Relation.ENCLOSED) True >>> (region_in_multiregion(first_inner_square, ... [first_square, third_square]) ... is Relation.WITHIN) True """ return _multiregion.relate_region( multiregion, region, _get_context() if context is None else context )
[docs]def multiregion_in_multiregion(left: _Multiregion, right: _Multiregion, *, context: _Optional[_Context] = None ) -> _Relation: """ Finds relation between multiregions. Time complexity: ``O(vertices_count * log vertices_count)`` Memory complexity: ``O(vertices_count)`` where ``vertices_count = sum(len(region.vertices) for region in left)\ + sum(len(region.vertices) for region in right)``. :param left: multiregion to check for. :param right: multiregion to check in. :param context: geometric context. :returns: relation between multiregions. >>> from ground.base import Relation, get_context >>> context = get_context() >>> Contour = context.contour_cls >>> Point = context.point_cls >>> first_square = Contour([Point(0, 0), Point(4, 0), Point(4, 4), ... Point(0, 4)]) >>> second_square = Contour([Point(4, 0), Point(8, 0), Point(8, 4), ... Point(4, 4)]) >>> third_square = Contour([Point(4, 4), Point(8, 4), Point(8, 8), ... Point(4, 8)]) >>> fourth_square = Contour([Point(0, 4), Point(4, 4), Point(4, 8), ... Point(0, 8)]) >>> first_inner_square = Contour([Point(1, 1), Point(3, 1), Point(3, 3), ... Point(1, 3)]) >>> second_inner_square = Contour([Point(5, 1), Point(7, 1), Point(7, 3), ... Point(5, 3)]) >>> third_inner_square = Contour([Point(5, 5), Point(7, 5), Point(7, 7), ... Point(5, 7)]) >>> (multiregion_in_multiregion([first_inner_square, third_inner_square], ... [second_square, fourth_square]) ... is Relation.DISJOINT) True >>> (multiregion_in_multiregion([first_square, third_square], ... [second_square, fourth_square]) ... is Relation.TOUCH) True >>> (multiregion_in_multiregion([first_square, third_inner_square], ... [first_inner_square, third_square]) ... is Relation.OVERLAP) True >>> (multiregion_in_multiregion([first_square, third_square], ... [first_inner_square, third_inner_square]) ... is Relation.COVER) True >>> (multiregion_in_multiregion([first_square, third_square], ... [first_square, third_inner_square]) ... is Relation.ENCLOSES) True >>> (multiregion_in_multiregion( ... [first_inner_square, second_inner_square, third_inner_square], ... [first_inner_square, second_inner_square]) ... is Relation.COMPOSITE) True >>> (multiregion_in_multiregion([first_square, third_square], ... [first_square, third_square]) ... is Relation.EQUAL) True >>> (multiregion_in_multiregion( ... [first_inner_square, second_inner_square], ... [first_inner_square, second_inner_square, third_inner_square]) ... is Relation.COMPONENT) True >>> (multiregion_in_multiregion([first_square, third_inner_square], ... [first_square, third_square]) ... is Relation.ENCLOSED) True >>> (multiregion_in_multiregion([first_inner_square, third_inner_square], ... [first_square, third_square]) ... is Relation.WITHIN) True """ return _multiregion.relate_multiregion( right, left, _get_context() if context is None else context )
[docs]def point_in_polygon(point: _Point, polygon: _Polygon, *, context: _Optional[_Context] = None) -> _Location: """ Finds location of point in polygon. Time complexity: ``O(vertices_count)`` Memory complexity: ``O(1)`` where ``vertices_count = len(polygon.border.vertices)\ + sum(len(hole.vertices) for hole in polygon.holes)``. :param point: point to check for. :param polygon: polygon to check in. :param context: geometric context. :returns: location of point in polygon. >>> from ground.base import Location, get_context >>> context = get_context() >>> Contour = context.contour_cls >>> Point = context.point_cls >>> Polygon = context.polygon_cls >>> outer_square = Contour([Point(0, 0), Point(4, 0), Point(4, 4), ... Point(0, 4)]) >>> inner_square = Contour([Point(1, 1), Point(3, 1), Point(3, 3), ... Point(1, 3)]) >>> (point_in_polygon(Point(0, 0), Polygon(inner_square, [])) ... is Location.EXTERIOR) True >>> (point_in_polygon(Point(0, 0), Polygon(outer_square, [])) ... is Location.BOUNDARY) True >>> (point_in_polygon(Point(1, 1), Polygon(inner_square, [])) ... is Location.BOUNDARY) True >>> (point_in_polygon(Point(1, 1), Polygon(outer_square, [])) ... is Location.INTERIOR) True >>> (point_in_polygon(Point(2, 2), Polygon(outer_square, [])) ... is Location.INTERIOR) True >>> (point_in_polygon(Point(2, 2), Polygon(outer_square, [inner_square])) ... is Location.EXTERIOR) True """ return _polygon.locate_point( polygon, point, _get_context() if context is None else context )
[docs]def segment_in_polygon(segment: _Segment, polygon: _Polygon, *, context: _Optional[_Context] = None) -> _Relation: """ Finds relation between segment and polygon. Time complexity: ``O(vertices_count * log vertices_count)`` Memory complexity: ``O(vertices_count)`` where ``vertices_count = len(polygon.border.vertices)\ + sum(len(hole.vertices) for hole in polygon.holes)``. :param segment: segment to check for. :param polygon: polygon to check in. :param context: geometric context. :returns: relation between segment and polygon. >>> from ground.base import Relation, get_context >>> context = get_context() >>> Contour = context.contour_cls >>> Point = context.point_cls >>> Polygon = context.polygon_cls >>> Segment = context.segment_cls >>> outer_square = Contour([Point(0, 0), Point(4, 0), Point(4, 4), ... Point(0, 4)]) >>> inner_square = Contour([Point(1, 1), Point(3, 1), Point(3, 3), ... Point(1, 3)]) >>> segment_in_polygon(Segment(Point(0, 0), Point(1, 0)), ... Polygon(outer_square, [])) is Relation.COMPONENT True >>> (segment_in_polygon(Segment(Point(0, 0), Point(1, 0)), ... Polygon(outer_square, [inner_square])) ... is Relation.COMPONENT) True >>> segment_in_polygon(Segment(Point(0, 0), Point(2, 2)), ... Polygon(outer_square, [])) is Relation.ENCLOSED True >>> (segment_in_polygon(Segment(Point(0, 0), Point(2, 2)), ... Polygon(outer_square, [inner_square])) ... is Relation.CROSS) True >>> segment_in_polygon(Segment(Point(1, 1), Point(3, 3)), ... Polygon(outer_square, [])) is Relation.WITHIN True >>> (segment_in_polygon(Segment(Point(1, 1), Point(3, 3)), ... Polygon(outer_square, [inner_square])) ... is Relation.TOUCH) True >>> segment_in_polygon(Segment(Point(0, 0), Point(4, 4)), ... Polygon(outer_square, [])) is Relation.ENCLOSED True >>> (segment_in_polygon(Segment(Point(0, 0), Point(4, 4)), ... Polygon(outer_square, [inner_square])) ... is Relation.CROSS) True """ return _polygon.relate_segment( polygon, segment, _get_context() if context is None else context )
[docs]def multisegment_in_polygon(multisegment: _Multisegment, polygon: _Polygon, *, context: _Optional[_Context] = None) -> _Relation: """ Finds relation between multisegment and polygon. Time complexity: ``O(segments_count * log segments_count)`` Memory complexity: ``O(segments_count)`` where ``segments_count = len(multisegment.segments)\ + len(polygon.border.vertices)\ + sum(len(hole.vertices) for hole in polygon.holes)``. :param multisegment: multisegment to check for. :param polygon: polygon to check in. :param context: geometric context. :returns: relation between multisegment and polygon. >>> from ground.base import Relation, get_context >>> context = get_context() >>> Contour = context.contour_cls >>> Multisegment = context.multisegment_cls >>> Point = context.point_cls >>> Polygon = context.polygon_cls >>> Segment = context.segment_cls >>> square = Contour([Point(0, 0), Point(4, 0), Point(4, 4), Point(0, 4)]) >>> inner_square = Contour([Point(1, 1), Point(3, 1), Point(3, 3), ... Point(1, 3)]) >>> square_edges = [Segment(Point(0, 0), Point(4, 0)), ... Segment(Point(0, 0), Point(0, 4)), ... Segment(Point(4, 0), Point(4, 4)), ... Segment(Point(0, 4), Point(4, 4))] >>> inner_square_edges = [Segment(Point(1, 1), Point(3, 1)), ... Segment(Point(1, 3), Point(1, 1)), ... Segment(Point(3, 1), Point(3, 3)), ... Segment(Point(1, 3), Point(3, 3))] >>> square_diagonals = [Segment(Point(0, 0), Point(2, 2)), ... Segment(Point(2, 2), Point(4, 0)), ... Segment(Point(2, 2), Point(4, 4)), ... Segment(Point(0, 4), Point(2, 2))] >>> (multisegment_in_polygon(Multisegment(square_edges), ... Polygon(inner_square, [])) ... is Relation.DISJOINT) True >>> (multisegment_in_polygon(Multisegment(square_edges ... + inner_square_edges), ... Polygon(inner_square, [])) ... is Relation.TOUCH) True >>> (multisegment_in_polygon(Multisegment(square_diagonals), ... Polygon(inner_square, [])) ... is Relation.CROSS) True >>> (multisegment_in_polygon(Multisegment(square_edges), ... Polygon(square, [])) ... is Relation.COMPONENT) True >>> (multisegment_in_polygon(Multisegment(square_edges ... + inner_square_edges), ... Polygon(square, [])) ... is Relation.ENCLOSED) True >>> (multisegment_in_polygon(Multisegment(inner_square_edges), ... Polygon(square, [])) ... is Relation.WITHIN) True """ return _polygon.relate_multisegment( polygon, multisegment, _get_context() if context is None else context )
[docs]def contour_in_polygon(contour: _Contour, polygon: _Polygon, *, context: _Optional[_Context] = None) -> _Relation: """ Finds relation between contour and polygon. Time complexity: ``O(vertices_count * log vertices_count)`` Memory complexity: ``O(vertices_count)`` where ``vertices_count = len(contour.vertices)\ + len(polygon.border.vertices)\ + sum(len(hole.vertices) for hole in polygon.holes)``. :param contour: contour to check for. :param polygon: polygon to check in. :param context: geometric context. :returns: relation between contour and polygon. >>> from ground.base import Relation, get_context >>> context = get_context() >>> Contour = context.contour_cls >>> Point = context.point_cls >>> Polygon = context.polygon_cls >>> square = Contour([Point(0, 0), Point(4, 0), Point(4, 4), Point(0, 4)]) >>> inner_square = Contour([Point(1, 1), Point(3, 1), Point(3, 3), ... Point(1, 3)]) >>> triangle = Contour([Point(0, 0), Point(4, 0), Point(0, 4)]) >>> (contour_in_polygon(square, Polygon(inner_square, [])) ... is Relation.DISJOINT) True >>> contour_in_polygon(square, Polygon(triangle, [])) is Relation.TOUCH True >>> (contour_in_polygon(inner_square, Polygon(triangle, [])) ... is Relation.CROSS) True >>> contour_in_polygon(square, Polygon(square, [])) is Relation.COMPONENT True >>> contour_in_polygon(triangle, Polygon(square, [])) is Relation.ENCLOSED True >>> (contour_in_polygon(inner_square, Polygon(square, [])) ... is Relation.WITHIN) True """ return _polygon.relate_contour( polygon, contour, _get_context() if context is None else context )
[docs]def region_in_polygon(region: _Region, polygon: _Polygon, *, context: _Optional[_Context] = None) -> _Relation: """ Finds relation between region and polygon. Time complexity: ``O(vertices_count * log vertices_count)`` Memory complexity: ``O(vertices_count)`` where ``vertices_count = len(region.vertices)\ + len(polygon.border.vertices)\ + sum(len(hole.vertices) for hole in polygon.holes)``. :param region: region to check for. :param polygon: polygon to check in. :param context: geometric context. :returns: relation between region and polygon. >>> from ground.base import Relation, get_context >>> context = get_context() >>> Contour = context.contour_cls >>> Point = context.point_cls >>> Polygon = context.polygon_cls >>> square = Contour([Point(0, 0), Point(4, 0), Point(4, 4), Point(0, 4)]) >>> neighbour_square = Contour([Point(4, 0), Point(8, 0), Point(8, 4), ... Point(4, 4)]) >>> inner_square = Contour([Point(1, 1), Point(3, 1), Point(3, 3), ... Point(1, 3)]) >>> triangle = Contour([Point(0, 0), Point(4, 0), Point(0, 4)]) >>> (region_in_polygon(inner_square, Polygon(neighbour_square, [])) ... is Relation.DISJOINT) True >>> (region_in_polygon(square, Polygon(neighbour_square, [])) ... is Relation.TOUCH) True >>> (region_in_polygon(inner_square, Polygon(triangle, [])) ... is Relation.OVERLAP) True >>> region_in_polygon(square, Polygon(inner_square, [])) is Relation.COVER True >>> region_in_polygon(square, Polygon(triangle, [])) is Relation.ENCLOSES True >>> region_in_polygon(square, Polygon(square, [])) is Relation.EQUAL True >>> region_in_polygon(triangle, Polygon(square, [])) is Relation.ENCLOSED True >>> region_in_polygon(inner_square, Polygon(square, [])) is Relation.WITHIN True """ return _polygon.relate_region( polygon, region, _get_context() if context is None else context )
[docs]def multiregion_in_polygon(multiregion: _Multiregion, polygon: _Polygon, *, context: _Optional[_Context] = None) -> _Relation: """ Finds relation between multiregion and polygon. Time complexity: ``O(vertices_count * log vertices_count)`` Memory complexity: ``O(vertices_count)`` where ``vertices_count =\ sum(len(region.vertices) for region in multiregion)\ + len(polygon.border.vertices)\ + sum(len(hole.vertices) for hole in polygon.holes)``. :param multiregion: multiregion to check for. :param polygon: polygon to check in. :param context: geometric context. :returns: relation between multiregion and polygon. >>> from ground.base import Relation, get_context >>> context = get_context() >>> Contour = context.contour_cls >>> Point = context.point_cls >>> Polygon = context.polygon_cls >>> first_square = Contour([Point(0, 0), Point(4, 0), Point(4, 4), ... Point(0, 4)]) >>> second_square = Contour([Point(4, 0), Point(8, 0), Point(8, 4), ... Point(4, 4)]) >>> third_square = Contour([Point(4, 4), Point(8, 4), Point(8, 8), ... Point(4, 8)]) >>> first_inner_square = Contour([Point(1, 1), Point(3, 1), Point(3, 3), ... Point(1, 3)]) >>> second_inner_square = Contour([Point(5, 1), Point(7, 1), Point(7, 3), ... Point(5, 3)]) >>> outer_square = Contour([Point(0, 0), Point(8, 0), Point(8, 8), ... Point(0, 8)]) >>> (multiregion_in_polygon([first_square, third_square], ... Polygon(second_inner_square, [])) ... is Relation.DISJOINT) True >>> (multiregion_in_polygon([first_inner_square, second_inner_square], ... Polygon(first_square, [first_inner_square])) ... is Relation.TOUCH) True >>> (multiregion_in_polygon([first_inner_square, second_inner_square], ... Polygon(first_square, [])) ... is Relation.OVERLAP) True >>> (multiregion_in_polygon([first_square, second_inner_square], ... Polygon(first_inner_square, [])) ... is Relation.COVER) True >>> (multiregion_in_polygon([first_square, second_inner_square], ... Polygon(first_square, [first_inner_square])) ... is Relation.ENCLOSES) True >>> (multiregion_in_polygon([first_square, second_inner_square], ... Polygon(first_square, [])) ... is Relation.COMPOSITE) True >>> (multiregion_in_polygon([first_square, second_inner_square], ... Polygon(outer_square, [])) ... is Relation.ENCLOSED) True >>> (multiregion_in_polygon([first_inner_square, second_inner_square], ... Polygon(outer_square, [])) ... is Relation.WITHIN) True """ return _polygon.relate_multiregion( polygon, multiregion, _get_context() if context is None else context )
[docs]def polygon_in_polygon(left: _Polygon, right: _Polygon, *, context: _Optional[_Context] = None) -> _Relation: """ Finds relation between polygons. Time complexity: ``O(vertices_count * log vertices_count)`` Memory complexity: ``O(vertices_count)`` where ``vertices_count = len(left.border.vertices)\ + sum(len(hole.vertices) for hole in left.holes) + len(right.border.vertices)\ + sum(len(hole.vertices) for hole in right.holes)``. :param left: polygon to check for. :param right: polygon to check in. :param context: geometric context. :returns: relation between polygons. >>> from ground.base import Relation, get_context >>> context = get_context() >>> Contour = context.contour_cls >>> Point = context.point_cls >>> Polygon = context.polygon_cls >>> outer_square = Contour([Point(0, 0), Point(7, 0), Point(7, 7), ... Point(0, 7)]) >>> inner_square = Contour([Point(1, 1), Point(6, 1), Point(6, 6), ... Point(1, 6)]) >>> innermore_square = Contour([Point(2, 2), Point(5, 2), Point(5, 5), ... Point(2, 5)]) >>> innermost_square = Contour([Point(3, 3), Point(4, 3), Point(4, 4), ... Point(3, 4)]) >>> (polygon_in_polygon(Polygon(outer_square, [inner_square]), ... Polygon(innermore_square, [])) ... is polygon_in_polygon(Polygon(innermore_square, []), ... Polygon(outer_square, [inner_square])) ... is polygon_in_polygon(Polygon(outer_square, [inner_square]), ... Polygon(innermore_square, [innermost_square])) ... is polygon_in_polygon(Polygon(innermore_square, [innermost_square]), ... Polygon(outer_square, [inner_square])) ... is Relation.DISJOINT) True >>> (polygon_in_polygon(Polygon(inner_square, []), ... Polygon(outer_square, [inner_square])) ... is polygon_in_polygon(Polygon(outer_square, [inner_square]), ... Polygon(inner_square, [])) ... is polygon_in_polygon(Polygon(outer_square, [inner_square]), ... Polygon(inner_square, [innermore_square])) ... is polygon_in_polygon(Polygon(inner_square, [innermore_square]), ... Polygon(outer_square, [inner_square])) ... is Relation.TOUCH) True >>> (polygon_in_polygon(Polygon(inner_square, []), ... Polygon(outer_square, [innermore_square])) ... is polygon_in_polygon(Polygon(outer_square, [innermore_square]), ... Polygon(inner_square, [])) ... is polygon_in_polygon(Polygon(outer_square, [innermore_square]), ... Polygon(inner_square, [innermost_square])) ... is polygon_in_polygon(Polygon(inner_square, [innermost_square]), ... Polygon(outer_square, [innermore_square])) ... is Relation.OVERLAP) True >>> (polygon_in_polygon(Polygon(outer_square, []), ... Polygon(inner_square, [])) ... is polygon_in_polygon(Polygon(outer_square, [innermost_square]), ... Polygon(inner_square, [innermore_square])) ... is Relation.COVER) True >>> (polygon_in_polygon(Polygon(outer_square, []), ... Polygon(outer_square, [inner_square])) ... is polygon_in_polygon(Polygon(outer_square, [innermore_square]), ... Polygon(outer_square, [inner_square])) ... is polygon_in_polygon(Polygon(outer_square, [innermore_square]), ... Polygon(inner_square, [innermore_square])) ... is Relation.ENCLOSES) True >>> (polygon_in_polygon(Polygon(outer_square, []), ... Polygon(outer_square, [])) ... is polygon_in_polygon(Polygon(outer_square, [inner_square]), ... Polygon(outer_square, [inner_square])) ... is Relation.EQUAL) True >>> (polygon_in_polygon(Polygon(outer_square, [inner_square]), ... Polygon(outer_square, [])) ... is polygon_in_polygon(Polygon(outer_square, [inner_square]), ... Polygon(outer_square, [innermore_square])) ... is polygon_in_polygon(Polygon(inner_square, [innermore_square]), ... Polygon(outer_square, [innermore_square])) ... is Relation.ENCLOSED) True >>> (polygon_in_polygon(Polygon(inner_square, []), ... Polygon(outer_square, [])) ... is polygon_in_polygon(Polygon(inner_square, [innermore_square]), ... Polygon(outer_square, [innermost_square])) ... is Relation.WITHIN) True """ return _polygon.relate_polygon( right, left, _get_context() if context is None else context )
[docs]def point_in_multipolygon(point: _Point, multipolygon: _Multipolygon, *, context: _Optional[_Context] = None) -> _Relation: """ Finds location of point in multipolygon. Time complexity: ``O(sum(len(polygon.border.vertices)\ + sum(len(hole.vertices) for hole in polygon.holes))\ for polygon in multipolygon.polygons))`` Memory complexity: ``O(1)`` :param point: point to check for. :param multipolygon: multipolygon to check in. :param context: geometric context. :returns: location of point in multipolygon. >>> from ground.base import Location, get_context >>> context = get_context() >>> Contour = context.contour_cls >>> Multipolygon = context.multipolygon_cls >>> Point = context.point_cls >>> Polygon = context.polygon_cls >>> first_square = Contour([Point(0, 0), Point(4, 0), Point(4, 4), ... Point(0, 4)]) >>> second_square = Contour([Point(4, 4), Point(8, 4), Point(8, 8), ... Point(4, 8)]) >>> (point_in_multipolygon(Point(6, 2), ... Multipolygon([Polygon(first_square, []), ... Polygon(second_square, [])])) ... is Location.EXTERIOR) True >>> (point_in_multipolygon(Point(4, 4), ... Multipolygon([Polygon(first_square, []), ... Polygon(second_square, [])])) ... is Location.BOUNDARY) True >>> (point_in_multipolygon(Point(2, 2), ... Multipolygon([Polygon(first_square, []), ... Polygon(second_square, [])])) ... is Location.INTERIOR) True """ return _multipolygon.locate_point( multipolygon, point, _get_context() if context is None else context )
[docs]def segment_in_multipolygon(segment: _Segment, multipolygon: _Multipolygon, *, context: _Optional[_Context] = None) -> _Relation: """ Finds relation between segment and multipolygon. Time complexity: ``O(segments_count * log segments_count)`` Memory complexity: ``O(segments_count)`` where ``segments_count = sum(len(polygon.border.vertices)\ + sum(len(hole.vertices) for hole in polygon.holes)\ for polygon in multipolygon.polygons)``. :param segment: segment to check for. :param multipolygon: multipolygon to check in. :param context: geometric context. :returns: relation between segment and multipolygon. >>> from ground.base import Relation, get_context >>> context = get_context() >>> Contour = context.contour_cls >>> Multipolygon = context.multipolygon_cls >>> Point = context.point_cls >>> Polygon = context.polygon_cls >>> Segment = context.segment_cls >>> first_square = Contour([Point(0, 0), Point(4, 0), Point(4, 4), ... Point(0, 4)]) >>> second_square = Contour([Point(4, 4), Point(8, 4), Point(8, 8), ... Point(4, 8)]) >>> (segment_in_multipolygon(Segment(Point(2, 5), Point(2, 9)), ... Multipolygon([Polygon(first_square, []), ... Polygon(second_square, [])])) ... is Relation.DISJOINT) True >>> (segment_in_multipolygon(Segment(Point(2, 4), Point(2, 8)), ... Multipolygon([Polygon(first_square, []), ... Polygon(second_square, [])])) ... is Relation.TOUCH) True >>> (segment_in_multipolygon(Segment(Point(2, 2), Point(2, 6)), ... Multipolygon([Polygon(first_square, []), ... Polygon(second_square, [])])) ... is Relation.CROSS) True >>> (segment_in_multipolygon(Segment(Point(2, 4), Point(6, 4)), ... Multipolygon([Polygon(first_square, []), ... Polygon(second_square, [])])) ... is Relation.COMPONENT) True >>> (segment_in_multipolygon(Segment(Point(3, 3), Point(5, 5)), ... Multipolygon([Polygon(first_square, []), ... Polygon(second_square, [])])) ... is Relation.ENCLOSED) True >>> (segment_in_multipolygon(Segment(Point(1, 1), Point(3, 3)), ... Multipolygon([Polygon(first_square, []), ... Polygon(second_square, [])])) ... is Relation.WITHIN) True """ return _multipolygon.relate_segment( multipolygon, segment, _get_context() if context is None else context )
[docs]def multisegment_in_multipolygon(multisegment: _Multisegment, multipolygon: _Multipolygon, *, context: _Optional[_Context] = None ) -> _Relation: """ Finds relation between multisegment and multipolygon. Time complexity: ``O(segments_count * log segments_count)`` Memory complexity: ``O(segments_count)`` where ``segments_count = len(multisegment.segments)\ + multipolygon_segments_count``, ``multipolygon_segments_count = sum(len(polygon.border.vertices)\ + sum(len(hole.vertices) for hole in polygon.holes)\ for polygon in multipolygon.polygons)``. :param multisegment: multisegment to check for. :param multipolygon: multipolygon to check in. :param context: geometric context. :returns: relation between multisegment and multipolygon. >>> from ground.base import Relation, get_context >>> context = get_context() >>> Contour = context.contour_cls >>> Multipolygon = context.multipolygon_cls >>> Multisegment = context.multisegment_cls >>> Point = context.point_cls >>> Polygon = context.polygon_cls >>> Segment = context.segment_cls >>> first_square = Contour([Point(0, 0), Point(4, 0), Point(4, 4), ... Point(0, 4)]) >>> first_inner_square = Contour([Point(1, 1), Point(3, 1), Point(3, 3), ... Point(1, 3)]) >>> second_square = Contour([Point(4, 4), Point(8, 4), Point(8, 8), ... Point(4, 8)]) >>> second_inner_square = Contour([Point(5, 5), Point(7, 5), Point(7, 7), ... Point(5, 7)]) >>> first_square_edges = [Segment(Point(0, 0), Point(4, 0)), ... Segment(Point(0, 0), Point(0, 4)), ... Segment(Point(4, 0), Point(4, 4)), ... Segment(Point(0, 4), Point(4, 4))] >>> first_inner_square_edges = [Segment(Point(1, 1), Point(3, 1)), ... Segment(Point(1, 3), Point(1, 1)), ... Segment(Point(3, 1), Point(3, 3)), ... Segment(Point(1, 3), Point(3, 3))] >>> first_square_diagonals = [Segment(Point(0, 0), Point(2, 2)), ... Segment(Point(2, 2), Point(4, 0)), ... Segment(Point(2, 2), Point(4, 4)), ... Segment(Point(0, 4), Point(2, 2))] >>> (multisegment_in_multipolygon( ... Multisegment(first_square_edges), ... Multipolygon([Polygon(first_inner_square, []), ... Polygon(second_inner_square, [])])) ... is Relation.DISJOINT) True >>> (multisegment_in_multipolygon( ... Multisegment(first_square_edges + first_inner_square_edges), ... Multipolygon([Polygon(first_inner_square, []), ... Polygon(second_inner_square, [])])) ... is Relation.TOUCH) True >>> (multisegment_in_multipolygon( ... Multisegment(first_square_diagonals), ... Multipolygon([Polygon(first_inner_square, []), ... Polygon(second_inner_square, [])])) ... is Relation.CROSS) True >>> (multisegment_in_multipolygon( ... Multisegment(first_square_edges), ... Multipolygon([Polygon(first_square, []), ... Polygon(second_square, [])])) ... is Relation.COMPONENT) True >>> (multisegment_in_multipolygon( ... Multisegment(first_inner_square_edges), ... Multipolygon([Polygon(first_square, []), ... Polygon(second_square, [])])) ... is Relation.WITHIN) True """ return _multipolygon.relate_multisegment( multipolygon, multisegment, _get_context() if context is None else context )
[docs]def contour_in_multipolygon(contour: _Contour, multipolygon: _Multipolygon, *, context: _Optional[_Context] = None) -> _Relation: """ Finds relation between contour and multipolygon. Time complexity: ``O(vertices_count * log vertices_count)`` Memory complexity: ``O(vertices_count)`` where ``vertices_count = len(contour.vertices)\ + multipolygon_vertices_count``, ``multipolygon_vertices_count = sum(len(polygon.border.vertices)\ + sum(len(hole.vertices) for hole in polygon.holes)\ for polygon in multipolygon.polygons)``. :param contour: contour to check for. :param multipolygon: multipolygon to check in. :param context: geometric context. :returns: relation between contour and multipolygon. >>> from ground.base import Relation, get_context >>> context = get_context() >>> Contour = context.contour_cls >>> Multipolygon = context.multipolygon_cls >>> Point = context.point_cls >>> Polygon = context.polygon_cls >>> first_square = Contour([Point(0, 0), Point(4, 0), Point(4, 4), ... Point(0, 4)]) >>> second_square = Contour([Point(4, 0), Point(8, 0), Point(8, 4), ... Point(4, 4)]) >>> third_square = Contour([Point(4, 4), Point(8, 4), Point(8, 8), ... Point(4, 8)]) >>> first_inner_square = Contour([Point(1, 1), Point(3, 1), Point(3, 3), ... Point(1, 3)]) >>> second_inner_square = Contour([Point(5, 1), Point(7, 1), Point(7, 3), ... Point(5, 3)]) >>> triangle = Contour([Point(0, 0), Point(4, 0), Point(0, 4)]) >>> (contour_in_multipolygon( ... first_square, Multipolygon([Polygon(first_inner_square, []), ... Polygon(second_inner_square, [])])) ... is Relation.DISJOINT) True >>> (contour_in_multipolygon( ... second_square, Multipolygon([Polygon(first_square, []), ... Polygon(third_square, [])])) ... is Relation.TOUCH) True >>> (contour_in_multipolygon( ... first_inner_square, Multipolygon([Polygon(triangle, []), ... Polygon(second_square, [])])) ... is Relation.CROSS) True >>> (contour_in_multipolygon( ... first_square, Multipolygon([Polygon(first_square, []), ... Polygon(third_square, [])])) ... is Relation.COMPONENT) True >>> (contour_in_multipolygon( ... triangle, Multipolygon([Polygon(first_square, []), ... Polygon(third_square, [])])) ... is Relation.ENCLOSED) True >>> (contour_in_multipolygon( ... first_inner_square, Multipolygon([Polygon(first_square, []), ... Polygon(third_square, [])])) ... is Relation.WITHIN) True """ return _multipolygon.relate_contour( multipolygon, contour, _get_context() if context is None else context )
[docs]def region_in_multipolygon(region: _Region, multipolygon: _Multipolygon, *, context: _Optional[_Context] = None) -> _Relation: """ Finds relation between region and multipolygon. Time complexity: ``O(vertices_count * log vertices_count)`` Memory complexity: ``O(vertices_count)`` where ``vertices_count = len(region.vertices)\ + multipolygon_vertices_count``, ``multipolygon_vertices_count = sum(len(polygon.border.vertices)\ + sum(len(hole.vertices) for hole in polygon.holes)\ for polygon in multipolygon.polygons)``. :param region: region to check for. :param multipolygon: multipolygon to check in. :param context: geometric context. :returns: relation between region and multipolygon. >>> from ground.base import Relation, get_context >>> context = get_context() >>> Contour = context.contour_cls >>> Point = context.point_cls >>> Polygon = context.polygon_cls >>> Multipolygon = context.multipolygon_cls >>> first_square = Contour([Point(0, 0), Point(4, 0), Point(4, 4), ... Point(0, 4)]) >>> second_square = Contour([Point(4, 0), Point(8, 0), Point(8, 4), ... Point(4, 4)]) >>> third_square = Contour([Point(4, 4), Point(8, 4), Point(8, 8), ... Point(4, 8)]) >>> first_inner_square = Contour([Point(1, 1), Point(3, 1), Point(3, 3), ... Point(1, 3)]) >>> second_inner_square = Contour([Point(5, 1), Point(7, 1), Point(7, 3), ... Point(5, 3)]) >>> outer_square = Contour([Point(0, 0), Point(8, 0), Point(8, 8), ... Point(0, 8)]) >>> triangle = Contour([Point(0, 0), Point(4, 0), Point(0, 4)]) >>> (region_in_multipolygon( ... third_square, Multipolygon([Polygon(first_inner_square, []), ... Polygon(second_inner_square, [])])) ... is Relation.DISJOINT) True >>> (region_in_multipolygon( ... second_square, Multipolygon([Polygon(first_square, []), ... Polygon(third_square, [])])) ... is Relation.TOUCH) True >>> (region_in_multipolygon( ... first_square, Multipolygon([Polygon(first_inner_square, []), ... Polygon(second_inner_square, [])])) ... is Relation.OVERLAP) True >>> (region_in_multipolygon( ... outer_square, Multipolygon([Polygon(first_inner_square, []), ... Polygon(second_inner_square, [])])) ... is Relation.COVER) True >>> (region_in_multipolygon( ... outer_square, Multipolygon([Polygon(first_square, []), ... Polygon(third_square, [])])) ... is Relation.ENCLOSES) True >>> (region_in_multipolygon( ... triangle, Multipolygon([Polygon(first_square, []), ... Polygon(third_square, [])])) ... is Relation.ENCLOSED) True >>> (region_in_multipolygon( ... first_inner_square, Multipolygon([Polygon(first_square, []), ... Polygon(third_square, [])])) ... is Relation.WITHIN) True """ return _multipolygon.relate_region( multipolygon, region, _get_context() if context is None else context )
[docs]def multiregion_in_multipolygon(multiregion: _Multiregion, multipolygon: _Multipolygon, *, context: _Optional[_Context] = None ) -> _Relation: """ Finds relation between multiregion and multipolygon. Time complexity: ``O(vertices_count * log vertices_count)`` Memory complexity: ``O(vertices_count)`` where ``vertices_count = multiregion_vertices_count\ + multipolygon_vertices_count``, ``multiregion_vertices_count =\ sum(len(region.vertices) for region in multiregion)``, ``multipolygon_vertices_count = sum(len(polygon.border.vertices)\ + sum(len(hole.vertices) for hole in polygon.holes)\ for polygon in multipolygon.polygons)``. :param multiregion: multiregion to check for. :param multipolygon: multipolygon to check in. :param context: geometric context. :returns: relation between multiregion and multipolygon. >>> from ground.base import Relation, get_context >>> context = get_context() >>> Contour = context.contour_cls >>> Multipolygon = context.multipolygon_cls >>> Point = context.point_cls >>> Polygon = context.polygon_cls >>> first_square = Contour([Point(0, 0), Point(4, 0), Point(4, 4), ... Point(0, 4)]) >>> second_square = Contour([Point(4, 0), Point(8, 0), Point(8, 4), ... Point(4, 4)]) >>> third_square = Contour([Point(4, 4), Point(8, 4), Point(8, 8), ... Point(4, 8)]) >>> fourth_square = Contour([Point(0, 4), Point(4, 4), Point(4, 8), ... Point(0, 8)]) >>> first_inner_square = Contour([Point(1, 1), Point(3, 1), Point(3, 3), ... Point(1, 3)]) >>> second_inner_square = Contour([Point(5, 1), Point(7, 1), Point(7, 3), ... Point(5, 3)]) >>> third_inner_square = Contour([Point(5, 5), Point(7, 5), Point(7, 7), ... Point(5, 7)]) >>> fourth_inner_square = Contour([Point(1, 5), Point(3, 5), Point(3, 7), ... Point(1, 7)]) >>> (multiregion_in_multipolygon( ... [first_square, third_square], ... Multipolygon([Polygon(second_inner_square, []), ... Polygon(fourth_inner_square, [])])) ... is multiregion_in_multipolygon( ... [first_inner_square, third_inner_square], ... Multipolygon([Polygon(second_square, [second_inner_square]), ... Polygon(fourth_square, [fourth_inner_square])])) ... is Relation.DISJOINT) True >>> (multiregion_in_multipolygon( ... [first_square, third_square], ... Multipolygon([Polygon(second_square, []), ... Polygon(fourth_square, [])])) ... is multiregion_in_multipolygon( ... [first_inner_square, third_inner_square], ... Multipolygon([Polygon(first_square, [first_inner_square]), ... Polygon(third_square, [third_inner_square])])) ... is Relation.TOUCH) True >>> (multiregion_in_multipolygon( ... [first_square, third_inner_square], ... Multipolygon([Polygon(first_inner_square, []), ... Polygon(third_square, [])])) ... is Relation.OVERLAP) True >>> (multiregion_in_multipolygon( ... [first_square, third_square], ... Multipolygon([Polygon(first_inner_square, []), ... Polygon(third_inner_square, [])])) ... is Relation.COVER) True >>> (multiregion_in_multipolygon( ... [first_square, third_inner_square], ... Multipolygon([Polygon(first_inner_square, []), ... Polygon(third_inner_square, [])])) ... is multiregion_in_multipolygon( ... [first_square, third_square], ... Multipolygon([Polygon(first_square, [first_inner_square]), ... Polygon(third_square, [third_inner_square])])) ... is Relation.ENCLOSES) True >>> (multiregion_in_multipolygon( ... [first_inner_square, second_inner_square, third_inner_square], ... Multipolygon([Polygon(first_inner_square, []), ... Polygon(third_inner_square, [])])) ... is Relation.COMPOSITE) True >>> (multiregion_in_multipolygon( ... [first_square, third_square], ... Multipolygon([Polygon(first_square, []), ... Polygon(third_square, [])])) ... is Relation.EQUAL) True >>> (multiregion_in_multipolygon( ... [first_inner_square, second_inner_square], ... Multipolygon([Polygon(first_inner_square, []), ... Polygon(second_inner_square, []), ... Polygon(third_inner_square, [])])) ... is Relation.COMPONENT) True >>> (multiregion_in_multipolygon( ... [first_inner_square, third_inner_square], ... Multipolygon([Polygon(first_square, []), ... Polygon(third_inner_square, [])])) ... is Relation.ENCLOSED) True >>> (multiregion_in_multipolygon( ... [first_inner_square, third_inner_square], ... Multipolygon([Polygon(first_square, []), ... Polygon(third_square, [])])) ... is Relation.WITHIN) True """ return _multipolygon.relate_multiregion( multipolygon, multiregion, _get_context() if context is None else context )
[docs]def polygon_in_multipolygon(polygon: _Polygon, multipolygon: _Multipolygon, *, context: _Optional[_Context] = None) -> _Relation: """ Finds relation between polygon and multipolygon. Time complexity: ``O(vertices_count * log vertices_count)`` Memory complexity: ``O(vertices_count)`` where ``vertices_count = polygon_vertices_count\ + multipolygon_vertices_count``, ``polygon_vertices_count = len(polygon.border.vertices)\ + sum(len(hole.vertices) for hole in polygon.holes)``, ``multipolygon_vertices_count = sum(len(polygon.border.vertices)\ + sum(len(hole.vertices) for hole in polygon.holes)\ for polygon in multipolygon.polygons)``. :param polygon: polygon to check for. :param multipolygon: multipolygon to check in. :param context: geometric context. :returns: relation between polygon and multipolygon. >>> from ground.base import Relation, get_context >>> context = get_context() >>> Contour = context.contour_cls >>> Multipolygon = context.multipolygon_cls >>> Point = context.point_cls >>> Polygon = context.polygon_cls >>> outer_square = Contour([Point(0, 0), Point(7, 0), Point(7, 7), ... Point(0, 7)]) >>> inner_square = Contour([Point(1, 1), Point(6, 1), Point(6, 6), ... Point(1, 6)]) >>> innermore_square = Contour([Point(2, 2), Point(5, 2), Point(5, 5), ... Point(2, 5)]) >>> innermost_square = Contour([Point(3, 3), Point(4, 3), Point(4, 4), ... Point(3, 4)]) >>> (polygon_in_multipolygon(Polygon(outer_square, [inner_square]), ... Multipolygon([Polygon(innermore_square, [])])) ... is polygon_in_multipolygon( ... Polygon(innermore_square, []), ... Multipolygon([Polygon(outer_square, [inner_square])])) ... is polygon_in_multipolygon( ... Polygon(outer_square, [inner_square]), ... Multipolygon([Polygon(innermore_square, ... [innermost_square])])) ... is polygon_in_multipolygon( ... Polygon(innermore_square, [innermost_square]), ... Multipolygon([Polygon(outer_square, [inner_square])])) ... is Relation.DISJOINT) True >>> (polygon_in_multipolygon( ... Polygon(inner_square, []), ... Multipolygon([Polygon(outer_square, [inner_square])])) ... is polygon_in_multipolygon( ... Polygon(outer_square, [inner_square]), ... Multipolygon([Polygon(inner_square, [])])) ... is polygon_in_multipolygon( ... Polygon(outer_square, [inner_square]), ... Multipolygon([Polygon(inner_square, ... [innermore_square])])) ... is polygon_in_multipolygon( ... Polygon(inner_square, [innermore_square]), ... Multipolygon([Polygon(outer_square, [inner_square])])) ... is Relation.TOUCH) True >>> (polygon_in_multipolygon( ... Polygon(inner_square, []), ... Multipolygon([Polygon(outer_square, [innermore_square])])) ... is polygon_in_multipolygon(Polygon(outer_square, [innermore_square]), ... Multipolygon([Polygon(inner_square, [])])) ... is polygon_in_multipolygon( ... Polygon(outer_square, [innermore_square]), ... Multipolygon([Polygon(inner_square, ... [innermost_square])])) ... is polygon_in_multipolygon( ... Polygon(inner_square, [innermost_square]), ... Multipolygon([Polygon(outer_square, ... [innermore_square])])) ... is Relation.OVERLAP) True >>> (polygon_in_multipolygon(Polygon(outer_square, []), ... Multipolygon([Polygon(inner_square, [])])) ... is polygon_in_multipolygon( ... Polygon(outer_square, [innermost_square]), ... Multipolygon([Polygon(inner_square, ... [innermore_square])])) ... is Relation.COVER) True >>> (polygon_in_multipolygon( ... Polygon(outer_square, []), ... Multipolygon([Polygon(outer_square, [inner_square])])) ... is polygon_in_multipolygon( ... Polygon(outer_square, [innermore_square]), ... Multipolygon([Polygon(outer_square, [inner_square])])) ... is polygon_in_multipolygon( ... Polygon(outer_square, [innermore_square]), ... Multipolygon([Polygon(inner_square, ... [innermore_square])])) ... is Relation.ENCLOSES) True >>> (polygon_in_multipolygon(Polygon(outer_square, []), ... Multipolygon([Polygon(outer_square, [])])) ... is polygon_in_multipolygon( ... Polygon(outer_square, [inner_square]), ... Multipolygon([Polygon(outer_square, [inner_square])])) ... is Relation.EQUAL) True >>> (polygon_in_multipolygon(Polygon(innermore_square, []), ... Multipolygon([Polygon(outer_square, ... [inner_square]), ... Polygon(innermore_square, [])])) ... is polygon_in_multipolygon( ... Polygon(innermore_square, [innermost_square]), ... Multipolygon([Polygon(outer_square, [inner_square]), ... Polygon(innermore_square, ... [innermost_square])])) ... is Relation.COMPONENT) True >>> (polygon_in_multipolygon(Polygon(outer_square, [inner_square]), ... Multipolygon([Polygon(outer_square, [])])) ... is polygon_in_multipolygon( ... Polygon(outer_square, [inner_square]), ... Multipolygon([Polygon(outer_square, ... [innermore_square])])) ... is polygon_in_multipolygon( ... Polygon(inner_square, [innermore_square]), ... Multipolygon([Polygon(outer_square, ... [innermore_square])])) ... is Relation.ENCLOSED) True >>> (polygon_in_multipolygon(Polygon(inner_square, []), ... Multipolygon([Polygon(outer_square, [])])) ... is polygon_in_multipolygon( ... Polygon(inner_square, [innermore_square]), ... Multipolygon([Polygon(outer_square, ... [innermost_square])])) ... is Relation.WITHIN) True """ return _multipolygon.relate_polygon( multipolygon, polygon, _get_context() if context is None else context )
[docs]def multipolygon_in_multipolygon(left: _Multipolygon, right: _Multipolygon, *, context: _Optional[_Context] = None ) -> _Relation: """ Finds relation between multipolygons. Time complexity: ``O(vertices_count * log vertices_count)`` Memory complexity: ``O(vertices_count)`` where ``vertices_count = left_vertices_count + right_vertices_count``, ``left_vertices_count = sum(len(polygon.border.vertices)\ + sum(len(hole.vertices) for hole in polygon.holes)\ for polygon in left.polygons)``, ``right_vertices_count = sum(len(polygon.border.vertices)\ + sum(len(hole.vertices) for hole in polygon.holes)\ for polygon in right.polygons)``. :param left: multipolygon to check for. :param right: multipolygon to check in. :param context: geometric context. :returns: relation between multipolygons. >>> from ground.base import Relation, get_context >>> context = get_context() >>> Contour = context.contour_cls >>> Multipolygon = context.multipolygon_cls >>> Point = context.point_cls >>> Polygon = context.polygon_cls >>> first_square = Contour([Point(0, 0), Point(4, 0), Point(4, 4), ... Point(0, 4)]) >>> second_square = Contour([Point(4, 0), Point(8, 0), Point(8, 4), ... Point(4, 4)]) >>> third_square = Contour([Point(4, 4), Point(8, 4), Point(8, 8), ... Point(4, 8)]) >>> fourth_square = Contour([Point(0, 4), Point(4, 4), Point(4, 8), ... Point(0, 8)]) >>> first_inner_square = Contour([Point(1, 1), Point(3, 1), Point(3, 3), ... Point(1, 3)]) >>> second_inner_square = Contour([Point(5, 1), Point(7, 1), Point(7, 3), ... Point(5, 3)]) >>> third_inner_square = Contour([Point(5, 5), Point(7, 5), Point(7, 7), ... Point(5, 7)]) >>> (multipolygon_in_multipolygon( ... Multipolygon([Polygon(first_inner_square, []), ... Polygon(third_inner_square, [])]), ... Multipolygon([Polygon(second_square, []), ... Polygon(fourth_square, [])])) ... is Relation.DISJOINT) True >>> (multipolygon_in_multipolygon( ... Multipolygon([Polygon(first_square, []), ... Polygon(third_square, [])]), ... Multipolygon([Polygon(second_square, []), ... Polygon(fourth_square, [])])) ... is multipolygon_in_multipolygon( ... Multipolygon([Polygon(first_inner_square, []), ... Polygon(third_inner_square, [])]), ... Multipolygon([Polygon(first_square, [first_inner_square]), ... Polygon(third_square, [third_inner_square])])) ... is Relation.TOUCH) True >>> (multipolygon_in_multipolygon( ... Multipolygon([Polygon(first_square, []), ... Polygon(third_inner_square, [])]), ... Multipolygon([Polygon(first_inner_square, []), ... Polygon(third_square, [])])) ... is Relation.OVERLAP) True >>> (multipolygon_in_multipolygon( ... Multipolygon([Polygon(first_square, []), ... Polygon(third_square, [])]), ... Multipolygon([Polygon(first_inner_square, []), ... Polygon(third_inner_square, [])])) ... is Relation.COVER) True >>> (multipolygon_in_multipolygon( ... Multipolygon([Polygon(first_square, []), ... Polygon(third_inner_square, [])]), ... Multipolygon([Polygon(first_inner_square, []), ... Polygon(third_inner_square, [])])) ... is multipolygon_in_multipolygon( ... Multipolygon([Polygon(first_square, []), ... Polygon(third_square, [])]), ... Multipolygon([Polygon(first_square, [first_inner_square]), ... Polygon(third_square, [third_inner_square])])) ... is Relation.ENCLOSES) True >>> (multipolygon_in_multipolygon( ... Multipolygon([Polygon(first_inner_square, []), ... Polygon(second_inner_square, []), ... Polygon(third_inner_square, [])]), ... Multipolygon([Polygon(first_inner_square, []), ... Polygon(third_inner_square, [])])) ... is Relation.COMPOSITE) True >>> (multipolygon_in_multipolygon( ... Multipolygon([Polygon(first_square, []), ... Polygon(third_square, [])]), ... Multipolygon([Polygon(first_square, []), ... Polygon(third_square, [])])) ... is Relation.EQUAL) True >>> (multipolygon_in_multipolygon( ... Multipolygon([Polygon(first_inner_square, []), ... Polygon(second_inner_square, [])]), ... Multipolygon([Polygon(first_inner_square, []), ... Polygon(second_inner_square, []), ... Polygon(third_inner_square, [])])) ... is Relation.COMPONENT) True >>> (multipolygon_in_multipolygon( ... Multipolygon([Polygon(first_inner_square, []), ... Polygon(third_inner_square, [])]), ... Multipolygon([Polygon(first_square, []), ... Polygon(third_inner_square, [])])) ... is Relation.ENCLOSED) True >>> (multipolygon_in_multipolygon( ... Multipolygon([Polygon(first_inner_square, []), ... Polygon(third_inner_square, [])]), ... Multipolygon([Polygon(first_square, []), ... Polygon(third_square, [])])) ... is Relation.WITHIN) True """ return _multipolygon.relate_multipolygon( right, left, _get_context() if context is None else context )