Example #1
0
def segment_squared_distance(
        box: Box, segment: Segment,
        dot_producer: QuaternaryPointFunction[Scalar],
        segments_collision_detector: QuaternaryPointFunction[bool],
        point_cls: Type[Point]) -> Scalar:
    segment_start, segment_end = segment.start, segment.end
    min_x, min_y, max_x, max_y = (rationalize(box.min_x), rationalize(
        box.min_y), rationalize(box.max_x), rationalize(box.max_y))
    return (
        0 if
        ((min_x <= segment_start.x <= max_x
          and min_y <= segment_start.y <= max_y) or
         (min_x <= segment_end.x <= max_x and min_y <= segment_end.y <= max_y))
        else
        ((segment_point_squared_distance(segment_start, segment_end,
                                         point_cls(min_x, min_y), dot_producer)
          if min_y == max_y else segment_segment_squared_distance(
              segment_start, segment_end, point_cls(min_x, min_y),
              point_cls(min_x, max_y), dot_producer,
              segments_collision_detector)) if min_x == max_x else
         (segment_segment_squared_distance(
             segment_start, segment_end, point_cls(min_x, min_y),
             point_cls(max_x, min_y), dot_producer, segments_collision_detector
         ) if min_y == max_y else _non_degenerate_segment_squared_distance(
             max_x, max_y, min_x, min_y, segment_start, segment_end,
             dot_producer, segments_collision_detector, point_cls))))
Example #2
0
def centroid(multipoint: Multipoint,
             point_cls: Type[Point],
             inverse: Callable[[int], Fraction] = Fraction(1).__truediv__
             ) -> Point:
    result_x = result_y = 0
    for point in multipoint.points:
        result_x += rationalize(point.x)
        result_y += rationalize(point.y)
    inverted_points_count = inverse(len(multipoint.points))
    return point_cls(result_x * inverted_points_count,
                     result_y * inverted_points_count)
Example #3
0
def signed_area(contour: Contour[Scalar],
                *,
                _half: Fraction = Fraction(1, 2)) -> Scalar:
    vertices = contour.vertices
    result, vertex = 0, vertices[-1]
    vertex_x, vertex_y = rationalize(vertex.x), rationalize(vertex.y)
    for next_vertex in vertices:
        next_vertex_x, next_vertex_y = (rationalize(next_vertex.x),
                                        rationalize(next_vertex.y))
        result += vertex_x * next_vertex_y - next_vertex_x * vertex_y
        vertex_x, vertex_y = next_vertex_x, next_vertex_y
    return _half * result
Example #4
0
def centroid_components(
        vertices: Sequence[Point]) -> Tuple[Scalar, Scalar, Scalar]:
    double_area = x_numerator = y_numerator = 0
    prev_vertex = vertices[-1]
    prev_x, prev_y = rationalize(prev_vertex.x), rationalize(prev_vertex.y)
    for vertex in vertices:
        x, y = rationalize(vertex.x), rationalize(vertex.y)
        area_component = prev_x * y - prev_y * x
        double_area += area_component
        x_numerator += (prev_x + x) * area_component
        y_numerator += (prev_y + y) * area_component
        prev_x, prev_y = x, y
    return x_numerator, y_numerator, double_area
Example #5
0
def centroid(multisegment: Multisegment, point_cls: Type[Point],
             sqrt: Callable[[Scalar], Scalar]) -> Point:
    accumulated_x = accumulated_y = accumulated_length = 0
    for segment in multisegment.segments:
        start, end = segment.start, segment.end
        start_x, start_y = rationalize(start.x), rationalize(start.y)
        end_x, end_y = rationalize(end.x), rationalize(end.y)
        length = sqrt((end_x - start_x)**2 + (end_y - start_y)**2)
        accumulated_x += (start_x + end_x) * length
        accumulated_y += (start_y + end_y) * length
        accumulated_length += length
    inverted_divisor = 1 / (2 * accumulated_length)
    return point_cls(accumulated_x * inverted_divisor,
                     accumulated_y * inverted_divisor)
Example #6
0
def multiply(first_start: Point,
             first_end: Point,
             second_start: Point,
             second_end: Point) -> Scalar:
    return ((rationalize(first_end.x) - rationalize(first_start.x))
            * (rationalize(second_end.x) - rationalize(second_start.x))
            + (rationalize(first_end.y) - rationalize(first_start.y))
            * (rationalize(second_end.y) - rationalize(second_start.y)))
Example #7
0
def centroid(contour: Contour, point_cls: Type[Point],
             sqrt: Callable[[Scalar], Scalar]) -> Point:
    vertices = contour.vertices
    accumulated_x = accumulated_y = accumulated_length = 0
    vertex = vertices[-1]
    start_x, start_y = rationalize(vertex.x), rationalize(vertex.y)
    for vertex in vertices:
        end_x, end_y = rationalize(vertex.x), rationalize(vertex.y)
        length = sqrt((end_x - start_x)**2 + (end_y - start_y)**2)
        accumulated_x += (start_x + end_x) * length
        accumulated_y += (start_y + end_y) * length
        accumulated_length += length
        start_x, start_y = end_x, end_y
    inverted_divisor = 1 / (2 * accumulated_length)
    return point_cls(accumulated_x * inverted_divisor,
                     accumulated_y * inverted_divisor)
Example #8
0
def rotate_translate_point(point: Point, cosine: Scalar, sine: Scalar,
                           step_x: Scalar, step_y: Scalar,
                           point_cls: Type[Point]) -> Point:
    x, y = rationalize(point.x), rationalize(point.y)
    cosine, sine = rationalize(cosine), rationalize(sine)
    return point_cls(cosine * x - sine * y + rationalize(step_x),
                     sine * x + cosine * y + rationalize(step_y))
Example #9
0
def test(point: Point, first: Point, second: Point, third: Point) -> Scalar:
    point_x, point_y = rationalize(point.x), rationalize(point.y)
    first_dx, first_dy = (rationalize(first.x) - point_x,
                          rationalize(first.y) - point_y)
    second_dx, second_dy = (rationalize(second.x) - point_x,
                            rationalize(second.y) - point_y)
    third_dx, third_dy = (rationalize(third.x) - point_x,
                          rationalize(third.y) - point_y)
    return Location(1 +
                    to_sign((first_dx * first_dx + first_dy * first_dy) *
                            (second_dx * third_dy - second_dy * third_dx) -
                            (second_dx * second_dx + second_dy * second_dy) *
                            (first_dx * third_dy - first_dy * third_dx) +
                            (third_dx * third_dx + third_dy * third_dy) *
                            (first_dx * second_dy - first_dy * second_dx)))
Example #10
0
def point_squared_distance(segment_start: Point,
                           segment_end: Point,
                           point: Point,
                           dot_producer: QuaternaryPointFunction[Scalar]
                           ) -> Scalar:
    end_factor = max(0, min(1,
                            dot_producer(segment_start, point, segment_start,
                                         segment_end)
                            / point_point_squared_distance(segment_start,
                                                           segment_end)))
    start_factor = 1 - end_factor
    return ((start_factor * rationalize(segment_start.x)
             + end_factor * rationalize(segment_end.x)
             - rationalize(point.x)) ** 2
            + (start_factor * rationalize(segment_start.y)
               + end_factor * rationalize(segment_end.y)
               - rationalize(point.y)) ** 2)
Example #11
0
def translate_point(point: Point, step_x: Scalar, step_y: Scalar,
                    point_cls: Type[Point]) -> Point:
    return point_cls(
        rationalize(point.x) + rationalize(step_x),
        rationalize(point.y) + rationalize(step_y))
Example #12
0
def point_squared_distance(box: Box, point: Point) -> Scalar:
    return (_linear_interval_distance(rationalize(
        box.min_x), rationalize(box.max_x), rationalize(point.x))**2 +
            _linear_interval_distance(rationalize(
                box.min_y), rationalize(box.max_y), rationalize(point.y))**2)
Example #13
0
def scale_point(point: Point, factor_x: Scalar, factor_y: Scalar,
                point_cls: Type[Point]) -> Point:
    return point_cls(
        rationalize(point.x) * rationalize(factor_x),
        rationalize(point.y) * rationalize(factor_y))
Example #14
0
def centroid(segment: Segment, point_cls: Type[Point]) -> Point:
    return point_cls(
        (rationalize(segment.start.x) + rationalize(segment.end.x)) / 2,
        (rationalize(segment.start.y) + rationalize(segment.end.y)) / 2)
Example #15
0
def rotate_point_around_origin(point: Point, cosine: Scalar, sine: Scalar,
                               point_cls: Type[Point]) -> Point:
    cosine, sine = rationalize(cosine), rationalize(sine)
    x, y = rationalize(point.x), rationalize(point.y)
    return point_cls(cosine * x - sine * y, sine * x + cosine * y)
Example #16
0
def point_to_step(point: Point, cosine: Scalar,
                  sine: Scalar) -> Tuple[Scalar, Scalar]:
    x, y = rationalize(point.x), rationalize(point.y)
    cosine, sine = rationalize(cosine), rationalize(sine)
    return x - (cosine * x - sine * y), y - (sine * x + cosine * y)