几何学¶
介绍¶
SymPy 的几何模块允许用户创建二维几何实体,如线和圆,并查询这些实体的信息。这可能包括询问椭圆的面积、检查一组点是否共线,或找到两条线的交点。该模块的主要用途涉及具有数值的实体,但也可以使用符号表示。
可用实体¶
以下实体目前在几何模块中可用:
大多数工作将通过这些实体的属性和方法来完成,但存在几种全局方法:
intersection(entity1, entity2)
are_similar(entity1, entity2)
convex_hull(points)
如需查看完整的API列表以及方法及其返回值的说明,请参阅本文档末尾的类列表。
示例用法¶
以下Python会话展示了如何使用几何模块中的一些功能。
>>> from sympy import *
>>> from sympy.geometry import *
>>> x = Point(0, 0)
>>> y = Point(1, 1)
>>> z = Point(2, 2)
>>> zp = Point(1, 0)
>>> Point.is_collinear(x, y, z)
True
>>> Point.is_collinear(x, y, zp)
False
>>> t = Triangle(zp, y, x)
>>> t.area
1/2
>>> t.medians[x]
Segment2D(Point2D(0, 0), Point2D(1, 1/2))
>>> m = t.medians
>>> intersection(m[x], m[y], m[zp])
[Point2D(2/3, 1/3)]
>>> c = Circle(x, 5)
>>> l = Line(Point(5, -5), Point(5, 5))
>>> c.is_tangent(l) # is l tangent to c?
True
>>> l = Line(x, y)
>>> c.is_tangent(l) # is l tangent to c?
False
>>> intersection(c, l)
[Point2D(-5*sqrt(2)/2, -5*sqrt(2)/2), Point2D(5*sqrt(2)/2, 5*sqrt(2)/2)]
中线的交点¶
>>> from sympy import symbols
>>> from sympy.geometry import Point, Triangle, intersection
>>> a, b = symbols("a,b", positive=True)
>>> x = Point(0, 0)
>>> y = Point(a, 0)
>>> z = Point(2*a, b)
>>> t = Triangle(x, y, z)
>>> t.area
a*b/2
>>> t.medians[x]
Segment2D(Point2D(0, 0), Point2D(3*a/2, b/2))
>>> intersection(t.medians[x], t.medians[y], t.medians[z])
[Point2D(a, b/3)]
深入的例子:帕普斯六边形定理¶
来自维基百科([WikiPappus]):
给定一组共线点 \(A\), \(B\), \(C\),以及另一组共线点 \(a\), \(b\), \(c\),那么直线对 \(Ab\) 和 \(aB\)、\(Ac\) 和 \(aC\)、\(Bc\) 和 \(bC\) 的交点 \(X\), \(Y\), \(Z\) 是共线的。
>>> from sympy import *
>>> from sympy.geometry import *
>>>
>>> l1 = Line(Point(0, 0), Point(5, 6))
>>> l2 = Line(Point(0, 0), Point(2, -2))
>>>
>>> def subs_point(l, val):
... """Take an arbitrary point and make it a fixed point."""
... t = Symbol('t', real=True)
... ap = l.arbitrary_point()
... return Point(ap.x.subs(t, val), ap.y.subs(t, val))
...
>>> p11 = subs_point(l1, 5)
>>> p12 = subs_point(l1, 6)
>>> p13 = subs_point(l1, 11)
>>>
>>> p21 = subs_point(l2, -1)
>>> p22 = subs_point(l2, 2)
>>> p23 = subs_point(l2, 13)
>>>
>>> ll1 = Line(p11, p22)
>>> ll2 = Line(p11, p23)
>>> ll3 = Line(p12, p21)
>>> ll4 = Line(p12, p23)
>>> ll5 = Line(p13, p21)
>>> ll6 = Line(p13, p22)
>>>
>>> pp1 = intersection(ll1, ll3)[0]
>>> pp2 = intersection(ll2, ll5)[0]
>>> pp3 = intersection(ll4, ll6)[0]
>>>
>>> Point.is_collinear(pp1, pp2, pp3)
True
参考文献¶
“帕普斯六边形定理” 维基百科,自由的百科全书。网络。2013年4月26日。<https://en.wikipedia.org/wiki/Pappus’s_hexagon_theorem>
杂项笔记¶
Polygon
和Triangle
的 area 属性可能会返回正值或负值,这取决于点的方向是逆时针还是顺时针。如果你总是想要一个正值,请确保使用abs
函数。虽然
Polygon
可以指任何类型的多边形,但代码是为简单多边形编写的。因此,如果处理复杂多边形(边重叠),可能会遇到潜在问题。由于 SymPy 仍处于起步阶段,某些功能可能无法正确简化,因此某些应该返回
True
的情况(例如,Point.is_collinear
)可能实际上不会返回。同样,尝试查找实际相交的实体的交点可能会导致空结果。
未来工作¶
真理设置表达式¶
当处理符号实体时,通常会出现无法保证断言的情况。例如,考虑以下代码:
>>> from sympy import *
>>> from sympy.geometry import *
>>> x,y,z = map(Symbol, 'xyz')
>>> p1,p2,p3 = Point(x, y), Point(y, z), Point(2*x*y, y)
>>> Point.is_collinear(p1, p2, p3)
False
尽管结果目前是 False
,但这并不总是 正确 的。如果数量 \(z - y - 2*y*z + 2*y**2 == 0\),那么这些点将是共线的。告知用户这一点会非常好,因为这样的数量可能对用户的进一步计算有用,而且至少是值得了解的。这可以通过返回一个对象(例如,GeometryResult)来实现,用户可以使用该对象。实际上,这并不需要大量的工作。
三维及超越¶
目前,几何模块的一个有限子集已扩展到三维,但这无疑是一个很好的扩展方向。这可能需要相当多的工作,因为所使用的许多算法都是针对二维的。
几何可视化¶
绘图模块能够绘制几何实体。请参阅绘图模块条目中的 绘制几何实体 。