python - 在 Python 中赋值变量值之前对变量执行操作

标签 python variables bezier polynomials

好的,所以基本上我的问题是将思维框架从解决“纸上”数学问题转变为通过编程解决它们。让我解释一下:我想知道是否可以在为变量赋值之前对其执行操作。就像如果我有类似 (1-x)**n 的东西,我可以先给 n 赋值,然后在一定程度上将它从 specific 变成 a,然后给 x 一个或多个值。如果我不够清楚:如果n=2,我可以先将方程转成1-2x+x**2的形式,然后在下一步处理x值吗?

我想编写一个代码来计算和绘制 n 次贝塞尔曲线。我为此使用伯恩斯坦多项式,所以我意识到方程由 3 部分组成:第一部分是多项式系数,它们都是帕斯卡三角形的一部分;我正在计算这些并将它们放在一个列表中。第二部分是控制点的坐标,也是某种系数,将它们放在单独的列表中。现在是困难的部分:方程中有变量的部分。Bernsteins 使用重心坐标(意思是 u 和 1-u)。这部分方程的 N 阶公式是:

u**i  *(1-u)**(n-i)

其中 n 是曲线度数,我从 0->n 并且 U 是变量。U 是实际归一化的变量,这意味着它的值可以从 0 到 1,我想稍后在一定数量的步骤中迭代它(像 1000)。但问题是,如果我尝试使用提到的等式,我会不断出错,因为 Python 不知道如何处理你。我讲授了嵌套循环,其中第一个循环将 u 的值从 0 迭代到 1,第二个将采用关心从0到n的上述方程,但不确定它是否是正确的解决方案,也不知道如何检查结果。你怎么看? PS:我没有上传代码,因为我遇到问题的部分我什至无法开始,而且,我认为但可能是错误的,它与代码的其余部分分开了;但如果您认为它可以帮助解决问题,我可以上传它。

最佳答案

您可以使用高阶函数,即返回函数的函数,如

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)

编辑

我认为正确的做法是在模块级别,使用 sort-of-defaultdictionary memoizes执行实际计算所需的所有不同列表,但 defaultdict 不会将 variable 传递给它的 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)

但客户永远是对的,所以如果您声明我的解决方案与您的预期不同,我将不再试图说服您我的解决方案适合您。

关于python - 在 Python 中赋值变量值之前对变量执行操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26897003/

相关文章:

c++ - 从函数返回局部变量的引用不会出错

javascript - 变量值发生变化(根据alert())但被插件代码忽略?

python - 给定 X 坐标,如何计算一个点的 Y 坐标,使其位于贝塞尔曲线上

math - 三次贝塞尔曲线 - 得到给定 X 的 Y - 控制点的 X 增加的特殊情况

python - 我如何使用tastepie登录django

python - ImportError:无法导入名称argparser

python - 将变量内容传递给 Python 中的类函数

javascript - 如何计算避开物体的贝塞尔曲线控制点?

python - 从二维数组中,创建另一个由原始数组中随机选择的值(行之间不共享的值)组成的二维数组,而不使用循环

python - 在 Python 中打开远程文档