2016-11-06 187 views
2

我想在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, 0, 1, -1的交叉比应该是-1

另外,我想处理以两个数字的比例表示的积分。因此(1 1)将是数1,而(1,0)将代表Infinity

我总是可以的情况下回落到一个定义,并用它做什么,但我觉得这可能是学习好的设计的好机会。

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

回答

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)]) 

这将输入使用齐次坐标,所以你INOUT两个元素的矢量。它也将返回齐次坐标的结果,作为一个两元素向量,所以您可以获得无限交叉比的干净描述。如果您需要的结果是一些领域的一个元素,而不是,只是使用的替代载体构造师:

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

最好的是与投影线一起工作。

这里的文档包含有用的提示: 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)