def centroid( contour: Contour, point_cls: Type[Point], third: Fraction = Fraction(1, 3)) -> Point: x_numerator, y_numerator, double_area = centroid_components( contour.vertices) inverted_denominator = third / double_area return point_cls(x_numerator * inverted_denominator, y_numerator * inverted_denominator)
def signed_area(contour: Contour[Scalar], *, _half: Fraction = Fraction(1, 2)) -> Scalar: vertices = contour.vertices result, vertex = 0, vertices[-1] for next_vertex in vertices: result += vertex.x * next_vertex.y - next_vertex.x * vertex.y vertex = next_vertex return _half * result
def centroid( polygon: Polygon, point_cls: Type[Point], third: Fraction = Fraction(1, 3)) -> Point: x_numerator, y_numerator, double_area = centroid_components( polygon.border, polygon.holes) inverted_denominator = third / double_area return point_cls(x_numerator * inverted_denominator, y_numerator * inverted_denominator)
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
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 += 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)
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
def point_squared_distance( start: Point, end: Point, point: Point, dot_producer: QuaternaryPointFunction[Scalar], inverse: Callable[[Scalar], Scalar] = Fraction(1).__truediv__) -> Scalar: end_factor = max( 0, min( 1, dot_producer(start, point, start, end) * inverse(point_point_squared_distance(start, end)))) start_factor = 1 - end_factor return ((start_factor * start.x + end_factor * end.x - point.x)**2 + (start_factor * start.y + end_factor * end.y - point.y)**2)
def rationalize(value: Scalar) -> Scalar: try: return Fraction(value) except TypeError: return value
def perfect_sqrt(self) -> Expression: return Finite( Fraction(perfect_sqrt(self.value.numerator), perfect_sqrt(self.value.denominator)))
def inverse(self) -> 'Finite': return Finite(Fraction(self.value.denominator, self.value.numerator))
def __init__(self, value: Real = 0) -> None: self._value = Fraction(value)
class Finite(Constant): """Represents rational number.""" is_finite = True __slots__ = '_value', def __init__(self, value: Real = 0) -> None: self._value = Fraction(value) @property def value(self) -> Rational: return self._value def evaluate(self, sqrt_evaluator: Optional[SqrtEvaluator] = None) -> Real: return self.value def extract_common_denominator(self) -> Tuple[int, 'Finite']: return self.value.denominator, Finite(self.value.numerator) def extract_common_numerator(self) -> Tuple[int, 'Finite']: return self.value.numerator, One / self.value.denominator def inverse(self) -> 'Finite': return Finite(Fraction(self.value.denominator, self.value.numerator)) def is_positive(self) -> bool: return self.value > 0 def perfect_sqrt(self) -> Expression: return Finite( Fraction(perfect_sqrt(self.value.numerator), perfect_sqrt(self.value.denominator))) def significant_digits_count(self) -> int: return digits_count(self._value.limit_denominator(1).numerator) def square(self) -> 'Finite': return Finite(square(self.value)) def __add__(self, other: Union[Real, 'Finite']) -> 'Finite': other = to_expression(other) return ((Finite(self.value + other.value) if isinstance(other, Finite) else other.__radd__(self)) if isinstance(other, Expression) else NotImplemented) def __bool__(self) -> bool: return bool(self.value) def __mul__(self, other: Union[Real, 'Finite']) -> 'Finite': other = to_expression(other) return ((Finite(self.value * other.value) if isinstance(other, Finite) else other.__rmul__(self)) if isinstance(other, Expression) else NotImplemented) def __neg__(self) -> 'Finite': return Finite(-self.value) def __radd__(self, other: Union[Real, 'Finite']) -> 'Finite': return (to_expression(other) + self if isinstance(other, Real) else NotImplemented) __repr__ = generate_repr(__init__) def __rmul__(self, other: Union[Real, 'Finite']) -> 'Finite': return (to_expression(other) * self if isinstance(other, Real) else NotImplemented)
def centroid(segment: Segment, point_cls: Type[Point], *, _half: Fraction = Fraction(1, 2)) -> Point: return point_cls(_half * (segment.start.x + segment.end.x), _half * (segment.start.y + segment.end.y))