![](/img/trans.png)
[英]Need help converting my Processing code to p5.js (ArrayList + others!)
[英]Need help converting .PDE to P5.js
我是這兩種語言的新手,我正在嘗試將我在 github 上找到並編輯的這個程序轉換為 p5.js,以便我可以將它包含在網頁中。 我嘗試遵循指南並將 void() 替換為 function(),將 int i 替換為 var i 等。但似乎有問題。 第一個代碼是原始的 .pde,第二個是我嘗試轉換的代碼。 非常感謝!
final int STAGE_WIDTH = 1200;
final int STAGE_HEIGHT = 950;
final int NB_PARTICLES = 60000;
final float MAX_PARTICLE_SPEED = 5;
final int MIN_LIFE_TIME = 20;
final int MAX_LIFE_TIME = 80;
final String IMAGE_PATH = "starrynight.jpg";
myVector tabParticles[];
float particleSize = 1.2;
PImage myImage;
int imageW;
int imageH;
color myPixels[];
FlowField ff;
GUI gui;
void setup()
{
size(1200, 950, P3D);
background(0);
initializeImage();
initializeParticles();
ff = new FlowField(5);
gui = new GUI(this);
gui.setup();
}
void initializeImage()
{
myImage = loadImage(IMAGE_PATH);
imageW = myImage.width;
imageH = myImage.height;
myPixels = new color[imageW * imageH];
myImage.loadPixels();
myPixels = myImage.pixels;
image(myImage, 0, 0);
}
void setParticle(int i) {
tabParticles[i] = new myVector((int)random(imageW), (int)random(imageH));
tabParticles[i].prevX = tabParticles[i].x;
tabParticles[i].prevY = tabParticles[i].y;
tabParticles[i].count = (int)random(MIN_LIFE_TIME, MAX_LIFE_TIME);
tabParticles[i].myColor = myPixels[(int)(tabParticles[i].y)*imageW + (int)(tabParticles[i].x)];
}
void initializeParticles()
{
tabParticles = new myVector[NB_PARTICLES];
for (int i = 0; i < NB_PARTICLES; i++)
{
setParticle(i);
}
}
void draw()
{
ff.setRadius(gui.getR());
ff.setForce(gui.getF());
particleSize = gui.getS();
float vx;
float vy;
PVector v;
for (int i = 0; i < NB_PARTICLES; i++)
{
tabParticles[i].prevX = tabParticles[i].x;
tabParticles[i].prevY = tabParticles[i].y;
v = ff.lookup(tabParticles[i].x, tabParticles[i].y);
vx = v.x;
vy = v.y;
vx = constrain(vx, -MAX_PARTICLE_SPEED, MAX_PARTICLE_SPEED);
vy = constrain(vy, -MAX_PARTICLE_SPEED, MAX_PARTICLE_SPEED);
tabParticles[i].x += vx;
tabParticles[i].y += vy;
tabParticles[i].count--;
if ((tabParticles[i].x < 0) || (tabParticles[i].x > imageW-1) ||
(tabParticles[i].y < 0) || (tabParticles[i].y > imageH-1) ||
tabParticles[i].count < 0) {
setParticle(i);
}
strokeWeight(1.5*particleSize);
stroke(tabParticles[i].myColor, 250);
line(tabParticles[i].prevX, tabParticles[i].prevY, tabParticles[i].x, tabParticles[i].y);
}
ff.updateField();
}
void mouseDragged() {
if(mouseX>950 && mouseY>830) return;
ff.onMouseDrag();
}
void keyPressed() {
//if (key =='s' || key == 'S') {
// ff.saveField();
//}
}
class myVector extends PVector
{
myVector (float p_x, float p_y) {
super(p_x, p_y);
}
float prevX;
float prevY;
int count;
color myColor;
}
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
class FlowField {
PVector[][] field;
PVector[][] tempField;
int cols, rows;
int resolution;
int affectRadius;
float force;
File file = new File(dataPath("field.txt"));
FlowField(int r) {
resolution = r;
cols = 1200 / resolution;
rows = 950 / resolution;
field = new PVector[cols][rows];
tempField = new PVector[cols][rows];
init();
affectRadius = 3;
force = 1;
}
void setRadius(int r) {
affectRadius = r;
}
void setForce(float f) {
force = f;
}
void init() {
try {
for (int i=0; i<cols; i++) {
for (int j=0; j<rows; j++) {
tempField[i][j] = new PVector(0, 0);
}
}
readField();
}
catch(Exception e) {
for (int i=0; i<cols; i++) {
for (int j=0; j<rows; j++) {
field[i][j] = new PVector(0, 0);
}
}
}
}
PVector lookup(float x, float y) {
int column = int(constrain(x/resolution, 0, cols-1));
int row = int(constrain(y/resolution, 0, rows-1));
return PVector.add(field[column][row],tempField[column][row]);
}
void drawBrush() {
pushStyle();
noFill();
stroke(255, 255, 255);
ellipse(mouseX, mouseY, affectRadius*10, affectRadius*10);
popStyle();
}
void drawField(float x, float y, PVector v) {
int column = int(constrain(x/resolution, 0, cols-1));
int row = int(constrain(y/resolution, 0, rows-1));
for (int i=-affectRadius; i<=affectRadius; i++) {
for (int j=-affectRadius; j<=affectRadius; j++) {
if (i*i+j*j<affectRadius*affectRadius) {
try {
tempField[column+i][row+j].add(v).mult(0.9);
}
catch(Exception e) {
}
}
}
}
}
void updateField(){
for (int i=0; i<cols; i++) {
for (int j=0; j<rows; j++) {
tempField[i][j].mult(0.992);
}
}
}
void onMouseDrag() {
PVector direc = new PVector(mouseX-pmouseX, mouseY-pmouseY).normalize();
drawField(pmouseX, pmouseY, direc.mult(force));
}
void saveField() {
try {
FileWriter out = new FileWriter(file);
for (int i=0; i<cols; i++) {
for (int j=0; j<rows; j++) {
out.write(field[i][j].x+","+field[i][j].y+"\t");
}
out.write("\r\n");
}
out.close();
}
catch(Exception e) {
}
}
void readField() throws IOException {
try {
BufferedReader in = new BufferedReader(new FileReader(file));
String line;
for (int i = 0; (line = in.readLine()) != null; i++) {
String[] temp = line.split("\t");
for (int j=0; j<temp.length; j++) {
String[] xy = temp[j].split(",");
float x = Float.parseFloat(xy[0]);
float y = Float.parseFloat(xy[1]);
field[i][j] = new PVector(x, y);
}
}
in.close();
}
catch(Exception e) {
throw new IOException("no field.txt");
}
}
}
import controlP5.*;
class GUI {
ControlP5 cp5;
Slider sliderR;
Slider sliderF;
Slider sliderS;
GUI(PApplet thePApplet){
cp5 = new ControlP5(thePApplet);
}
void setup(){
cp5.setColorBackground(0x141414);
sliderR = cp5.addSlider("Radius")
.setPosition(980,890)
.setRange(1,20)
.setValue(12).setSize(150,25);
sliderF = cp5.addSlider("Force")
.setPosition(980,918)
.setRange(0.1,0.5)
.setValue(0.3).setSize(150,25);
sliderS = cp5.addSlider("Particle Size")
.setPosition(980,862)
.setRange(0.8,2)
.setValue(1.5).setSize(150,25);
}
int getR(){
return int(sliderR.getValue());
}
float getF(){
return sliderF.getValue();
}
float getS(){
return sliderS.getValue();
}
}
final var STAGE_WIDTH = 1200;
final var STAGE_HEIGHT = 950;
final var NB_PARTICLES = 60000;
final let MAX_PARTICLE_SPEED = 5;
final var MIN_LIFE_TIME = 20;
final var MAX_LIFE_TIME = 80;
final let IMAGE_PATH = "starrynight.jpg";
myVector tabParticles[];
let particleSize = 1.2;
PImage myImage;
var imageW;
var imageH;
color myPixels[];
FlowField ff;
GUI gui;
function setup()
{
var canvas = createCanvas(1200, 950, P3D);
canvas.parent('canvasForHTML');
background(0);
initializeImage();
initializeParticles();
ff = new FlowField(5);
gui = new GUI(this);
gui.setup();
}
function preload() { img = loadImage('data/starrynight.jpg');
}
function initializeImage()
{ imageW = myImage.width;
imageH = myImage.height;
myPixels = new color[imageW * imageH];
myImage.loadPixels();
myPixels = myImage.pixels;
image(myImage, 0, 0);
}
function setParticle(var i) {
tabParticles[i] = new myVector((var)random(imageW), (var)random(imageH));
tabParticles[i].prevX = tabParticles[i].x;
tabParticles[i].prevY = tabParticles[i].y;
tabParticles[i].count = (var)random(MIN_LIFE_TIME, MAX_LIFE_TIME);
tabParticles[i].myColor = myPixels[(var)(tabParticles[i].y)*imageW + (var)(tabParticles[i].x)];
}
function initializeParticles()
{
tabParticles = new myVector[NB_PARTICLES];
for (var i = 0; i < NB_PARTICLES; i++)
{
setParticle(i);
}
}
function draw()
{
ff.setRadius(gui.getR());
ff.setForce(gui.getF());
particleSize = gui.getS();
let vx;
let vy;
PVector v;
for (var i = 0; i < NB_PARTICLES; i++)
{
tabParticles[i].prevX = tabParticles[i].x;
tabParticles[i].prevY = tabParticles[i].y;
v = ff.lookup(tabParticles[i].x, tabParticles[i].y);
vx = v.x;
vy = v.y;
vx = constrain(vx, -MAX_PARTICLE_SPEED, MAX_PARTICLE_SPEED);
vy = constrain(vy, -MAX_PARTICLE_SPEED, MAX_PARTICLE_SPEED);
tabParticles[i].x += vx;
tabParticles[i].y += vy;
tabParticles[i].count--;
if ((tabParticles[i].x < 0) || (tabParticles[i].x > imageW-1) ||
(tabParticles[i].y < 0) || (tabParticles[i].y > imageH-1) ||
tabParticles[i].count < 0) {
setParticle(i);
}
strokeWeight(1.5*particleSize);
stroke(tabParticles[i].myColor, 250);
line(tabParticles[i].prevX, tabParticles[i].prevY, tabParticles[i].x, tabParticles[i].y);
}
ff.updateField();
}
function mouseDragged() {
if(mouseX>950 && mouseY>830) return;
ff.onMouseDrag();
}
function keyPressed() {
//if (key =='s' || key == 'S') {
// ff.saveField();
//}
}
class myVector extends PVector
{
myVector (let p_x, let p_y) {
super(p_x, p_y);
}
let prevX;
let prevY;
var count;
color myColor;
}
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
class FlowField {
PVector[][] field;
PVector[][] tempField;
var cols, rows;
var resolution;
var affectRadius;
let force;
File file = new File(dataPath("field.txt"));
FlowField(var r) {
resolution = r;
cols = 1200 / resolution;
rows = 950 / resolution;
field = new PVector[cols][rows];
tempField = new PVector[cols][rows];
init();
affectRadius = 3;
force = 1;
}
function setRadius(var r) {
affectRadius = r;
}
function setForce(let f) {
force = f;
}
function init() {
try {
for (var i=0; i<cols; i++) {
for (var j=0; j<rows; j++) {
tempField[i][j] = new PVector(0, 0);
}
}
readField();
}
catch(Exception e) {
for (var i=0; i<cols; i++) {
for (var j=0; j<rows; j++) {
field[i][j] = new PVector(0, 0);
}
}
}
}
PVector lookup(let x, let y) {
var column = var(constrain(x/resolution, 0, cols-1));
var row = var(constrain(y/resolution, 0, rows-1));
return PVector.add(field[column][row],tempField[column][row]);
}
function drawBrush() {
pushStyle();
noFill();
stroke(255, 255, 255);
ellipse(mouseX, mouseY, affectRadius*10, affectRadius*10);
popStyle();
}
function drawField(let x, let y, PVector v) {
var column = var(constrain(x/resolution, 0, cols-1));
var row = var(constrain(y/resolution, 0, rows-1));
for (var i=-affectRadius; i<=affectRadius; i++) {
for (var j=-affectRadius; j<=affectRadius; j++) {
if (i*i+j*j<affectRadius*affectRadius) {
try {
tempField[column+i][row+j].add(v).mult(0.9);
}
catch(Exception e) {
}
}
}
}
}
function updateField(){
for (var i=0; i<cols; i++) {
for (var j=0; j<rows; j++) {
tempField[i][j].mult(0.992);
}
}
}
function onMouseDrag() {
PVector direc = new PVector(mouseX-pmouseX, mouseY-pmouseY).normalize();
drawField(pmouseX, pmouseY, direc.mult(force));
}
function saveField() {
try {
FileWriter out = new FileWriter(file);
for (var i=0; i<cols; i++) {
for (var j=0; j<rows; j++) {
out.write(field[i][j].x+","+field[i][j].y+"\t");
}
out.write("\r\n");
}
out.close();
}
catch(Exception e) {
}
}
function readField() throws IOException {
try {
BufferedReader in = new BufferedReader(new FileReader(file));
let line;
for (var i = 0; (line = in.readLine()) != null; i++) {
let[] temp = line.split("\t");
for (var j=0; j<temp.length; j++) {
let[] xy = temp[j].split(",");
let x = let.parselet(xy[0]);
let y = let.parselet(xy[1]);
field[i][j] = new PVector(x, y);
}
}
in.close();
}
catch(Exception e) {
throw new IOException("no field.txt");
}
}
}
import controlP5.*;
class GUI {
ControlP5 cp5;
Slider sliderR;
Slider sliderF;
Slider sliderS;
GUI(PApplet thePApplet){
cp5 = new ControlP5(thePApplet);
}
function setup(){
cp5.setColorBackground(0x141414);
sliderR = cp5.addSlider("Radius")
.setPosition(980,890)
.setRange(1,20)
.setValue(12).setSize(150,25);
sliderF = cp5.addSlider("Force")
.setPosition(980,918)
.setRange(0.1,0.5)
.setValue(0.3).setSize(150,25);
sliderS = cp5.addSlider("Particle Size")
.setPosition(980,862)
.setRange(0.8,2)
.setValue(1.5).setSize(150,25);
}
var getR(){
return var(sliderR.getValue());
}
let getF(){
return sliderF.getValue();
}
let getS(){
return sliderS.getValue();
}
}
今天晚上我什么都不想做,所以你去吧:
另外,我建議為your code editor of choice
獲取“更好的評論”擴展/插件,因為我在這里使用了很多
const STAGE_WIDTH = 1200;
const STAGE_HEIGHT = 950;
const NB_PARTICLES = 60000;
const MAX_PARTICLE_SPEED = 5;
const MIN_LIFE_TIME = 20;
const MAX_LIFE_TIME = 80;
const IMAGE_PATH = "starrynight.jpg";
let tabParticles = [];
let particleSize = 1.2;
let myImage;
let imageW;
let imageH;
let myPixels = [];
let ff;
let gui;
function setup()
{
size(1200, 950, WEBGL);
background(0);
initializeImage();
initializeParticles();
ff = new FlowField(5);
// ! CHANGE THIS AND ALL OF THE OTHER GUI STUFF THAT COME AFTER IT!
// gui = new GUI(this);
// gui.setup();
}
function initializeImage()
{
myImage = loadImage(IMAGE_PATH);
imageW = myImage.width;
imageH = myImage.height;
myPixels = new color[imageW * imageH]; // ? dunno
// myImage.loadPixels();
// myPixels = myImage.pixels;
image(myImage, 0, 0);
}
function setParticle(i) {
tabParticles[i] = new myVector(random(imageW), random(imageH));
tabParticles[i].prevX = tabParticles[i].x;
tabParticles[i].prevY = tabParticles[i].y;
tabParticles[i].count = random(MIN_LIFE_TIME, MAX_LIFE_TIME);
tabParticles[i].myColor = myPixels[(int)(tabParticles[i].y)*imageW + (int)(tabParticles[i].x)];
}
function initializeParticles()
{
// tabParticles = new myVector[NB_PARTICLES];
for(let i = 0; i < NB_PARTICLES; i ++)
tabParticles.push(new myVector())
for (let i = 0; i < NB_PARTICLES; i++)
{
setParticle(i);
}
}
function draw()
{
ff.setRadius(gui.getR());
ff.setForce(gui.getF());
particleSize = gui.getS();
let vx;
let vy;
let v;
for (let i = 0; i < NB_PARTICLES; i++)
{
tabParticles[i].prevX = tabParticles[i].x;
tabParticles[i].prevY = tabParticles[i].y;
v = ff.lookup(tabParticles[i].x, tabParticles[i].y);
vx = v.x;
vy = v.y;
vx = constrain(vx, -MAX_PARTICLE_SPEED, MAX_PARTICLE_SPEED);
vy = constrain(vy, -MAX_PARTICLE_SPEED, MAX_PARTICLE_SPEED);
tabParticles[i].x += vx;
tabParticles[i].y += vy;
tabParticles[i].count--;
if ((tabParticles[i].x < 0) || (tabParticles[i].x > imageW-1) ||
(tabParticles[i].y < 0) || (tabParticles[i].y > imageH-1) ||
tabParticles[i].count < 0) {
setParticle(i);
}
strokeWeight(1.5*particleSize);
stroke(tabParticles[i].myColor, 250);
line(tabParticles[i].prevX, tabParticles[i].prevY, tabParticles[i].x, tabParticles[i].y);
}
ff.updateField();
}
function mouseDragged() {
if(mouseX>950 && mouseY>830) return;
ff.onMouseDrag();
}
function keyPressed() {
//if (key =='s' || key == 'S') {
// ff.saveField();
//}
}
class myVector extends PVector
{
constructor (p_x, p_y) {
super(p_x, p_y);
this.prevX
this.prevY
this.count
this.myColor
}
}
class FlowField {
constructor(r) {
this.field; // PVector[][]
this.tempField; // PVector[][]
this.cols; this.rows; // int
this.resolution; // int
this.affectRadius; // int
this.force; // float
this.file = new File(dataPath("field.txt")); // File
// ! You'll need to have a preload loadStrings(filepath) or fetch(filename).then(blob => blob.text()).then(text => ... )
// ! can't be bothered to do this right now
throw "Ult1: change this!!! also delete this line (just incase: ~129th line)"
resolution = r;
cols = 1200 / resolution;
rows = 950 / resolution;
field = new PVector[cols][rows];
tempField = new PVector[cols][rows];
init();
affectRadius = 3;
force = 1;
}
setRadius(r) {
affectRadius = r;
}
setForce(f) {
force = f;
}
// FROM HERE ON I CONVERTED IT WHILE HALF ASLEEP (11pm)
init() {
try {
for (let i=0; i<cols; i++) {
for (let j=0; j<rows; j++) {
tempField[i][j] = createVector()
}
}
readField();
}
catch(e) {
for (let i=0; i<cols; i++) {
for (let j=0; j<rows; j++) {
field[i][j] = createVector()
}
}
}
}
lookup(x, y) {
let column = int(constrain(x/resolution, 0, cols-1));
let row = int(constrain(y/resolution, 0, rows-1));
return p5.Vector.add(field[column][row],tempField[column][row]);
}
drawBrush() {
pushStyle();
noFill();
stroke(255, 255, 255);
ellipse(mouseX, mouseY, affectRadius*10, affectRadius*10);
popStyle();
}
drawField(x, y, v) {
let column = int(constrain(x/resolution, 0, cols-1));
let row = int(constrain(y/resolution, 0, rows-1));
for (let i=-affectRadius; i<=affectRadius; i++) {
for (let j=-affectRadius; j<=affectRadius; j++) {
if (i*i+j*j<affectRadius*affectRadius) {
try {
tempField[column+i][row+j].add(v).mult(0.9);
}
catch(e) {
}
}
}
}
}
updateField(){
for (let i=0; i<cols; i++) {
for (let j=0; j<rows; j++) {
tempField[i][j].mult(0.992);
}
}
}
onMouseDrag() {
let direc = createVector(mouseX-pmouseX, mouseY-pmouseY).normalize()
drawField(pmouseX, pmouseY, direc.mult(force));
}
saveField() {
try {
// FileWriter out = new FileWriter(file);
throw "FileWriter doesn't exist in Javascript, line: 215"
// ! this doesn't exist! in javascript, I don't remember how to do this, but you can just search it on Google
for (let i=0; i<cols; i++) {
for (let j=0; j<rows; j++) {
out.write(field[i][j].x+","+field[i][j].y+"\t");
}
out.write("\r\n");
}
out.close();
}
catch(e) {
}
}
readField() {
throw "once again, BufferedReader is just not a thing, but it's for file reading, so you can just loadString(\"file\") or fetch... line: 230"
try {
let _in = new BufferedReader(new FileReader(file));
let line;
for (let i = 0; (line = _in.readLine()) != null; i++) {
let temp = line.split("\t");
for (let j=0; j<temp.length; j++) {
let xy = temp[j].split(",");
let x = Float.parseFloat(xy[0]);
let y = Float.parseFloat(xy[1]);
field[i][j] = createVector(x, y);
}
}
_in.close();
}
catch(e) {
throw new IOException("no field.txt");
}
}
}
// I think you should just do this with html to be honest
// copy this into your body (below the <script src="sketch.js"></script>, or above it):
/*
<div id="GUI">
<label for="Radius">Radius</label>
<input type="range" name="Radius" id="slider-radius" min="1" max="20" step="0.5" value="10">
<br>
<label for="Force">Force</label>
<input type="range" name="Force" id="slider-force" min="0.1" max="0.5" step="0.01" value="0.3">
<br>
<label for="Particle-size">Particle size</label>
<input type="range" name="Particle-size" id="slider-particle-size" min="0.8" max="2" step="0.05" value="1.5">
</div>
<style>
html, body {
background-color: #141414;
}
label {
color: #ccc;
}
</style>
*/
// color: #ccc is the same as text-color = #CCCCCC in some other language, maybe...
class GUI {
constructor(){
throw "don't declare the GUI class, instead do GUI.getR(), GUI.getF() ... line: 288, you should be able to see line # in your console"
}
static getR(){
return document.getElementById("slider-radius").value;
}
static getF(){
return document.getElementById("slider-force").value
}
static getS(){
return document.getElementById("slider-particle-size").value
}
}
// static = same between ALL the classes(instances) of a class thing, so:
// class A { static x = 7; this.y = 5 }
// * console.log(A.x) -> 7
// ! console.log(A.y) -> probably null, since you need to do console.log(new A().y)
// here I have it to keep the GUI class, but there is no need to keep this stuff
您仍然需要做很多工作才能完成這項工作,例如翻譯類,例如class myVector extends PVector {...}
。 在 p5.js 中沒有 PVector,但我很確定有 p5.Vector,所以class myVector extends p5.Vector
可能會起作用。 文件讀取和寫入也會變得混亂,因為 JavaScript 沒有new File()
和所有類似的東西。
您還需要處理 CORS,祝您好運! 我還將大部分 GUI 內容更改為 .html 內容和一個靜態類,那里的詞有點難,但不能真正將它們更改為任何內容。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.