Redian新闻
>
笑喷了!电视剧里的代码真能运行吗?

笑喷了!电视剧里的代码真能运行吗?

公众号新闻

最近有一部关于程序员的电视剧,里边有一段关于期中考试要用程序画一个爱心的桥段。

电视剧里的代码,真的能运行吗?

今天就给大家分析下剧中出现的“爱心”代码,并且来复刻一下最后男主完成的酷炫跳动爱心。

剧中代码赏析

1路人同学的代码

虽然剧中说是“C 语言期中考试”,但这位同学的代码名叫 draw2.py,一个典型的 Python 文件,再结合截图中的 pen.forward、pen.setpos 等方法来看,应该是用 turtle 海龟作图库来画爱心。那效果通常是这样的:

import turtle as t
t.color('red')
t.setheading(50)
t.begin_fill()
t.circle(-100170)
t.circle(-30040)
t.right(38)
t.circle(-30040)
t.circle(-100170)
t.end_fill()
t.done()

而不是剧中那个命令行下用 1 组成的不规则的图形。

2课代表向路人同学展示的优秀代码

及效果:

这确实是C语言代码了,但文件依然是以 .py 为后缀,并且 include 前面没有加上 #,这显然是没法运行的。

里面的内容是可以画出爱心的,用的是这个爱心曲线公式:

然后遍历一个 15*17 的方阵,计算每个坐标是在曲线内还是曲线外,在内部就输出 # 或 *,外部就是 -。

用 python 改写一下是这样的:


for y in range(9-6-1):
    for x in range(-89):
        print('*##*'[(x+10)%4if (x*x+y*y-25)**3 < 25*x*x*y*y*y else '-', end=' ')
    print()

效果:

稍微改一下输出,还能做出前面那个全是 1 的效果:


for y in range(9-6-1):
    for x in range(-89):
        print('1' if (x*x+y*y-25)**3 < 25*x*x*y*y*y else ' ', end=' ')
    print()

但跟剧中所谓的效果相去甚远。

3主角狂拽酷炫 D 炸天的跳动爱心:

代码有两个片段:

但这两个片段也不 C 语言,而是 C++,且两段并不是同一个程序,用的方法也完全不一样。

第一段代码跟前面一种思路差不多,只不过没有直接用一条曲线,而是上半部用两个圆形,下半部用两条直线,围出一个爱心。

改写成 Python 代码:


size = 10
for x in range(size):
    for y in range(4*size+1):
        dist1 = ((x-size)**2 + (y-size)**2) ** 0.5
        dist2 = ((x-size)**2 + (y-3*size)**2) ** 0.5
        if dist1 < size + 0.5 or dist2 < size + 0.5:
            print('V', end=' ')
        else:
            print(' ', end=' ')
    print()

for x in range(12*size):
    for y in range(x):
        print(' ', end=' ')
    for y in range(4*size+1-2*x):
        print('V', end=' ')
    print()

运行效果:

第二段代码用的是基于极坐标的爱心曲线,是遍历角度来计算点的位置。公式是:

计算出不同角度对应的点坐标,然后把它们连起来,就是一个爱心。

from math import pi, sin, cos
import matplotlib.pyplot as plt
no_pieces = 100
dt = 2*pi/no_pieces
t = 0
vx = []
vy = []
while t <= 2*pi:
    vx.append(16*sin(t)**3)
    vy.append(13*cos(t)-5*cos(2*t)-2*cos(3*t)-cos(4*t))
    t += dt
plt.plot(vx, vy)
plt.show()

效果:

代码中循环时用到的 2π 是为了保证曲线长度足够绕一个圈,但其实长一点也无所谓,即使 π=100 也不影响显示效果,只是相当于同一条曲线画了很多遍。所以剧中代码里写下 35 位小数的 π,还被女主用纸笔一字不落地抄写下来,实在是让程序员无法理解的迷惑行为。

但不管写再多位的 π,上述两段代码都和最终那个跳动的效果差了五百只羊了个羊。

跳动爱心实现

下面就来挑战一下用 Python 实现最终的那个跳动爱心的效果。

1、想要绘制动态的效果,必定要借助一些库的帮助,不然代码量肯定会让你感动得想哭。这里我们将使用 pgzero 库。然后结合最后那个极坐标爱心曲线代码,先绘制出曲线上离散的点。

import pgzrun
from math import pi, sin, cos

no_p = 100
dt = 2*3/no_p
t = 0
x = []
y = []
while t <= 2*3:
    x.append(16*sin(t)**3)
    y.append(13*cos(t)-5*cos(2*t)-2*cos(3*t)-cos(4*t))
    t += dt

def draw():
    screen.clear()
    for i in range(len(x)):
        screen.draw.filled_rect(Rect((x[i]*10+400, -y[i]*10+300), (44)), 'pink')

pgzrun.go()

2、把点的数量增加,同时沿着原点到每个点的径向加一个随机数,并且这个随机数是按照正态分布来的(半个正态分布),大概率分布在曲线上,向曲线内部递减。这样,就得到这样一个随机分布的爱心效果。

...
no_p = 20000
...
while t <= 2*pi:
    l = 10 - abs(random.gauss(102) - 10)
    x.append(l*16*sin(t)**3)
    y.append(l*(13*cos(t)-5*cos(2*t)-2*cos(3*t)-cos(4*t)))
    t += dt
...

3、下面就是让点动起来,这步是关键,也有一点点复杂。为了方便对于每个点进行控制,这里将每个点自定义成了一个 Particle 类的实例。从原理上来说,就是给每个点加一个缩放系数,这个系数是根据时间变化的正弦函数,看起来就会像呼吸的节律一样。

class Particle():
    def __init__(self, pos, size, f):
        self.pos = pos
        self.pos0 = pos
        self.size = size
        self.f = f

    def draw(self):
        screen.draw.filled_rect(Rect((10*self.f*self.pos[0] + 400-10*self.f*self.pos[1] + 300), self.size), 'hot pink')

    def update(self, t):
        df = 1 + (2 - 1.5) * sin(t * 3) / 8
        self.pos = self.pos0[0] * df, self.pos0[1] * df

...

t = 0
def draw():
    screen.clear()
    for p in particles:
        p.draw()

def update(dt):
    global t
    t += dt
    for p in particles:
        p.update(t)

4、 剧中爱心跳动时,靠中间的点波动的幅度更大,有一种扩张的效果。所以再根据每个点距离原点的远近,再加上一个系数,离得越近,系数越大。

class Particle():
    ...
    def update(self, t):
        df = 1 + (2 - 1.5 * self.f) * sin(t * 3) / 8
        self.pos = self.pos0[0] * df, self.pos0[1] * df

5、最后再用同样的方法画一个更大一点的爱心,这个爱心不需要跳动,只要每一帧随机绘制就可以了。

def draw():
    ...
    t = 0
    while t < 2*pi:
        f = random.gauss(1.10.1)
        x = 16*sin(t)**3
        y = 13*cos(t)-5*cos(2*t)-2*cos(3*t)-cos(4*t)
        size = (random.uniform(0.5,2.5), random.uniform(0.5,2.5))
        screen.draw.filled_rect(Rect((10*f*x + 400-10*f*y + 300), size), 'hot pink')
        t += dt * 3

合在一起,搞定!

总结一下,就是在原本的基础爱心曲线上加上一个正态分布的随机量、一个随时间变化的正弦函数和一个跟距离成反比的系数,外面再套一层更大的随机爱心,就得到类似剧中的跳动爱心效果。

当然,咱缺的不是代码,是女主角。


·················END·················

推荐阅读

•   一场乌龙,我的帐号,被永封•   今年,我只赚了一点点•   该死,这糟糕的心动感

微信扫码关注该文公众号作者

戳这里提交新闻线索和高质量文章给我们。
相关阅读
高考电视剧精准吐槽动画行业,它凭什么引起热议?日剧里的她们,都会这样穿衣服。《狂飙》安欣原型找到了!现实比电视剧更惊心动魄警犬上班的时候快乐上天,走近一看...笑喷了!闷声拿高分,《三体》电视剧的好评会持续吗?一批电视剧获广电总局扶持!金秋10月 我的玫瑰街角还在开中国妹子火上外媒!婚礼上专门给前男友安排一桌!看完他们长相,美国网友笑喷了还记得《欢乐颂》里的蒋欣吗?在新剧里居然瘦了这么多?上海公布前三季度国民经济运行情况:经济运行回稳向好,发展质量稳步提升GitHub Copilot代码笔刷火了,一刷修bug加文档,特斯拉前AI总监:我现在80%的代码由AI完成单卡就能运行AI画画模型,小白也能看懂的教程来了,还有100万卡时免费NPU算力可用丨昇思MindSpore火上热搜!电视剧《三体》登上央视;腾讯视频开播1小时便创纪录!“整个宇宙开始闪烁!”【提示】金山铁路10月11日起调整运行时刻表,运行时长增加"给你5000万美元离开我儿子"!电视剧豪门情节要在现实看到了狭义和广义相对论之本质区别。。。笑喷了!初中生水平“降维打击”知名粉红大V!申请党狂喜!赵丽颖新剧里的NYU,竟是最爱留学生的美国大学?!在美国250.丢、增衣物,太叫真了那些年琼瑶剧里的开车名场面,别让我一个人瞎老年人的酗酒“乙类乙管”,医疗资源够吗?国内仍有德尔塔流行吗?有新变异株吗?热点12问→小鸡毛以为自己是小狮子,昂首挺胸那一下,笑喷了!笑喷了~~一群娃爸娃妈的青春实录谁动了我的代码:代码混淆剖析想起少年讀小説赴华:美航AA取消了一些国泰航空北美航班的的代码共享,我的航班会被影响吗?电视剧《三体》定档!你期待吗?丢人丢进电视剧里了离婚后多久可以开始相亲?这些妈妈的答案太刺激,比电视剧更精彩!
logo
联系我们隐私协议©2024 redian.news
Redian新闻
Redian.news刊载任何文章,不代表同意其说法或描述,仅为提供更多信息,也不构成任何建议。文章信息的合法性及真实性由其作者负责,与Redian.news及其运营公司无关。欢迎投稿,如发现稿件侵权,或作者不愿在本网发表文章,请版权拥有者通知本网处理。