使用Processing和PixelFlow库创建交互式流体太极动画

news2024/11/16 13:23:10

使用Processing和PixelFlow库创建交互式流体太极动画

  • 引言
  • 准备工作
  • 效果展示
  • 代码结构
  • 代码解析
    • 第一部分:导入库和设置基本参数
    • 第二部分:流体类定义
      • `MyFluidDataConfig` 类详解
      • `MyFluidData` 类详解
      • `my_update` 方法详解
      • 流体类定义完整代码
    • 第三部分:太极类定义
      • 太极类定义完整代码
    • 结语

引言

本教程将指导您如何使用Processing编程环境结合PixelFlow库来创建一个交互式的流体太极动画。PixelFlow是一个基于GPU的实时图形库,它提供了高效的流体模拟功能。我们将通过麦克风输入的音频振幅来驱动流体模拟,并在流体之上绘制一个动态的太极图案。

准备工作

  1. 安装Processing:访问Processing官网下载并安装Processing IDE。

  2. 导入DwPixelFlow库:在Processing中,通过菜单"Sketch" -> “Import Library…” -> “Add Library…”,搜索并安装DwPixelFlow库。

  3. 导入声音库:同样地,搜索并安装Minim库,用于处理声音输入。

效果展示

在这里插入图片描述

代码结构

我们的项目将包含以下几个主要部分:

  1. 设置窗口和基本参数:定义窗口大小、背景色和线条颜色。
  2. 声音输入设置:使用Processing的AudioInAmplitude类来获取麦克风输入的音频振幅。
  3. 流体模拟设置:初始化PixelFlow库,创建流体对象,并设置其参数。
  4. 太极图案设置:创建太极对象,并为其分配绘制层。
  5. 主循环:在draw函数中更新流体模拟和太极图案。

代码解析

第一部分:导入库和设置基本参数

import com.thomasdiewald.pixelflow.java.DwPixelFlow;
import com.thomasdiewald.pixelflow.java.fluid.DwFluid2D;

import processing.core.*;
import processing.opengl.PGraphics2D;
import processing.sound.*;

int viewport_w = 600; // 定义窗口宽
int viewport_h = 600; // 定义窗口高
color bg_color = #FFFFFF; // 背景色
color line_color = #000000; // 线条颜色

DwFluid2D fluid; // 流体
PGraphics2D pg_fluid; // 流体层

// 声音麦克风输入
AudioIn audioIn;
// 振幅-音量
Amplitude rms;

Taichi taichi; // 太极
PGraphics2D pg_taichi;  // 太极图层
PGraphics2D pg_obstacles; // 障碍物
float taichi_radius = 100;

void settings() {
  size(viewport_w, viewport_h, P2D);
}

void setup() {
  background(bg_color);
  frameRate(60);

  // 设定声音
  setupSound();
  // 设置流体参数
  setupFluid();

  // 设置太极图
  setupTaichi();
}

void setupSound() {
  audioIn = new AudioIn(this, 0);
  audioIn.play();

  rms = new Amplitude(this);
  rms.input(audioIn);
}

void setupFluid() {
  // 初始化pixelflow
  DwPixelFlow context = new DwPixelFlow(this);
  context.print();
  context.printGL();

  // 流体模拟
  fluid = new DwFluid2D(context, width, height, 1);
  fluid.param.dissipation_velocity = 0.70f;
  fluid.param.dissipation_density  = 0.60f;

  fluid.addCallback_FluiData(new MyFluidData(rms));

  // 流体层
  pg_fluid = (PGraphics2D)createGraphics(width, height, P2D);

  // 障碍物层
  pg_obstacles = (PGraphics2D)createGraphics(viewport_w, viewport_h, P2D);
  pg_obstacles.smooth(4);
}

void setupTaichi() {
  pg_taichi = (PGraphics2D)createGraphics(viewport_w, viewport_h, P2D);
  pg_taichi.smooth(4);

  taichi = new Taichi(new PVector(width / 2, height / 2), 100, pg_taichi, rms);
}

void draw() {
  // 流体更新
  drawFluid();
  // 太极图
  drawTaichi();
}

void drawFluid() {
  // 绘制障碍物
  drawObstacles();

  // 给流体增加障碍物
  fluid.addObstacles(pg_obstacles);
  // 流体更新
  fluid.update();
  fluid.renderFluidTextures(pg_fluid, 0);

  // 显示流体层
  image(pg_fluid, 0, 0);
  // 显示障碍物层
  image(pg_obstacles, 0, 0);
}

void drawObstacles() {
  pg_obstacles.beginDraw();
  pg_obstacles.blendMode(REPLACE);
  pg_obstacles.clear();

  float x = width * 0.5;
  float y = height * 0.5;
  pg_obstacles.pushMatrix();
  pg_obstacles.translate(x, y);
  pg_obstacles.stroke(line_color);
  pg_obstacles.strokeWeight(2);
  pg_obstacles.noFill();
  pg_obstacles.circle(0, 0, 500);
  pg_obstacles.popMatrix();

  pg_obstacles.endDraw();
}

void drawTaichi() {
  pg_taichi.beginDraw();
  pg_taichi.blendMode(REPLACE);
  pg_taichi.clear();

  pg_taichi.pushMatrix();
  taichi.display();
  pg_taichi.popMatrix();

  pg_taichi.endDraw();

  image(pg_taichi, 0, 0);
}

第二部分:流体类定义

从您提供的代码看来,这段代码是用于在Processing环境中结合DwFluid库创建一个模拟流体的视觉效果的。代码中涉及到很多类和方法,主要包含以下几个方面:

  1. MyFluidDataConfig 类:用于配置流体运动的参数,比如圆的位置、半径、运动的角度和速度以及颜色等。

  2. MyFluidData 类:实现了 DwFluid2D.FluidData 接口,用于更新流体物理仿真的状态,同时整合声音输入作为流体动态变化的一部分。

  3. my_update 方法:是流体物理仿真更新的核心,它计算流体粒子的速度和位置,并且将这些数据传递给流体库来模拟流动。

现在,让我们进一步分析并解释每个部分的作用以及如何操作。

MyFluidDataConfig 类详解

这个类定义了流体仿真所需要的一些配置参数。例如:

  • x, y: 圆心位置。
  • radius: 半径。
  • isClockwise: 定义旋转方向。
  • angleSpeed: 角速度。
  • rx, ry, prx, pry: 当前和之前的位置坐标。
  • angle: 当前角度。
  • c: 颜色。

MyFluidData 类详解

此类使用 MyFluidDataConfig 中定义的配置来创建两个配置对象 config1config2。它们负责控制流体仿真中两个独立的流动体的行为。此外,它接收一个Amplitude对象(rms),它可能用于分析音频信号并将其影响应用于流体动画。

my_update 方法详解

这个方法是每一帧都会调用的,用于更新流体的状态。步骤如下:

  1. 使用极坐标计算弧上点的位置。
  2. 随机量产生抖动,使流动效果更自然。
  3. 计算速度,并根据是否顺时针调整y轴速度。
  4. 将计算的位置和速度用来更新流体对象的状态。
  5. 根据声音级别调整流体密度的半径大小。
  6. 添加颜色和密度到流体中。

流体类定义完整代码

public class MyFluidDataConfig {
  float x;  // 圆心位置x
  float y; // 圆心位置y
  float radius = 100; // 半径
  boolean isClockwise; // 是否是顺时针
  float angleSpeed = 0.04;
  float rx, ry, prx, pry; // 圆周运动,弧上的点位置,以及上一帧的点位置
  float angle = 0; // 角度
  color c; // 颜色
}


public class MyFluidData implements DwFluid2D.FluidData {
  MyFluidDataConfig config1;
  MyFluidDataConfig config2;
  Amplitude rms;

  MyFluidData(Amplitude rms) {
    this.rms = rms;
    
    float x1 = width * 0.5;
    float y1 = height * 0.5;
    
    config1 = new MyFluidDataConfig();
    config1.x = x1;
    config1.y = y1;
    config1.radius = 130;
    config1.isClockwise = true;
    config1.angleSpeed = 0.05;
    config1.c = color(0.0, 0.0, 0.0);
    config1.angle = PI / 2;

    config2 = new MyFluidDataConfig();
    config2.x = x1;
    config2.y = y1;
    config2.radius = 130;
    config2.isClockwise = true;
    config2.angleSpeed = 0.04;
    config2.c = color(0.0, 0.0, 0.0);
    config2.angle = - PI / 2;
  }

  void my_update(DwFluid2D fluid, MyFluidDataConfig config) {
    float vscale = 14;
    
    float soundLevel = rms.analyze() * 1000;

    float delta = random(-3, 3);
    // 极坐标下计算弧上点的位置,用一个随机量进行抖动
    config.rx = config.x + (config.radius + delta) * cos(config.angle); 
    config.ry = config.y + (config.radius + delta) * sin(config.angle);

    // 计算速度
    float vx = (config.rx - config.prx) * vscale;
    float vy = (config.ry - config.pry) * vscale;
    // 顺时针的话,需要乘以-1,因为y轴相反
    if (config.isClockwise) {
      vy = (config.ry - config.pry) * (-vscale);
    }

    float px = config.rx;
    float py = config.ry;
    // 顺时针的话,需要乘以-1,因为y轴相反
    if (config.isClockwise) {
      py = height - config.ry;
    }

    // 给流体上的点添加速度
    fluid.addVelocity(px, py, 16, vx, vy);
    
    float radius1 = map(soundLevel, 10, 600, 15, 20);
    float radius2 = map(soundLevel, 10, 500, 8, 12);
    println(soundLevel, radius1, radius2);
    
    // 给流体上的点添加密度,颜色为c,半径为radius1,稍微大点
    fluid.addDensity(px, py, radius1, red(config.c) / 255.0, green(config.c) / 255.0, blue(config.c) / 255.0, 1.0f);
    // 给流体上的点添加密度,颜色为白色,半径为radius2,稍微小点
    fluid.addDensity(px, py, radius2, 1.0f, 1.0f, 1.0f, 1.0f);
    //fluid.addTemperature(px, py, 30, 10);

    // 现在终将成为过去
    config.prx = config.rx;
    config.pry = config.ry;

    // 增加弧度角,用于下一帧计算,才能旋转
    float angleSpeed = constrain(radians(soundLevel * 0.03), 0.01, 0.08) * 3;
    println(soundLevel, angleSpeed);
    config.angle += angleSpeed;
  }

  @Override
    public void update(DwFluid2D fluid) {
    my_update(fluid, config1);
    my_update(fluid, config2);
  }
}

第三部分:太极类定义

太极类定义完整代码

class Taichi {
  
  PVector location;
  float radius;
  PGraphics2D pg;
  float angle = 0;
  Amplitude rms;  

  Taichi(PVector location, float radius, PGraphics2D pg, Amplitude rms) {
    this.location = location;
    this.radius = radius;
    this.pg = pg;
    this.rms = rms;
  }

  void display() {
    float d = 2 * radius;
    float soundLevel = rms.analyze();
    angle += TWO_PI/360 * soundLevel * 20+6;
    
    pg.noStroke();
    pg.translate(location.x, location.y);  // 平移坐标系,方便使用相对位置进行绘制
    pg.rotate(angle);
    pg.fill(0);
    pg.arc(0, 0, d, d, PI / 2, PI * 3 / 2);

    pg.fill(255);
    pg.arc(0, 0, d, d, -PI / 2, PI / 2);

    pg.fill(255);
    pg.circle(0, d / 4, radius);

    pg.fill(0);
    pg.circle(0, -d / 4, radius);

    pg.fill(0);
    pg.circle(0, d / 4, radius / 5);

    pg.fill(255);
    pg.circle(0, -d / 4, radius / 5);
  }
}

结语

通过本教程,您将学习到如何结合Processing的声音输入和PixelFlow的流体模拟功能,创建一个动态的太极动画。您可以根据自己的创意进一步扩展这个项目,例如添加更多的交互元素或改变流体的行为。记得在编写代码时保持耐心,实践是学习编程的最佳方式。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1656389.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

信创基础软件之中间件

信创基础软件之中间件 中间件概述 中间件是一种应用于分布式系统的基础软件,位于应用与操作系统、数据库之间,主要用于解决分布式环境下数据传输、数据访问、应用调度、系统构建和系统集成、流程管理等问题,是分布式环境下支撑应用开发、运…

深圳CPDA|如何利用数据分析改进业务流程,提高效率?

在当今数字化时代,数据已经成为企业决策和优化的关键资源。通过有效地收集、分析和应用数据,企业可以深入了解其业务流程中的瓶颈和问题,从而改进流程,提高效率。本文将探讨如何利用数据分析改进业务流程,并提高效率。…

FebHost:什么是.ME域名?

.ME域名是一个独一无二且被广泛接受的顶级域名(TLD),在近年来逐渐受到了大众的喜爱。最初,它被设定为黑山的国家/地区代码顶级域名(ccTLD)。但现在,.ME已经发展成为一个全球公认的顶级域名&…

Python应用:让生活更智能

随着科技的进步,Python已成为一种非常受欢迎的编程语言,它在数据分析、人工智能、Web开发等领域有着广泛的应用。今天,我们将探讨一个Python应用的例子,这个应用将帮助我们更智能地管理日常生活。 应用名称:智能生活助…

鸿蒙开发接口Ability框架:【@ohos.application.StartOptions (StartOptions)】

StartOptions StartOptions模块对系统的基本通信组件进行查询和设置的能力。 说明: 本模块首批接口从API version 9 开始支持。后续版本的新增接口,采用上角标单独标记接口的起始版本。 本模块接口仅可在Stage模型下使用。 开发前请熟悉鸿蒙开发指导文档…

CentOS 重启网络失败service network restart

命令 service network restart 提示 Job for network.service failed because the control process exited with error code. See “systemctl status network.service” and “journalctl -xe” for details. 原因分析 使用journalctl -xe命令查看日志后的具体错误 -- Un…

STM32单片机实战开发笔记-PWM波输出频率及占空比配置【wulianjishu666】

单片机物联网开发资料: 链接:https://pan.baidu.com/s/1XzodQuML7CqZ4ZKinDGKkg?pwdbgep 提取码:bgep PWM模块测试 功能描述 脉冲宽度调制模式: PWM边沿对齐模式: 向上计数配置 当TIMX_CR1寄存器中的DIR为低的时…

AD3552/AD3551驱动开发

开发环境:Vivado2021.2 ; Windows with Cygwin HDL版本:hdl_2021_r2 GitHub - analogdevicesinc/hdl at hdl_2021_r2 no-OS版本:no_OS-2021_R2 GitHub - analogdevicesinc/no-OS at 2021_R2 1.创建hdl 详细步骤参见参考链接1&#xf…

基于PHP高考志愿填报系统搭建私有化部署源码

金秋志愿高考志愿填报系统是一款为高中毕业生提供志愿填报服务的在线平台。该系统旨在帮助学生更加科学、合理地选择自己的大学专业和学校,从而为未来的职业发展打下坚实的基础。 该系统的主要功能包括:报考信息查询、志愿填报数据指导、专业信息查询、院校信息查询…

Allegro如何输出器件坐标文件

如何输出器件坐标文件 1、选择菜单栏File(文件)→Placement…(放置) 2、跳出下面的对话框,选择原点位置在Body Center(几何中心),然后选择Export(导出)&…

教练预约管理小程序开发源码现成案例(小程序、APP、H5圆源码搭建)

随着人们对身体健康越来越重视,对强身健体、健康个性化生活的需求日益增加,健身已成为时尚生活的标志。 然而,没有时间去健身房却成了很多上班族的痛点。健身房作为一项既能缓解工作压力又能缓解学业压力的运动,正好满足了当代人…

数据分析——业务数据描述

业务数据描述 前言一、数据收集数据信息来源企业内部数据源市场调查数据源公共数据源和第三方数据源 二、公司内部数据客户资料数据销售明细数据营销活动数据 三、市场调查数据观察法提问法实验法 四、公共数据五、第三方数据六、数据预处理七、数据清洗丢弃部分数据补全缺失的…

前端双语实现方案(VUE版)

一、封装一个lib包 结构如下 en.js use strict;exports.__esModule true; exports.default {sp: {input: {amountError: Incorrect amount format},table: {total: Total:,selected: Selected:,tableNoData: No data,tableNoDataSubtext: Tip: Suggest to recheck your fil…

浅析安全用电监控系统在工厂的研究与应用论述

摘 要:随着社会时代的发展,人们的安全意识越来越强烈,在人们生活和工作中离不开各种用电设备,用电设备的安全使用是保障人们生命安全的重要内容。工厂因自身厂内工作环境的特殊性,用电设备的种类多且复杂,如…

云原生测试实战-云计算大数据云原生架构容器技术Kubernetes计算机软件工程软件开发

系列文章目录 送书第一期 《用户画像:平台构建与业务实践》 送书活动之抽奖工具的打造 《获取博客评论用户抽取幸运中奖者》 送书第二期 《Spring Cloud Alibaba核心技术与实战案例》 送书第三期 《深入浅出Java虚拟机》 送书第四期 《AI时代项目经理成长之道》 …

AC/DC电源模块在通信与网络设备中的应用研究

BOSHIDA AC/DC电源模块在通信与网络设备中的应用研究 随着通信与网络技术的不断发展,通信与网络设备的使用不断增加。电源作为通信与网络设备的重要组成部分之一,在其稳定工作中起到至关重要的作用。AC/DC电源模块作为一种常用的电源转换器,…

信创 | 区块链技术在信创建设中的应用前景

区块链技术在信创建设中的应用前景是广阔的。首先,区块链技术具有去中心化、可追溯和不可篡改等特性,这些特性使其在数据可信、共享、共治和共同维护以增强信任的应用场景中具有显著优势。特别是在数字政务建设中,区块链技术能够有效解决信任…

Spring Boot集成Ldap快速入门Demo

1.Ldap介绍 LDAP,Lightweight Directory Access Protocol,轻量级目录访问协议. LDAP是一种特殊的服务器,可以存储数据数据的存储是目录形式的,或者可以理解为树状结构(一层套一层)一般存储关于用户、用户…

多规格产品应该如何设置呢?

今天一用户从供应商手中拿到产品价目表,但是设置起来蒙圈了,接下来我们就一起设置一下吧~ 一、产品价格表 我们通过供应商手中拿到产品价目表是这个样子的: 我们可以看到此产品的销售客价根据不同地区导致的价格不同&#xff0…

环绕数字化学校,打造四个体系

近年来,各地学校活跃顺应“互联网教育”发展大势,大力开展数字化学校建造,在投入上都设有专项资金,很多学校现在信息化教育设施已满意现行教育教育要求。学校环绕数字化学校着力打造四个体系,即教育教务管理体系、协同…