기하 객체를 위한 연산자 대수

Point, IRect, Rect, Quad, Matrix 클래스의 인스턴스는 집합적으로 “geometry” 객체라고도 합니다.

모두 Python 시퀀스의 특수한 경우입니다. 자세한 내용은 에서 Python 시퀀스를 인수로 사용하기 를 참조하세요.

이 클래스들에 대해 덧셈, 뺄셈, 곱셈, 나눗셈 및 기타 연산에서 일반 숫자처럼(거의) 다룰 수 있도록 연산자를 정의했습니다.

이 장은 가능한 작업의 요약입니다.

일반적인 설명

  1. 연산자는 이항 (즉, 두 객체를 포함) 또는 단항 일 수 있습니다.

  2. 이항 연산의 결과 유형은 왼쪽 피연산자 클래스의 새 객체, bool 또는(내적의 경우) float입니다.

  3. 단항 연산의 결과는 동일한 클래스의 새 객체, bool 또는 float입니다.

  4. 이항 연산자 +, -, *, / 는 모든 클래스에 대해 정의됩니다. 대략 예상대로 동작합니다 – 단, 두 번째 피연산자는 …

    • 항상 숫자일 수 있으며, 그러면 첫 번째 피연산자의 모든 구성 요소에 대해 연산을 수행합니다,

    • 항상 동일한 길이(2, 4 또는 6)의 숫자 시퀀스일 수 있습니다 – 이러한 시퀀스를 각각 point_like, rect_like, quad_like 또는 matrix_like 라고 합니다.

  5. 사각형은 추가 이항 연산을 지원합니다: 교집합 (연산자 "&"), 합집합 (연산자 "|") 및 포함 확인.

  6. 이항 연산자는 제자리 연산을 완전히 지원합니다. 따라서 “°”가 이항 연산자이면 표현식 a °= b 는 항상 유효하며 a = a ° b 와 동일합니다. 따라서 두 점에 대해 p1 *= p2하지 마세요. 그 후 “p1”은 float 가 됩니다.

단항 연산

연산

결과

bool(OBJ)

OBJ의 모든 구성 요소가 0인 경우에만 false

abs(OBJ)

사각형 영역 – 다른 유형의 경우 norm(OBJ)와 동일

norm(OBJ)

구성 요소 제곱의 제곱근(유클리드 노름)

+OBJ

OBJ의 새 복사본

-OBJ

부정된 구성 요소를 가진 OBJ의 새 복사본

~m

행렬 “m”의 역행렬, 또는 역행렬이 없으면 null 행렬

이항 연산

이것들은 “°”가 연산자 +, -, *, / 중 하나인 a ° b 와 같은 표현식입니다. 또한 이항 연산은 a == bb in a 형식의 표현식입니다.

“b”가 숫자이면 각 구성 요소에 대해 해당 연산이 실행됩니다. 그렇지 않고 “b”가 숫자가 아니면 다음이 발생합니다:

연산

결과

a+b, a-b

구성 요소별 실행, “b”는 “a-like”여야 합니다.

a*m, a/m

“a”는 점, 사각형 또는 행렬일 수 있으며 “m”은 matrix_like 입니다. “a/m”“a*~m” 로 처리됩니다(역행렬이 없는 행렬에 대한 참고 사항은 아래 참조). “a”가 또는 사각형 이면 “a.transform(m)” 이 실행됩니다. “a”가 행렬이면 행렬 연결이 수행됩니다.

a*b

점 “a”와 점과 유사한 “b”에 대한 벡터 내적 을 반환합니다.

a&b

교집합 사각형: “a”는 사각형이어야 하며 “b”는 rect_like 여야 합니다. 두 피연산자에 모두 포함된 가장 큰 사각형 을 제공합니다.

a|b

합집합 사각형: “a”는 사각형이어야 하며 “b”는 point_like 또는 rect_like 일 수 있습니다. 두 피연산자를 모두 포함하는 가장 작은 사각형 을 제공합니다.

b in a

“b”가 숫자이면 b in tuple(a) 가 반환됩니다. “b”가 point_like, rect_like 또는 quad_like 이면 “a”는 사각형이어야 하며 a.contains(b) 가 반환됩니다.

a == b

bool(a-b)False 이면 True (“b”는 “a-like”일 수 있음).

참고

일반적인 산술과의 중요한 차이점을 참고하세요:

행렬 곱셈은 가환적이지 않습니다. 즉, 일반적으로 두 행렬에 대해 m*n != n*m 입니다. 또한 역행렬이 없는 0이 아닌 행렬도 있습니다. 예를 들어 m = Matrix(1, 0, 1, 0, 1, 0) 입니다. 이것들 중 하나로 나누려고 하면 연산자 “/” 를 사용하여 ZeroDivisionError 예외를 받게 됩니다. 예를 들어 표현식 pymupdf.Identity / m 의 경우입니다. 하지만 pymupdf.Identity * ~m 으로 작성하면 결과는 pymupdf.Matrix() (null 행렬)가 됩니다.

인정하건대, 이것은 불일치를 나타내며, 우리는 이를 제거하는 것을 고려하고 있습니다. 당분간 예외를 피하고 ~m이 null 행렬인지 확인하거나, pymupdf.Identity / m 을 사용하여 잠재적인 ZeroDivisionError 를 받아들일 수 있습니다.

참고

  • 이러한 규칙으로 모든 일반적인 대수 규칙이 적용됩니다. 예를 들어, 괄호를 임의로 사용하는 것**(동일한 클래스의 객체 중에서!)** 이 가능합니다: r1, r2가 사각형이고 m1, m2가 행렬이면 (r1 + r2) * m1 * m2 를 수행할 수 있습니다.

  • 동일한 클래스의 모든 객체에 대해 a + b + c == (a + b) + c == a + (b + c) 가 참입니다.

  • 행렬의 경우 다음이 참입니다: (m1 + m2) * m3 == m1 * m3 + m2 * m3 (분배 법칙).

  • 하지만 행렬을 적용하는 순서가 중요합니다: r이 사각형이고 m1, m2가 행렬이면 – 주의!:
    • r * m1 * m2 == (r * m1) * m2 != r * (m1 * m2)

일부 예제

숫자로 조작

일반적인 산술 연산의 경우 숫자는 항상 두 번째 피연산자로 허용됩니다. 또한 x가 숫자인 경우 "x in OBJ" 를 작성할 수 있습니다. 이것은 "x in tuple(OBJ)" 로 구현됩니다:

>>> pymupdf.Rect(1, 2, 3, 4) + 5
pymupdf.Rect(6.0, 7.0, 8.0, 9.0)
>>> 3 in pymupdf.Rect(1, 2, 3, 4)
True
>>>

다음은 문서 페이지 사각형의 왼쪽 위 사분면을 생성합니다:

>>> page.rect
Rect(0.0, 0.0, 595.0, 842.0)
>>> page.rect / 2
Rect(0.0, 0.0, 297.5, 421.0)
>>>

다음은 두 점 p1p2 를 연결하는 선의 중점 을 제공합니다:

>>> p1 = pymupdf.Point(1, 2)
>>> p2 = pymupdf.Point(4711, 3141)
>>> mp = (p1 + p2) / 2
>>> mp
Point(2356.0, 1571.5)
>>>

두 점의 벡터 내적 을 계산합니다. 각도의 코사인 을 계산하고 직교성을 확인할 수 있습니다.

>>> p1 = pymupdf.Point(1, 0)
>>> p2 = pymupdf.Point(1, 1)
>>> dot = p1 * p2
>>> dot
1.0
>>> # compute the cosine of the angle between p1 and p2:
>>> cosine = dot / (abs(p1) * abs(p2))
>>> cosine  # cosine of 45 degrees
0.7071067811865475
>>> math.cos(mat.radians(45))  # verify:
0.7071067811865476
>>> # check orhogonality
>>> p3 = pymupdf.Point(0, 1)
>>> # p1 and p3 are orthogonal so, as expected:
>>> p1 * p3
0.0

“like” 객체로 조작

이항 연산의 두 번째 피연산자는 항상 왼쪽 피연산자와 “like”일 수 있습니다. 이 맥락에서 “Like”는 “동일한 길이의 숫자 시퀀스”를 의미합니다. 위의 예제와 함께:

>>> p1 + p2
Point(4712.0, 3143.0)
>>> p1 + (4711, 3141)
Point(4712.0, 3143.0)
>>> p1 += (4711, 3141)
>>> p1
Point(4712.0, 3143.0)
>>>

사각형을 오른쪽으로 5픽셀 이동하려면 다음을 수행하세요:

>>> pymupdf.Rect(100, 100, 200, 200) + (5, 0, 5, 0)  # add 5 to the x coordinates
Rect(105.0, 100.0, 205.0, 200.0)
>>>

점, 사각형 및 행렬은 행렬로 변환 될 수 있습니다. PyMuPDF에서는 이를 “곱셈” (또는 각각 “나눗셈” )처럼 취급하며, 두 번째 피연산자는 행렬과 “like”일 수 있습니다. 이 맥락에서 나눗셈은 “역행렬과의 곱셈”을 의미합니다:

>>> m = pymupdf.Matrix(1, 2, 3, 4, 5, 6)
>>> n = pymupdf.Matrix(6, 5, 4, 3, 2, 1)
>>> p = pymupdf.Point(1, 2)
>>> p * m
Point(12.0, 16.0)
>>> p * (1, 2, 3, 4, 5, 6)
Point(12.0, 16.0)
>>> p / m
Point(2.0, -2.0)
>>> p / (1, 2, 3, 4, 5, 6)
Point(2.0, -2.0)
>>>
>>> m * n  # matrix multiplication
Matrix(14.0, 11.0, 34.0, 27.0, 56.0, 44.0)
>>> m / n  # matrix division
Matrix(2.5, -3.5, 3.5, -4.5, 5.5, -7.5)
>>>
>>> m / m  # result is equal to the Identity matrix
Matrix(1.0, 0.0, 0.0, 1.0, 0.0, 0.0)
>>>
>>> # look at this non-invertible matrix:
>>> m = pymupdf.Matrix(1, 0, 1, 0, 1, 0)
>>> ~m
Matrix(0.0, 0.0, 0.0, 0.0, 0.0, 0.0)
>>> # we try dividing by it in two ways:
>>> p = pymupdf.Point(1, 2)
>>> p * ~m  # this delivers point (0, 0):
Point(0.0, 0.0)
>>> p / m  # but this is an exception:
Traceback (most recent call last):
  File "<pyshell#6>", line 1, in <module>
    p / m
  File "... /site-packages/fitz/pymupdf.py", line 869, in __truediv__
    raise ZeroDivisionError("matrix not invertible")
ZeroDivisionError: matrix not invertible
>>>

특수 기능으로, 사각형은 추가 이항 연산을 지원합니다:

  • 교집합 – 사각형과 유사한 것들의 공통 영역, 연산자 “&”

  • 포함 – 점과 유사하거나 사각형과 유사한 것을 포함하도록 확대, 연산자 “|”

  • 포함 확인 – 점과 유사하거나 사각형과 유사한 것이 내부에 있는지 여부

주어진 점을 둘러싸는 가장 작은 사각형을 만드는 예제입니다:

>>> # first define some point-likes
>>> points = []
>>> for i in range(10):
        for j in range(10):
            points.append((i, j))
>>>
>>> # now create a rectangle containing all these 100 points
>>> # start with an empty rectangle
>>> r = pymupdf.Rect(points[0], points[0])
>>> for p in points[1:]:  # and include remaining points one by one
        r |= p
>>> r  # here is the to be expected result:
Rect(0.0, 0.0, 9.0, 9.0)
>>> (4, 5) in r  # this point-like lies inside the rectangle
True
>>> # and this rect-like is also inside
>>> (4, 4, 5, 5) in r
True
>>>

This software is provided AS-IS with no warranty, either express or implied. This software is distributed under license and may not be copied, modified or distributed except as expressly authorized under the terms of that license. Refer to licensing information at artifex.com or contact Artifex Software Inc., 39 Mesa Street, Suite 108A, San Francisco CA 94129, United States for further information.