您可以使用高阶函数,即返回函数的函数,例如
def Bernstein(n,i):
def f(t):
return t**i*(1.0-t)**(n-i)
return f
你可以这样使用
b52 = Bernstein(5,2)
val = b52(0.74)
但你宁愿使用列表
Bernstein_ni = [Bernstein(n,i) for i in range(n+1)]
用于高阶函数来构建贝塞尔曲线函数
def mk_bezier(Px,Py):
"Input, lists of control points, output a function of t that returns (x,y)"
n = len(Px)
binomials = {0:[1], 1:[1,1], 2:[1,2,1],
3:[1,3,3,1], 4:[1,4,6,4,1], 5:[1,5,10,10,5,1]}
binomial = binomials[n-1]
bPx = [b*x for b,x in zip(binomial,Px)]
bPy = [b*y for b,y in zip(binomial,Py)]
bns = [Bernstein(n-1,i) for i in range(n)]
def f(t):
x = 0 ; y = 0
for i in range(n):
berns = bns[i](t)
x = x + bPx[i]*berns
y = y + bPy[i]*berns
return x, y
return f
最终,在您的程序中,您可以像这样使用函数工厂
linear = mk_bezier([0.0,1.0],[1.0,0.0])
quadra = mk_bezier([0.0,1.0,2.0],[1.0,3.0,1.0])
for t in (0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0):
l = linear(t) ; q = quadra(t)
print "%3.1f (%6.4f,%6.4f) (%6.4f,%6.4f)" % (t, l[0],l[1], q[0],q[1])
这是测试输出
0.0 (0.0000,1.0000) (0.0000,1.0000)
0.1 (0.1000,0.9000) (0.2000,1.3600)
0.2 (0.2000,0.8000) (0.4000,1.6400)
0.3 (0.3000,0.7000) (0.6000,1.8400)
0.4 (0.4000,0.6000) (0.8000,1.9600)
0.5 (0.5000,0.5000) (1.0000,2.0000)
0.6 (0.6000,0.4000) (1.2000,1.9600)
0.7 (0.7000,0.3000) (1.4000,1.8400)
0.8 (0.8000,0.2000) (1.6000,1.6400)
0.9 (0.9000,0.1000) (1.8000,1.3600)
1.0 (1.0000,0.0000) (2.0000,1.0000)
编辑
我认为正确的方法是在模块级别,使用顶级排序 -defaultdictionary
记住执行实际计算所需的所有不同列表,但不会defaultdict
将变量传递给它default_factory
,我不会为了这个答案,感觉像子类dict
化(不是现在),主要原因是我以前从未子类化......
回应OP评论
你说功能度是主要参数?但它是由控制点列表的长度隐含定义的......
N = user_input()
P0x = user_input()
P0y = user_input()
PNx = user_input()
PNy = user_input()
# code that computes P1, ..., PNminus1
orderN = mk_bezier([P0x,P1x,...,PNminus1x,PNx],
[P0y,P1y,...,PNminus1y,PNy])
x077, y077 = orderN(0.77)
但是客户永远是对的,所以如果你说我的解决方案与你的期望不同,我永远不会再试图说服你我的解决方案对你有用。