Ejemplo n.º 1
0
def _linear_interval_distance(min_coordinate: Scalar,
                              max_coordinate: Scalar,
                              coordinate: Scalar) -> Expansion:
    return (Expansion(min_coordinate, -coordinate)
            if coordinate < min_coordinate
            else (Expansion(coordinate, -max_coordinate)
                  if coordinate > max_coordinate
                  else Expansion()))
Ejemplo n.º 2
0
def signed_area(contour: Contour[Scalar], *,
                _half: Fraction = Fraction(1, 2)) -> Scalar:
    vertices = contour.vertices
    result, vertex = Expansion(), vertices[-1]
    for next_vertex in vertices:
        result = result + to_cross_product(vertex.x, vertex.y, next_vertex.x,
                                           next_vertex.y)
        vertex = next_vertex
    return result * _half
Ejemplo n.º 3
0
def centroid(
        multipoint: Multipoint,
        point_cls: Type[Point],
        inverse: Callable[[int], Fraction] = Fraction(1).__truediv__) -> Point:
    result_x = result_y = Expansion()
    for point in multipoint.points:
        result_x += point.x
        result_y += point.y
    inverted_points_count = inverse(len(multipoint.points))
    return point_cls(result_x * inverted_points_count,
                     result_y * inverted_points_count)
Ejemplo n.º 4
0
def centroid_components(
        vertices: Sequence[Point]) -> Tuple[Expansion, Expansion, Expansion]:
    double_area = x_numerator = y_numerator = Expansion()
    prev = vertices[-1]
    prev_x, prev_y = prev.x, prev.y
    for vertex in vertices:
        x, y = vertex.x, vertex.y
        area_component = to_cross_product(prev_x, prev_y, x, y)
        double_area = double_area + area_component
        x_numerator = x_numerator + area_component * (prev_x + x)
        y_numerator = y_numerator + area_component * (prev_y + y)
        prev_x, prev_y = x, y
    return x_numerator, y_numerator, double_area
Ejemplo n.º 5
0
def centroid(multisegment: Multisegment, point_cls: Type[Point],
             sqrt: Callable[[Scalar], Scalar]) -> Point:
    accumulated_x = accumulated_y = accumulated_length = Expansion()
    for segment in multisegment.segments:
        start, end = segment.start, segment.end
        length = sqrt(
            to_squared_points_distance(end.x, end.y, start.x, start.y))
        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)
Ejemplo n.º 6
0
def point_squared_distance(
        start: Point, end: Point, point: Point,
        dot_producer: QuaternaryPointFunction[Scalar]) -> Scalar:
    segment_squared_norm = dot_producer(start, end, start, end)
    point_end_projection = dot_producer(point, end, start, end)
    start_point_projection = dot_producer(start, point, start, end)
    start_factor = ((point_end_projection if point_end_projection > 0 else 0)
                    if point_end_projection < segment_squared_norm else
                    segment_squared_norm)
    end_factor = ((start_point_projection if start_point_projection > 0 else 0)
                  if start_point_projection < segment_squared_norm else
                  segment_squared_norm)
    return ((square(segment_squared_norm * Expansion(start.x, -point.x) +
                    end_factor * Expansion(end.x, -start.x)) +
             square(segment_squared_norm * Expansion(start.y, -point.y) +
                    end_factor * Expansion(end.y, -start.y)) if
             (abs(segment_squared_norm -
                  end_factor) < abs(segment_squared_norm - start_factor)) else
             (square(segment_squared_norm * Expansion(end.x, -point.x) +
                     start_factor * Expansion(start.x, -end.x)) +
              square(segment_squared_norm * Expansion(end.y, -point.y) +
                     start_factor * Expansion(start.y, -end.y)))) /
            square(segment_squared_norm))
Ejemplo n.º 7
0
def centroid(segment: Segment, point_cls: Type[Point]) -> Point:
    return point_cls(Expansion(segment.start.x, segment.end.x) / 2,
                     Expansion(segment.start.y, segment.end.y) / 2)
Ejemplo n.º 8
0
def scale_point(point: Point, factor_x: Scalar, factor_y: Scalar,
                point_cls: Type[Point]) -> Point:
    return point_cls(
        Expansion(point.x) * factor_x,
        Expansion(point.y) * factor_y)
Ejemplo n.º 9
0
def translate_point(point: Point, step_x: Scalar, step_y: Scalar,
                    point_cls: Type[Point]) -> Point:
    return point_cls(Expansion(point.x) + step_x, Expansion(point.y) + step_y)
Ejemplo n.º 10
0
def to_cross_product(first_x: Scalar, first_y: Scalar, second_x: Scalar,
                     second_y: Scalar) -> Expansion:
    """
    Returns expansion of vectors' cross product.
    """
    return Expansion(first_x) * second_y - Expansion(second_x) * first_y
Ejemplo n.º 11
0
def to_squared_points_distance(first_x: Scalar, first_y: Scalar,
                               second_x: Scalar,
                               second_y: Scalar) -> Expansion:
    return (square(Expansion(first_x, -second_x)) +
            square(Expansion(first_y, -second_y)))
Ejemplo n.º 12
0
def rotate_point_around_origin(point: Point, cosine: Scalar, sine: Scalar,
                               point_cls: Type[Point]) -> Point:
    cosine, sine = Expansion(cosine), Expansion(sine)
    return point_cls(cosine * point.x - sine * point.y,
                     sine * point.x + cosine * point.y)
Ejemplo n.º 13
0
def point_to_step(point: Point, cosine: Scalar,
                  sine: Scalar) -> Tuple[Scalar, Scalar]:
    cosine, sine = Expansion(cosine), Expansion(sine)
    return (point.x - (cosine * point.x - sine * point.y),
            point.y - (sine * point.x + cosine * point.y))
Ejemplo n.º 14
0
def rotate_translate_point(point: Point, cosine: Scalar, sine: Scalar,
                           step_x: Scalar, step_y: Scalar,
                           point_cls: Type[Point]) -> Point:
    cosine, sine = Expansion(cosine), Expansion(sine)
    return point_cls(cosine * point.x - sine * point.y + step_x,
                     sine * point.x + cosine * point.y + step_y)