기하 객체를 위한 연산자 대수¶
Point, IRect, Rect, Quad, Matrix 클래스의 인스턴스는 집합적으로 “geometry” 객체라고도 합니다.
모두 Python 시퀀스의 특수한 경우입니다. 자세한 내용은 에서 Python 시퀀스를 인수로 사용하기 를 참조하세요.
이 클래스들에 대해 덧셈, 뺄셈, 곱셈, 나눗셈 및 기타 연산에서 일반 숫자처럼(거의) 다룰 수 있도록 연산자를 정의했습니다.
이 장은 가능한 작업의 요약입니다.
일반적인 설명¶
연산자는 이항 (즉, 두 객체를 포함) 또는 단항 일 수 있습니다.
이항 연산의 결과 유형은 왼쪽 피연산자 클래스의 새 객체, bool 또는(내적의 경우) float입니다.
단항 연산의 결과는 동일한 클래스의 새 객체, bool 또는 float입니다.
이항 연산자
+, -, *, /는 모든 클래스에 대해 정의됩니다. 대략 예상대로 동작합니다 – 단, 두 번째 피연산자는 …항상 숫자일 수 있으며, 그러면 첫 번째 피연산자의 모든 구성 요소에 대해 연산을 수행합니다,
항상 동일한 길이(2, 4 또는 6)의 숫자 시퀀스일 수 있습니다 – 이러한 시퀀스를 각각
point_like,rect_like,quad_like또는matrix_like라고 합니다.
사각형은 추가 이항 연산을 지원합니다: 교집합 (연산자
"&"), 합집합 (연산자"|") 및 포함 확인.이항 연산자는 제자리 연산을 완전히 지원합니다. 따라서 “°”가 이항 연산자이면 표현식
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 == b 및 b in a 형식의 표현식입니다.
“b”가 숫자이면 각 구성 요소에 대해 해당 연산이 실행됩니다. 그렇지 않고 “b”가 숫자가 아니면 다음이 발생합니다:
연산 |
결과 |
|---|---|
a+b, a-b |
구성 요소별 실행, “b”는 “a-like”여야 합니다. |
a*m, a/m |
“a”는 점, 사각형 또는 행렬일 수 있으며 “m”은 |
a*b |
점 “a”와 점과 유사한 “b”에 대한 벡터 내적 을 반환합니다. |
a&b |
교집합 사각형: “a”는 사각형이어야 하며 “b”는 |
a|b |
합집합 사각형: “a”는 사각형이어야 하며 “b”는 |
b in a |
“b”가 숫자이면 |
a == b |
bool(a-b) 가 |
참고
일반적인 산술과의 중요한 차이점을 참고하세요:
행렬 곱셈은 가환적이지 않습니다. 즉, 일반적으로 두 행렬에 대해 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)
>>>
다음은 두 점 p1 과 p2 를 연결하는 선의 중점 을 제공합니다:
>>> 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
>>>
