PyMuPDF 1.24.4 中文文档(十一)(2)https://developer.aliyun.com/article/1559462
几何对象的运算代数
类 Point, IRect, Rect, Quad 和 Matrix 的实例统称为“几何”对象。
它们都是 Python 序列的特例,请参阅 Using Python Sequences as Arguments in PyMuPDF 了解更多背景。
我们已经为这些类定义了运算符,可以用它们(几乎)像普通数字一样进行加法、减法、乘法、除法等操作。
本章是可能性的概要。
一般说明
- 运算符可以是二进制的(即涉及两个对象)或一元的。
- 二进制操作的结果类型可以是左操作数类的新对象或 bool。
- 一元操作的结果要么是相同类的新对象,要么是 bool,要么是 float。
- 二进制运算符 +, -, , / 对所有类都定义了。它们大致*做您所期望的事情 - 除了,第二个操作数 …
- 可能始终是一个数字,然后对第一个数字的每个组件执行操作,
- 可能始终是相同长度的数值序列(2、4 或 6) - 我们称这样的序列为
point_like
,rect_like
,quad_like
或matrix_like
。
- 矩形支持附加的二进制操作:交集(操作符 “&”)、并集(操作符 “|”)和包含检查。
- 二进制运算符完全支持原地操作,因此像
a /= b
这样的表达式如果 b 是数值或“a_like”则是有效的。
一元操作
Oper. | 结果 |
bool(OBJ) | 当 OBJ 的所有组件都为零时,为 false。 |
abs(OBJ) | 矩形区域 - 对于其他类型,等于 norm(OBJ)。 |
norm(OBJ) | 组件平方的平方根(欧几里德范数) |
+OBJ | OBJ 的新副本 |
-OBJ | 具有否定组件的 OBJ 的新副本 |
~m | 矩阵“m”的逆,如果不可逆则为零矩阵 |
二进制运算
对于每个几何对象“a”和每个数字“b”,运算 “a ° b” 和 “a °= b” 对于运算符 *+, -, , / 总是定义的。相应的操作仅对“a”的每个组件执行。如果第二个操作数不是数字,则定义如下:
Oper. | 结果 |
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”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(“b”可能是“a-like”),则True。 |
注意
请注意与通常算术的重要差异:
矩阵乘法是不可交换的,即通常情况下我们有m*n != n*m
对于两个矩阵。此外,还存在一些不可逆的非零矩阵,例如m = Matrix(1, 0, 1, 0, 1, 0)
。如果你尝试使用运算符*“/”*除以这些矩阵之一,将会收到ZeroDivisionError
异常,例如对于表达式pymupdf.Identity / m
。但如果你形式化为pymupdf.Identity * ~m
,结果将是pymupdf.Matrix()
(空矩阵)。
诚然,这代表了一种不一致性,我们正在考虑移除它。目前,您可以选择避免异常并检查~m
是否为空矩阵,或者通过使用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 in OBJ"
,其中 x 是一个数字。它被实现为"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) >>>
“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 中,我们将其视为**“乘法”(或“除法”**),其中第二个操作数可能是“类似”于矩阵。此上下文中的除法意味着“与倒置矩阵的乘法”:
>>> 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 >>>
您对此页面有何反馈?
本软件按现状提供,没有任何明示或暗示的保证。此软件根据许可分发,未经明确授权,不得复制、修改或分发。请参考 artifex.com 获取许可信息或联系美国加利福尼亚州旧金山 Mesa 街 39 号 108A 号 Artifex Software Inc. 了解更多信息。
此文档覆盖所有版本,直至 1.24.4。
一般备注
- 操作符可以是二元(即涉及两个对象)或一元。
- 二元操作的结果类型要么是左操作数类的新对象,要么是布尔值。
- 一元操作的结果要么是同类的新对象,要么是布尔值或浮点数。
- 二元运算符 *+, -, , / 对所有类别都有定义。它们 大致 做您期望的事情 – 除了第二个操作数…
- 可能始终是一个数字,然后对第一个组件的每个组件执行操作,
- 可以始终是相同长度的数字序列(2、4 或 6)– 我们分别称这些序列为
point_like
、rect_like
、quad_like
或matrix_like
。
- 矩形支持额外的二元操作:交集(操作符 “&”)、并集(操作符 “|”)和包含性检查。
- 二元操作符完全支持原地操作,因此像
a /= b
这样的表达式在 b 是数值或“类似于 a”的情况下是有效的。
一元操作
Oper. | Result |
bool(OBJ) | 如果 OBJ 的所有组件都为零,则为假 |
abs(OBJ) | 矩形面积 – 对于其他类型等于 norm(OBJ) |
norm(OBJ) | 组件平方的平方根(欧几里得范数) |
+OBJ | OBJ 的新副本 |
-OBJ | 带有反转分量的 OBJ 的新副本 |
~m | “m” 的逆矩阵,如果不可逆则为零矩阵 |
二进制运算
对于每个几何对象“a”和每个数“b”,对于运算符 +、-、、/*,操作“a ° b”和“a °= b”总是定义的。相应的操作简单地对“a”的每个分量执行。如果第二个操作数不是一个数,则定义如下:
Oper. | Result |
a+b, a-b | 分量执行,要求“b”必须类似于“a”。 |
a*m, a/m | “a” 可以是点、矩形或矩阵,但“m”必须是 matrix_like 。“a/m” 被视为 “a~m”*(有关不可逆矩阵,请参阅下面的注释)。如果“a”是点或矩形,则执行 “a.transform(m)”。如果“a”是矩阵,则进行矩阵连接。 |
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”)。 |
注意
请注意与通常算术的一个重要区别:
矩阵乘法是非交换的,即一般来说我们有 m*n != n*m
。此外,存在一些不可逆的非零矩阵,例如 m = Matrix(1, 0, 1, 0, 1, 0)
。如果尝试除以任何这些矩阵,将会收到一个使用运算符 “/” 的 ZeroDivisionError 异常,例如对于表达式 pymupdf.Identity / m
。但如果使用 pymupdf.Identity * ~m
这种形式,结果将会是 pymupdf.Matrix()
(即零矩阵)。
诚然,这代表了一种不一致性,我们正在考虑移除它。暂时,您可以选择避免异常并检查是否 ~m 是零矩阵,或者接受通过使用 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)
PyMuPDF 1.24.4 中文文档(十一)(4)https://developer.aliyun.com/article/1559464