动态粒子爱心,表白神器源码

2023-11-09

效果

https://www.douyin.com/user/self?modal_id=7187722820967763237

源码

from tkinter import *
from matplotlib import pyplot as plt
from PIL import Image
import random
import math
import numpy as np
import os
import colorsys
import cv2
from scipy.ndimage.filters import gaussian_filter

canvas_width = 600
canvas_height = 600
world_width = 0.05
world_heigth = 0.05

# 中间心的参数
points = None
fixed_point_size = 20000
fixed_scale_range = (4, 4.3)
min_scale = np.array([1.0, 1.0, 1.0]) * 0.9
max_scale = np.array([1.0, 1.0, 1.0]) * 0.9
min_heart_scale = -15
max_heart_scale = 16

# 外围随机心参数
random_point_szie = 7000
random_scale_range = (3.5, 3.9)
random_point_maxvar = 0.2

# 心算法参数
mid_point_ignore = 0.95

# 相机参数
camera_close_plane = 0.1
camera_position = np.array([0.0, -2.0, 0.0])

# 点的颜色
hue = 0.92
color_strength = 255

# 常用向量缓存
zero_scale = np.array([0.0, 0.0, 0.0])
unit_scale = np.array([1.0, 1.0, 1.0])
color_white = np.array([255, 255, 255])
axis_y = np.array([0.0, 1.0, 0.0])

# 渲染缓存
render_buffer = np.empty((canvas_width, canvas_height, 3), dtype=int)
strength_buffer = np.empty((canvas_width, canvas_height), dtype=float)

# 随机点文件缓存
points_file = "temp.txt"

# 渲染结果
total_frames = 30
output_dir = "./output"

# 格式
image_fmt = "jpg"

def color(value):
    digit = list(map(str, range(10))) + list("ABCDEF")
    string = '#'
    for i in value:
        a1 = i // 16
        a2 = i % 16
        string += digit[a1] + digit[a2]
    return string
    

def heart_func(x, y, z, scale):
    bscale = scale
    bscale_half = bscale / 2
    x = x * bscale - bscale_half
    y = y * bscale - bscale_half
    z = z * bscale - bscale_half
    return (x**2 + 9/4*(y**2) + z**2 - 1)**3 - (x**2)*(z**3) - 9/200*(y**2)*(z**3)

def lerp_vector(a, b, ratio):
    result = a.copy()
    for i in range(3):
        result[i] = a[i] + (b[i] - a[i]) * ratio
    return result

def lerp_int(a, b, ratio):
    return (int)(a + (b - a) * ratio)

def lerp_float(a, b, ratio):
    return (a + (b - a) * ratio)

def distance(point):
    return (point[0]**2 + point[1]**2 + point[2]**2) ** 0.5

def dot(a, b):
    return a[0]*b[0] + a[1]*b[1] + a[2]*b[2]

def inside_rand(tense):
    x = random.random()
    y = -tense * math.log(x)
    return y

# 生成中间心
def genPoints(pointCount, heartScales):
    result = np.empty((pointCount, 3))
    index = 0
    while index < pointCount:
        # 生成随机点
        x = random.random()
        y = random.random()
        z = random.random()

        # 扣掉心中间的点
        mheartValue = heart_func(x, 0.5, z, heartScales[1])
        mid_ignore = random.random()
        if mheartValue < 0 and mid_ignore < mid_point_ignore:
            continue
        
        heartValue = heart_func(x, y, z, heartScales[0])
        z_shrink = 0.01
        sz = z - z_shrink
        sheartValue = heart_func(x, y, sz, heartScales[1])

        # 保留在心边上的点
        if heartValue < 0 and sheartValue > 0:
            result[index] = [x - 0.5, y - 0.5, z - 0.5]

            len = 0.7
            result[index] = result[index] * (1 - len * inside_rand(0.2))

            newY = random.random() - 0.5
            rheartValue = heart_func(result[index][0] + 0.5, newY + 0.5, result[index][2] + 0.5, heartScales[0])
            if rheartValue > 0:
                continue
            result[index][1] = newY

            dist = distance(result[index])
            if dist < 0.12:
                continue
            
            index = index + 1
            if index % 100 == 0:
                print("{ind} generated {per}%".format(ind=index, per=((index / pointCount) * 100)))

    return result

def genRandPoints(pointCount, heartScales, maxVar, ratio):
    result = np.empty((pointCount, 3))
    index = 0
    while index < pointCount:
        x = random.random()
        y = random.random()
        z = random.random()
        mheartValue = heart_func(x, 0.5, z, heartScales[1])
        mid_ignore = random.random()
        if mheartValue < 0 and mid_ignore < mid_point_ignore:
            continue

        heartValue = heart_func(x, y, z, heartScales[0])
        sheartValue = heart_func(x, y, z, heartScales[1])

        if heartValue < 0 and sheartValue > 0:
            result[index] = [x - 0.5, y - 0.5, z - 0.5]
            dist = distance(result[index])
            if dist < 0.12:
                continue

            len = 0.7
            result[index] = result[index] * (1 - len * inside_rand(0.2))
            index = index + 1

    for i in range(pointCount):
        var = maxVar * ratio
        randScale = 1 + random.normalvariate(0, var)
        result[i] = result[i] * randScale

    return result

# 世界坐标到相机本地坐标
def world_2_cameraLocalSapce(world_point):
    new_point = world_point.copy()
    new_point[1] = new_point[1] + camera_position[1]
    return new_point

# 相机本地坐标到相机空间坐标
def cameraLocal_2_cameraSpace(cameraLocalPoint):
    depth = distance(cameraLocalPoint)
    cx = cameraLocalPoint[0] * (camera_close_plane / cameraLocalPoint[1])
    cz = -cameraLocalPoint[2] * (cx / cameraLocalPoint[0])
    cameraLocalPoint[0] = cx
    cameraLocalPoint[1] = cz
    return cameraLocalPoint, depth

# 相机空间坐标到屏幕坐标
def camerSpace_2_screenSpace(cameraSpace):
    x = cameraSpace[0]
    y = cameraSpace[1]

    # convert to view space
    centerx = canvas_width / 2
    centery = canvas_height / 2
    ratiox = canvas_width / world_width
    ratioy = canvas_height / world_heigth

    viewx = centerx + x * ratiox
    viewy = canvas_height - (centery + y * ratioy)

    cameraSpace[0] = viewx
    cameraSpace[1] = viewy
    return cameraSpace.astype(int)


# 绘制世界坐标下的点
def draw_point(worldPoint):
    cameraLocal = world_2_cameraLocalSapce(worldPoint)
    cameraSpsace, depth = cameraLocal_2_cameraSpace(cameraLocal)
    screeSpace = camerSpace_2_screenSpace(cameraSpsace)

    draw_size = int(random.random() * 3 + 1)
    draw_on_buffer(screeSpace, depth, draw_size)

# 绘制到缓存上
def draw_on_buffer(screenPos, depth, draw_size):
    if draw_size == 0:
        return
    elif draw_size == 1:
        draw_point_on_buffer(screenPos[0], screenPos[1], color_strength, depth)
    elif draw_size == 2:
        draw_point_on_buffer(screenPos[0], screenPos[1], color_strength, depth)
        draw_point_on_buffer(screenPos[0] + 1, screenPos[1] + 1, color_strength, depth)
    elif draw_size == 3:
        draw_point_on_buffer(screenPos[0], screenPos[1], color_strength, depth)
        draw_point_on_buffer(screenPos[0] + 1, screenPos[1] + 1, color_strength, depth)
        draw_point_on_buffer(screenPos[0] + 1, screenPos[1], color_strength, depth)
    elif draw_size == 4:
        draw_point_on_buffer(screenPos[0], screenPos[1], color_strength, depth)
        draw_point_on_buffer(screenPos[0] + 1, screenPos[1], color_strength, depth)
        draw_point_on_buffer(screenPos[0], screenPos[1] + 1, color_strength, depth)
        draw_point_on_buffer(screenPos[0] + 1, screenPos[1] + 1, color_strength, depth)


# 根据色调和颜色强度获取颜色
def get_color(strength):
    result = None
    if strength >= 1:
        result = colorsys.hsv_to_rgb(hue, 2 - strength, 1)
    else:
        result = colorsys.hsv_to_rgb(hue, 1, strength)
    r = min(result[0] * 256, 255)
    g = min(result[1] * 256, 255)
    b = min(result[2] * 256, 255)
    return np.array((r, g, b), dtype=int)

# 可以根据深度做一些好玩的
def draw_point_on_buffer(x, y, color, depth):
    if x < 0 or x >= canvas_width or y < 0 or y >= canvas_height:
        return

    # 混合
    strength = float(color) / 255
    strength_buffer[x, y] = strength_buffer[x, y] + strength

# 绘制缓存
def draw_buffer_on_canvas(output = None):
    render_buffer.fill(0)
    for i in range(render_buffer.shape[0]):
        for j in range(render_buffer.shape[1]):
            render_buffer[i, j] = get_color(strength_buffer[i, j])
    im = Image.fromarray(np.uint8(render_buffer))
    im = im.rotate(-90)
    if output is None:
        plt.imshow(im)
        plt.show()
    else:
        im.save(output)


def paint_heart(ratio, randratio, outputFile = None):
    global strength_buffer
    global render_buffer
    global points

    # 清空缓存
    strength_buffer.fill(0)

    for i in range(fixed_point_size):
        # 缩放
        point = points[i] * lerp_vector(min_scale, max_scale, ratio)

        # 球型场
        dist = distance(point)
        radius = 0.4
        sphere_scale = radius / dist
        point = point * lerp_float(0.9, sphere_scale, ratio * 0.3)

        # 绘制
        draw_point(point)

    # 生成一组随机点
    randPoints = genRandPoints(random_point_szie, random_scale_range, random_point_maxvar, randratio)
    for i in range(random_point_szie):
        # 绘制
        draw_point(randPoints[i])

    # 高斯模糊
    for i in range(1):
        strength_buffer = gaussian_filter(strength_buffer, sigma=0.8)

    # 绘制缓存
    draw_buffer_on_canvas(outputFile)

def show_images():
    img = None
    for i in range(total_frames):
        save_name = "{name}.{fmt}".format(name=i, fmt=image_fmt)
        save_path = os.path.join(output_dir, save_name)
        img = cv2.imread(save_path, cv2.IMREAD_ANYCOLOR)
        cv2.imshow("Img", img)
        cv2.waitKey(25)


def gen_images():
    global points

    if not os.path.isdir(output_dir):
        os.mkdir(output_dir)
    
    # 尝试加载或生成中间心
    if not os.path.exists(points_file):
        print("未发现缓存点,重新生成中")
        points = genPoints(fixed_point_size, fixed_scale_range)
        np.savetxt(points_file, points)
    else:
        print("发现缓存文件,跳过生成")
        points = np.loadtxt(points_file)

    for i in range(total_frames):
        print("正在处理图片... ", i)
        frame_ratio = float(i) / (total_frames - 1)
        frame_ratio = frame_ratio ** 2
        ratio = math.sin(frame_ratio * math.pi) * 0.743144
        randratio = math.sin(frame_ratio * math.pi * 2 + total_frames / 2)
        save_name = "{name}.{fmt}".format(name=i, fmt=image_fmt)
        save_path = os.path.join(output_dir, save_name)
        paint_heart(ratio, randratio, save_path)
        print("图片已保存至", save_path)


if __name__ == "__main__":
    gen_images()
    while True:
        show_images()
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

动态粒子爱心,表白神器源码 的相关文章

  • 保存为 HDF5 的图像未着色

    我目前正在开发一个将文本文件和 jpg 图像转换为 HDF5 格式的程序 用HDFView 3 0打开 似乎图像仅以灰度保存 hdf h5py File Sample h5 img Image open Image jpg data np
  • 在 django ORM 中查询时如何将 char 转换为整数?

    最近开始使用 Django ORM 我想执行这个查询 select student id from students where student id like 97318 order by CAST student id as UNSIG
  • 将html数据解析成python列表进行操作

    我正在尝试读取 html 网站并提取其数据 例如 我想查看公司过去 5 年的 EPS 每股收益 基本上 我可以读入它 并且可以使用 BeautifulSoup 或 html2text 创建一个巨大的文本块 然后我想搜索该文件 我一直在使用
  • Python 中的舍入浮点问题

    我遇到了 np round np around 的问题 它没有正确舍入 我无法包含代码 因为当我手动设置值 而不是使用我的数据 时 返回有效 但这是输出 In 177 a Out 177 0 0099999998 In 178 np rou
  • Pandas/Google BigQuery:架构不匹配导致上传失败

    我的谷歌表中的架构如下所示 price datetime DATETIME symbol STRING bid open FLOAT bid high FLOAT bid low FLOAT bid close FLOAT ask open
  • 需要在python中找到print或printf的源代码[关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 我正在做一些我不能完全谈论的事情 我
  • 跟踪 pypi 依赖项 - 谁在使用我的包

    无论如何 是否可以通过 pip 或 PyPi 来识别哪些项目 在 Pypi 上发布 可能正在使用我的包 也在 PyPi 上发布 我想确定每个包的用户群以及可能尝试积极与他们互动 预先感谢您的任何答案 即使我想做的事情是不可能的 这实际上是不
  • 使用 kivy textinput 的 'input_type' 属性的问题

    您好 我在使用 kivy 的文本输入小部件的 input type 属性时遇到问题 问题是我制作了两个自定义文本输入 其中一个称为 StrText 其中设置了 input type text 然后是第二个文本输入 名为 NumText 其
  • Python zmq SUB 套接字未接收 MQL5 Zmq PUB 套接字

    我正在尝试在 MQL5 中设置一个 PUB 套接字 并在 Python 中设置一个 SUB 套接字来接收消息 我在 MQL5 中有这个 include
  • 在Python中连接反斜杠

    我是 python 新手 所以如果这听起来很简单 请原谅我 我想加入一些变量来生成一条路径 像这样 AAAABBBBCCCC 2 2014 04 2014 04 01 csv Id TypeOfMachine year month year
  • 如何将张量流模型部署到azure ml工作台

    我在用Azure ML Workbench执行二元分类 到目前为止 一切正常 我有很好的准确性 我想将模型部署为用于推理的 Web 服务 我真的不知道从哪里开始 azure 提供了这个doc https learn microsoft co
  • Python beautifulsoup 仅限 1 级文本

    我看过其他 beautifulsoup 得到相同级别类型的问题 看来我的有点不同 这是网站 我正试图拿到右边那张桌子 请注意表的第一行如何展开为该数据的详细细分 我不想要那个数据 我只想要最顶层的数据 您还可以看到其他行也可以展开 但在本例
  • 从Python中的字典列表中查找特定值

    我的字典列表中有以下数据 data I versicolor 0 Sepal Length 7 9 I setosa 0 I virginica 1 I versicolor 0 I setosa 1 I virginica 0 Sepal
  • 如何通过 TLS 1.2 运行 django runserver

    我正在本地 Mac OS X 机器上测试 Stripe 订单 我正在实现这段代码 stripe api key settings STRIPE SECRET order stripe Order create currency usd em
  • Jupyter Notebook 找不到 Python 模块

    不知道发生了什么 但每当我使用 ipython 氢 原子 或 jupyter 笔记本时都找不到任何已安装的模块 我知道我安装了 pandas 但笔记本说找不到 我应该补充一点 当我正常运行脚本时 python script py 它确实导入
  • 仅第一个加载的 Django 站点有效

    我最近向 stackoverflow 提交了一个问题 标题为使用mod wsgi在apache上多次请求后Django无限加载 https stackoverflow com questions 71705909 django infini
  • 为什么 Pickle 协议 4 中的 Pickle 文件是协议 3 中的两倍,而速度却没有任何提升?

    我正在测试 Python 3 4 我注意到 pickle 模块有一个新协议 因此 我对 2 个协议进行了基准测试 def test1 pickle3 open pickle3 wb for i in range 1000000 pickle
  • 使用for循环时如何获取前一个元素? [复制]

    这个问题在这里已经有答案了 可能的重复 Python 循环内的上一个和下一个值 https stackoverflow com questions 1011938 python previous and next values inside
  • 模拟pytest中的异常终止

    我的多线程应用程序遇到了一个错误 主线程的任何异常终止 例如 未捕获的异常或某些信号 都会导致其他线程之一死锁 并阻止进程干净退出 我解决了这个问题 但我想添加一个测试来防止回归 但是 我不知道如何在 pytest 中模拟异常终止 如果我只
  • cv2.VideoWriter:请求一个元组作为 Size 参数,然后拒绝它

    我正在使用 OpenCV 4 0 和 Python 3 7 创建延时视频 构造 VideoWriter 对象时 文档表示 Size 参数应该是一个元组 当我给它一个元组时 它拒绝它 当我尝试用其他东西替换它时 它不会接受它 因为它说参数不是

随机推荐

  • 在复苏与重塑之路上,同程旅行为旅游业价值回归交出答卷

    若论对疫情感受最深刻的行业 旅游业必然榜上有名 也许这个产业链上的每个玩家在这两年都思考过这样两个问题 客观上 旅游业恢复的基础条件有哪些 主观上 又该用什么措施 什么方法应对现在的局面 尽管疫情影响仍未消散 但11月以来 从防疫新提法到文
  • PostgreSQL pg中的截取补齐lpad函数怎么用?

    PostgreSQL pg中的截取补齐lpad函数怎么用 1 左边填充 右边截取 PostgreSQL中的lpad 函数有两个功能 如果长度不够指定的长度 就在左边填充字符串 如果长度超出了指定的长度 就把右边截掉 The PostgreS
  • 使用matplotlib绘制饼图

    根据消费类别 如外卖 零食 衣服 娱乐等 使用matplotlib绘制本月的消费支出饼图 以代码插入方式提交源代码 并以图像文件提交运行截图 python代码 import matplotlib pyplot as plt from pyl
  • 60分钟学pytorch

    本文会持续更新 直至完成pytorch中的60分入门文档部分 目前为tensor的基础操作部分 本文代码github https github com amazingzby pytorch tutorial pytorch官方文档给初学者提
  • ui(new Ui::MainWindow)

    用最新的QtCreator选择GUI的应用会产生含有如下文件的工程 下面就简单分析下各部分的功能 pro文件是供qmake使用的文件 不是本文的重点 不过其实也很简单的 在此不多赘述 所以呢 还是从main开始 include
  • Java基础-学习笔记(一)

    1 IT业务的发展变化 1 大型机 一代 IBM 2 PC Mac 二代 微软 苹果 3 互联网 三代 Google Baidu 4 移动互联网 谷歌 微软 苹果 所谓 移动互联网 移动通信 互联网 马云所属 IT到DT的变化 注 推荐本书
  • MATLAB的曲线拟合

    原文地址 MATLAB的曲线拟合 作者 睿吉jerry MATLAB软件提供了基本的曲线拟合函数的命令 曲线拟合就是计算出两组数据之间的一种函数关系 由此可描绘其变化曲线及估计非采集数据对应的变量信息 1 线性拟合函数 regress 调用
  • 智能合约简介

    链客 专为开发者而生 有问必答 此文章来自区块链技术社区 未经允许拒绝转载 当人们在讨论智能合约的时候他们到底在说什么 在区块链和加密货币的语境中 智能合约的定义是 在分布式存储平台 例如区块链 上存储并复制的 在计算机网络 通常是运行区块
  • 【qiankun】子应用的路由信息传给主应用,主应用使用this.$router.push跳转子应用页面

    前提 已经安装qiankun 并且子应用已经接入主应用 场景 主应用是vue2 子应用是vue3 子应用的路由文件router index ts 在这段后面加下列代码 const router createRouter history cr
  • VMware Workstation 无法连接到虚拟机。请确保您有权运行该程序、访问该程序使用的所有目录以及访问所有临时文件目录的解决方法

    VMware Workstation 无法连接到虚拟机 请确保您有权运行该程序 访问该程序使用的所有目录以及访问所有临时文件目录 这个问题刚刚用虚拟机的人可能会经常遇到 解决方法就是 在开始中搜索服务 点击服务正在本电脑运行 注意 这里演示
  • CloudCompare 二次开发(5)——非插件中的PCL环境配置(均匀采样为例)

    目录 一 概述 二 CMakeLists txt 三 源码编译 四 代码示例 五 结果展示 本文由CSDN点云侠原创 原文链接 爬虫网站自重 一 概述 在进行CloudCompare二次开发的时候 可以直接在CloudCompare的核心功
  • 推动政府数字化转型进入新阶段

    推动政府数字化转型进入新阶段 公司近两年比较关注数字化转型和金融科技 打算今年重点了解一下 在网上看到了一个文章 感觉还不错 转载到这里 本文转自人民政协网上的 推动政府数字化转型进入新阶段 1 国家政策 国务院近日发布的 十四五 数字经济
  • 智慧城市智慧零售受益于5G和AI双核驱动

    支付宝推出了刷脸支付 我们只需要对准摄像头让它把我们脸部的特征完全识别出来 然后就可以进行支付了 那么这种人脸支付会用在很多地方 很简单 我们去超市购物的时候 以往你要么用卡要么给现金 或者你掏出手机来支付 但是怎么也得输入密码或者按指纹
  • MySQL自增主键详解

    一 自增值保存在哪儿 不同的引擎对于自增值的保存策略不同 1 MyISAM引擎的自增值保存在数据文件中 2 InnoDB引擎的自增值 在MySQL5 7及之前的版本 自增值保存在内存里 并没有持久化 每次重启后 第一次打开表的时候 都会去找
  • chrome浏览器:您的连接不是私密连接,burp抓包

    问题 您的连接不是私密连接 处理 简简单单 跟着我来没错 不要浪费时间再找了 插件设置 SwitchyOmega 开启代理访问http burp CA下载证书 chrome flags Allow invalid certificates
  • 第3章 数据库结构设计

    3 1数据库概念设计 数据库概念设计主要解决数据需求 即如何准确地理解数据需求 真实地把应用领域中要处理的数据组织 定义描述清楚 以支持数据库设计后续阶段的工作 3 1 1概念设计的任务 数据库概念设计阶段的目标是 1 定义和描述应用领域涉
  • 2024王道数据结构P17No11

    一个长度为L L gt 1 的升序序列S 处在第L 2位置 向下取整 的数称为S的中位数 例如 序列S1 11 13 15 17 19 则中位数为15 两个序列的中位数是含他们所有元素的升序序列的中位数 例如 S2 2 4 6 8 20 则
  • 【毕业设计】深度学习身份证识别系统 - 机器视觉 python

    文章目录 0 前言 1 实现方法 1 1 原理 1 1 1 字符定位 1 1 2 字符识别 1 1 3 深度学习算法介绍 1 1 4 模型选择 2 算法流程 3 部分关键代码 4 效果展示 5 最后 0 前言 Hi 大家好 这里是丹成学长的
  • 学习总结7.1 Linux Rsh服务器

    在线安装是指不需要用户亲自下对应软件的包 但是需要对应系统能够访问互联网 不同的Linux系统使用不同的工具进行在线安装软件 常见的在线安装软件的工具如下所示 Ubuntu Debian系统使用apt get进行在线安装软件 Redhat
  • 动态粒子爱心,表白神器源码

    效果 https www douyin com user self modal id 7187722820967763237 源码 from tkinter import from matplotlib import pyplot as p