计算交叉比率

时间:2016-11-06 18:06:00

标签: python python-2.7 math sage

我想在python中编写一个函数来计算四个投影点的交叉比率,我想知道是否有一个优雅而简洁的实现来处理无限的情况。

交叉比率的天真实现如下:

ratio = lambda a,b,c: (a-c)/(b-c)
cross_ratio = lambda a,b,c,d: ratio(a,b,c)/ratio(a,b,d)

但是当其中一个输入是Infinity时,这会失败。这不应该发生,而是我们希望无穷大能够相互抵消"并给我们一个简单的比例。

例如,Infinity, 0, 1, -1的交叉比率应为-1

另外,我想处理以两个数字的比率表示的点数。因此(1 1)1,而(1,0)代表Infinity等。

我总是可以回到一个案例的定义并用它做,但我觉得这可能是学习好设计的好机会。

我正在使用Python 2.7和Sagemath模块。有关如何实现这一点的任何建议吗?

2 个答案:

答案 0 :(得分:1)

我试试这个:

def det2(a, b): return a[0]*b[1] - a[1]*b[0]
def cr2(a, b, c, d): return vector([det2(a,c)*det2(b,d), det2(a,d)*det2(b,c)])

这将在输入上使用齐次坐标,因此您可以输入双元素向量。它也会将其结果返回到齐次坐标,作为一个双元素向量,因此您可以得到无限交叉比的清晰描述。如果你需要将结果作为某个字段的元素,只需使用除法而不是向量构造函数:

def cr2(a, b, c, d): return (det2(a,c)*det2(b,d))/(det2(a,d)*det2(b,c))

我将后缀2添加到我的公式中,因为我个人经常需要平面中四个共线点的交叉比率。在那种情况下,我使用

def det3(a, b, c):
  return matrix([a,b,c]).det() # Or spell this out, if you prefer
def cr3(a, b, c, d, x):
  return vector([det3(a,c,x)*det3(b,d,x), det3(a,d,x)* det3(b,c,x)])

现在让x成为 a,b,c,d共线的任意点,您就可以获得这四个点的交叉比率。或者更一般地说,如果a,b,c,d不共线,则可以得到将这些线连接到x的四条线的交叉比率,这对于许多场景很有用,其中许多场景涉及圆锥曲线。

答案 1 :(得分:1)

最好是使用投射线。

此处的文档包含有用的提示: http://doc.sagemath.org/html/en/reference/schemes/sage/schemes/projective/projective_space.html

以下是交叉比率的实现,以及示例。

sage: P = ProjectiveSpace(1, QQ)
sage: oo, zero, one = P(1, 0), P(0, 1), P(1, 1)
sage: tm = P.point_transformation_matrix
sage: def cross_ratio(a, b, c, d):
....:     a, b, c, d = P(a), P(b), P(c), P(d)
....:     m = tm([a, b, c], [oo, zero, one])
....:     return P(list(m*vector(list(d))))
....: 
sage: cross_ratio(oo, zero, one, 1/2)
(1/2 : 1)
sage: cross_ratio(1, 2, 3, 4)
(4/3 : 1)