当前位置:网站首页>百行代码发射红心,程序员何愁命不中女朋友!
百行代码发射红心,程序员何愁命不中女朋友!
2022-08-05 08:51:00 【AI科技大本营】

七夕是中国民间的传统节日,不同时代、不同地域的人们给这个节日赋予了不同的含义。在漫长的演变过程中,七夕成了牛郎织女相会的日子。正因为这个美丽的爱情传说,七夕被视为中国最具浪漫色彩的、象征爱情的节日。在西风东渐的背景下,七夕又成了中国的“情人节”。
作者 | 许向武
责编 | 张红月
既然是情人节,浪漫的程序员总喜欢搞点花样出来,为紧张且平淡的生活添点色彩。今天给各位带来的是3D动画版的丘比特爱情之剑:一只金色的丘比特爱情之剑以慢镜头方式缓缓刺中一个脉动的红心,红心的主人将会无法控制地爱上TA所看到第一个人。
我猜,当初牛郎和织女一定是被丘比特的爱情之剑射中以后才相爱的,毕竟,他们都生活的天上——西方文化中,木星(Jupiter)就是小爱神丘比特,金星(Venus)则是大爱神维纳斯。
在丘比特的出场爱情之剑前,先用matplotlib绘制一个2D的红心热热身。
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(-np.pi/2, np.pi/2, 1000)
y1 = np.power(np.cos(x),0.5) * np.cos(200*x) + np.power(np.absolute(x),0.5) - 0.7
y2 = np.power(4-np.power(x, 2), 0.01)
plt.plot(x, y1*y2, c='r')
plt.show()
上下波动的曲线形成的心形
放大一点看的话,就会发现上面这个红心其实是一条连续上下波动的曲线。下面的红心,是一个真正封闭的心形,只不过是由四条曲线首尾相连组成的。
import numpy as np
import matplotlib.pyplot as plt
x1 = np.linspace(0, 2, 300)
x2 = np.linspace(0, -2, 300)
y11 = (np.power(x1, 2/3) + np.power(np.power(x1, 4/3)-4*np.power(x1, 2)+4, 0.5))/2 - 0.12
y12 = (np.power(x1, 2/3) - np.power(np.power(x1, 4/3)-4*np.power(x1, 2)+4, 0.5))/2
y21 = (np.power(-x2, 2/3) + np.power(np.power(-x2, 4/3)-4*np.power(-x2, 2)+4, 0.5))/2 - 0.12
y22 = (np.power(-x2, 2/3) - np.power(np.power(-x2, 4/3)-4*np.power(-x2, 2)+4, 0.5))/2
plt.plot(x1, y11, c='r')
plt.plot(x1, y12, c='r')
plt.plot(x2, y21, c='r')
plt.plot(x2, y22, c='r')
plt.show()
四条曲线首尾相连组成的心形
那么,可用用一笔画一个心形吗?当然可以,极坐标方程 r = Arccos(sinθ)就是一条心形线,只是形状不够完美而已。
import numpy as np
import matplotlib.pyplot as plt
theta = np.linspace(0, 2*np.pi, 1000)
x = np.arccos(np.sin(theta)) * np.cos(theta)
y = np.arccos(np.sin(theta)) * np.sin(theta)
plt.plot(x, y, c='r')
plt.show()
心形线
是时候展示3D版的红心了。运行下面的代码,除了需要numpy模块,还需要安装wxgl模块——基于PyOpenGL的三维数据绘图工具包。
pip install wxgl关于wxgl模块的更多详情,请点击十分钟玩转3D绘图:WxGL完全手册,这里是中文文档。
下面是3D版的红心的绘制代码:
import numpy as np
import wxgl.glplot as glt
a = np.linspace(0, 2*np.pi, 500)
b = np.linspace(0.5*np.pi, -0.5*np.pi, 500)
lons, lats = np.meshgrid(a, b)
w = np.sqrt(np.abs(a - np.pi)) * 2
x = 2 * np.cos(lats) * np.sin(lons) * w
y = -2 * np.cos(lats) * np.cos(lons) * w
z = 2 * np.sin(lats)
glt.mesh(x, y, z, color='crimson') # crimson - 绯红
glt.show()是不是很简单?wxgl的使用风格几乎和matplotlib完全一致。拖动鼠标,就可以看到这个3D版的红心的前后左右了。

3D红心
接下来,这段代码将红心数据的生成封装了一个函数,然后调用自定义的模型变换函数,这颗红心就跳动起来了。
import numpy as np
import wxgl.glplot as glt
def red_heart(r, slices=100, thick=2.0, shift=(0,0,0)):
"""返回红心顶点数据"""
a = np.linspace(0, 2*np.pi, slices)
b = np.linspace(0.5*np.pi, -0.5*np.pi, slices)
lons, lats = np.meshgrid(a, b)
w = np.sqrt(np.abs(a - np.pi)) * thick
x = r * np.cos(lats) * np.sin(lons) * w + shift[0]
y = -r * np.cos(lats) * np.cos(lons) * w + shift[1]
z = r * np.sin(lats) + shift[2]
return x, y, z
def heart_beat(t):
"""心跳函数"""
t %= 1000
if t < 300:
scale = 1 + t/3000
elif t > 700:
scale = 1 + (1000-t)/3000
else:
scale = 1.1
return (scale,)
glt.mesh(*red_heart(2), color='crimson', transform=heart_beat)
glt.show()点击左侧工具条上的播放按钮,这颗红心就会按照60次/秒的心率跳动起来。熟悉了wxgl的使用,不难读懂下面这个完整的丘比特爱情之箭的代码。
import numpy as np
import wxgl
import wxgl.glplot as glt
def red_heart(r, slices=100, thick=2.0, shift=(0,0,0)):
"""返回红心顶点数据"""
a = np.linspace(0, 2*np.pi, slices)
b = np.linspace(0.5*np.pi, -0.5*np.pi, slices)
lons, lats = np.meshgrid(a, b)
w = np.sqrt(np.abs(a - np.pi)) * thick
x = r * np.cos(lats) * np.sin(lons) * w + shift[0]
y = -r * np.cos(lats) * np.cos(lons) * w + shift[1]
z = r * np.sin(lats) + shift[2]
return x, y, z
def heart_beat(t):
"""心跳函数"""
t %= 1000
if t < 300:
scale = 1 + t/3000
elif t > 700:
scale = 1 + (1000-t)/3000
else:
scale = 1.1
return (scale,)
def arrow_fly(t):
"""丘比特之箭飞行函数"""
t %= 4000
if t > 2000:
return ((0,-2,40-t/100),)
else:
return ((0,-2,0),)
def heart_fly(t):
"""丘比特之箭飞行函数"""
t %= 4000
if t > 2000:
return ((0,0,1,90), (0,-2,40-t/100))
else:
return ((0,0,1,90), (0,-2,0))
glt.figure(azim=50, elev=16, style='gray') # 设置初始方位角、高度角、背景色
glt.mesh(*red_heart(2), color='crimson', transform=heart_beat) # 绘制跳动的红心
x, y, z = red_heart(0.2, thick=3.0, shift=(0,-8,0)) # 生成心形箭头顶点数据
glt.mesh(x, -z, y, color='crimson', transform=heart_fly) # 绘制心形箭头
light = wxgl.SunLight(roughness=0, metalness=0, shininess=0.5) # 箭杆灯光
glt.cylinder((0,0,-8), (0,0,9), 0.1, color='goldenrod', transform=arrow_fly, light=light) # 绘制箭杆
vs = [(-1,1,11), (1,-1,11), (1,-1,6), (-1,1,6),(-1,-1,11), (1,1,11), (1,1,6), (-1,-1,6)] # 箭尾顶点数据
texture = wxgl.Texture(r'res\feather.png') # 箭尾羽毛纹理
texcoord = [(0,1), (0,0), (1,0), (1,1),(0,1), (0,0), (1,0), (1,1)] # 箭尾纹理坐标
light = wxgl.BaseLight() # 箭尾灯光
glt.quad(vs, texture=texture, texcoord=texcoord, transform=arrow_fly, light=light) # 绘制箭尾
glt.show()wxgl的工具条提供了录制gif和MP4文件的功能,下面的gif就是使用wxgl自带的录制功能生成的。

代码中用到了羽毛的纹理,请下载这个图片,并保存到代码指定的位置。


不止七夕,让《新程序员》陪伴你每个朝夕!
凡在七夕当日订阅《新程序员》的朋友
都将获得CSDN赠送的定制马克杯一个!
扫描下方二维码立即订阅

往期回顾
分享
点收藏
点点赞
点在看边栏推荐
猜你喜欢

CVPR 2022 | 将X光图片用于垃圾分割,港中大(深圳)探索大规模智能垃圾分类

mySQL数据库初始化失败,有谁可以指导一下吗

Data source object management Druid and c3p0

What is a good movie to watch on Qixi Festival?Crawl movie ratings and save to csv file

Fiddler工具讲解

Redis implements distributed lock-principle-detailed explanation of the problem

Comprehensively explain what is the essential difference between GET and POST requests?Turns out I always misunderstood

全面讲解GET 和 POST请求的本质区别是什么?原来我一直理解错了

代码审计—PHP

嵌入式系统:基本定时器
随机推荐
16 kinds of fragrant rice recipes
【LeetCode】623. 在二叉树中增加一行
Dynamic memory development (C language)
What is the connection and difference between software system testing and acceptance testing? Professional software testing solution recommendation
Random code generation
love is a sad song
七夕看什么电影好?爬取电影评分并存入csv文件
ps怎么拼图,自学ps软件photoshop2022,PS制作拼图效果
D2--FPGA SPI interface communication2022-08-03
NC20164 :最大数MAXNUMBER [线段树]
MM上街前的折腾(有趣)
EA谈单机游戏:仍是产品组合中极其重要的部分
[Structural Internal Power Cultivation] Structural Realization Stages (2)
Creo 9.0 基准特征:基准轴
七夕给自己new一个chatRobot当对象
【每日一题】1403. 非递增顺序的最小子序列
thinkPHP5 realizes clicks (data increment/decrement)
MySQL 数据库 报错 The server quit without updating PID file (/var/lib/mysql/localhost.localdomain.pid)
How to make a puzzle in PS, self-study PS software photoshop2022, PS make a puzzle effect
爱情是一部忧伤的乐曲