几何图形#
介绍#
几何实体,如几何圆和几何信息模块,允许创建这些一维几何体。这可能包括询问椭圆的面积,检查一组点的共线性,或者找到两条直线之间的交点。该模块的主要用例涉及具有数值的实体,但也可以使用符号表示。
可用实体#
几何体模块中当前提供以下实体:
我们将要做的大部分工作将是通过这些实体的属性和方法来完成的,但是存在几种全局方法:
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\) ,然后是交点 \(X\) , \(Y\) , \(Z\) 线对数 \(Ab\) 和 \(aB\) , \(Ac\) 和 \(aC\) , \(Bc\) 和 \(bC\) 共线。
>>> 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_六边形定理>
杂记说明#
的面积属性
Polygon
和Triangle
可能返回正值或负值,具体取决于点的方向分别是逆时针还是顺时针。如果您总是想要一个正值,请务必使用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)来实现。这实际上不会涉及大量的工作。
三维及以上#
目前,几何模块的一个有限的子集已经扩展到三维,但是它肯定是一个很好的扩展。这可能需要大量的工作,因为许多算法都是针对二维的。
几何可视化#
绘图模块能够绘制几何实体。看到了吗 Plotting Geometric Entities 在绘图模块条目中。