Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

224
Visualizações
Cómo suavizar los rastros de las partículas en una simulación p5js

Quiero convertir estos rastros intermitentes y discontinuos en la partícula en esta simulación

ingrese la descripción de la imagen aquí

a algo digno de contemplar como en este hermoso flujo de campo aquí (no es mi trabajo, pero no recuerdo de dónde lo obtuve).

Probé diferentes permutaciones del código en el flujo de campo logrado sin obtener nada remotamente parecido a la suavidad en las transiciones que buscaba. Sospecho que estoy manejando mal las actualizaciones o la ubicación del rectángulo negro que parece eludir la necesidad de un fondo negro, que borraría la estela de las partículas.

 const scl = 45; var cols, rows; var particles = []; var flowfield; function setup() { createCanvas(750, 750); cols = ceil( width / scl ); rows = ceil( height / scl ); flowfield = new Array( cols * rows ); for (var i = 0; i < 1000; i ++ ) { particles[i] = new Particle(); } } function draw() { translate(height / 2, height / 2); //moves the origin to center scale( 1, - 1 ); //flips the y values so y increases "up" rect(-width,-height,2*width,2*height); for ( var y = 0; y < rows; y ++ ) { for ( var x = 0; x < cols; x ++ ) { var index = x + y * cols; let vX = x * 2 - cols; let vY = y * 2 - rows; var v = createVector( vY, -vX ); v.normalize(); flowfield[index] = v; // The following push() / pull() affects only the arrows push(); translate(x*scl-width/2,y*scl-height/2); fill(255); stroke(255); rotate(v.heading()); line(0,0,0.5*scl,0); let arrowSize = 7; translate(0.5*scl - arrowSize, 0); triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0); pop(); // The preceding push() / pull() affects only the arrows }// Closes inner loop }// Closes outer loop to create vectors and index. //This next loop actually creates the desired particles: for (var i = 0; i < particles.length; i++) { particles[i].follow(flowfield); particles[i].update(); particles[i].edges(); particles[i].show(); } } // End of the function draw class Particle { constructor() { // changed startpostion. Since the origin is in the center of the canvas, // the x goes from -width/2 to width/2 // the y goes from -height/2 to height/2 // i also changed this in this.edges(). this.pos = createVector( random( - width / 2, width / 2 ), random( - height / 2, height / 2 ) ); this.vel = createVector( 0, 0 ); this.acc = createVector( 0, 0 ); this.maxspeed = 4; this.steerStrength = 30; this.prevPos = this.pos.copy(); this.size = 2; } update() { this.vel.add( this.acc ); this.vel.limit( this.maxspeed ); this.pos.add( this.vel ); this.acc.mult( 0 ); fill(255) circle( this.pos.x, this.pos.y, this.size ); } follow( vectors ) { var x = floor( map( this.pos.x, - width / 2, width / 2, 0, cols - 1, true ) ); var y = floor( map( this.pos.y, - height / 2, height / 2, 0, rows - 1, true ) ); var index = ( y * cols ) + x; var force = vectors[ index ].copy(); force.mult( this.steerStrength ); this.applyForce( force ); } applyForce( force ) { this.acc.add( force ); } show() { noStroke(); fill(0,5) // you can just draw on the position. this.updatePrev(); } updatePrev() { this.prevPos.x = this.pos.x; this.prevPos.y = this.pos.y; } edges() { //clamp between -width/2 and width/2. -height/2 and height/2 if ( this.pos.x > width / 2 ) { this.pos.x = - width / 2; this.updatePrev(); } if ( this.pos.x < - width / 2 ) { this.pos.x = width / 2; this.updatePrev(); } if ( this.pos.y > height / 2 ) { this.pos.y = - height / 2; this.updatePrev(); } if ( this.pos.y < - height / 2 ) { this.pos.y = height / 2; this.updatePrev(); } } }

Como seguimiento, bajé a lo básico para poder combinar de manera más adecuada el código en la simulación vinculada a continuación con el código inicial, incorporando las ideas en la respuesta aceptada. this.maxspeed = 3 (solo en 1). Me deshice del show() y update() dentro de la class Particle , dejando solo update() como en el ejemplo proporcionado en el OP.

Aquí está para comparar:

 const scl = 45 var cols, rows; var particles = []; var flowfield; function setup() { createCanvas(750, 750); cols = ceil( width / scl ); rows = ceil( height / scl ); flowfield = new Array( cols * rows ); for (var i = 0; i < 1000; i ++ ) { particles[i] = new Particle(); } } function draw() { translate(height / 2, height / 2); //moves the origin to center scale(1, -1); //flips the y values so y increases "up" fill(0, 10); rect(-width, -height, 2*width, 2*height ); for ( var y = 0; y < rows; y ++ ) { for ( var x = 0; x < cols; x ++ ) { var index = x + y * cols; let vX = x * 2 - cols; let vY = y * 2 - rows; var v = createVector( vY, -vX ); v.normalize(); flowfield[index] = v; // The following push() / pull() affects only the arrows push(); translate(x*scl-width/2,y*scl-height/2); fill(255); stroke(255); rotate(v.heading()); line(0,0,0.5*scl,0); let arrowSize = 7; translate(0.5*scl - arrowSize, 0); triangle(0, arrowSize / 2, 0, -arrowSize / 2, arrowSize, 0); pop(); // The preceding push() / pull() affects only the arrows }// Closes inner loop }// Closes outer loop to create vectors and index. //This next loop actually creates the desired particles: for (var i = 0; i < particles.length; i++) { particles[i].follow(flowfield); particles[i].update(); particles[i].edges(); } } // End of the function draw class Particle { constructor() { this.pos = createVector( random( - width / 2, width / 2 ), random( - height / 2, height / 2 ) ); this.vel = createVector( 0, 0 ); this.acc = createVector( 0, 0 ); this.maxspeed = 3; this.steerStrength = 30; this.prevPos = this.pos.copy(); this.size = 4; } update() { this.vel.add( this.acc ); this.vel.limit( this.maxspeed ); this.pos.add( this.vel ); this.acc.mult( 0 ); noStroke(); fill(255) circle(this.pos.x, this.pos.y, this.size); } follow(vectors) { var x = floor( map( this.pos.x, - width / 2, width / 2, 0, cols - 1, true ) ); var y = floor( map( this.pos.y, - height / 2, height / 2, 0, rows - 1, true ) ); var index = (y * cols) + x; var force = vectors[index].copy(); force.mult(this.steerStrength); this.applyForce(force); } applyForce( force ) { this.acc.add(force); } updatePrev() { this.prevPos.x = this.pos.x; this.prevPos.y = this.pos.y; } edges() { //clamp between -width/2 and width/2. -height/2 and height/2 if ( this.pos.x > width / 2 ) { this.pos.x = - width / 2; this.updatePrev(); } if ( this.pos.x < - width / 2 ) { this.pos.x = width / 2; this.updatePrev(); } if ( this.pos.y > height / 2 ) { this.pos.y = - height / 2; this.updatePrev(); } if ( this.pos.y < - height / 2 ) { this.pos.y = height / 2; this.updatePrev(); } } }

Finalmente me conformé con un par de ilustraciones con diferente atracción ejercida por el campo vectorial sobre las partículas: this.steerStrength = 0.1; (partículas sueltas) versus this.steerStrength = 30; (aferrándose a los vectores):

Tirador suelto (más llamativo):

ingrese la descripción de la imagen aquí

Código aquí .

Más compacto o fiel a los vectores guía:

ingrese la descripción de la imagen aquí

con código aquí .

over 4 years ago · Santiago Trujillo
2 Respostas
Responde à pergunta

0

Puede obtener pruebas de varias maneras. El boceto que mencionaste crea los senderos al agregar opacidad al fondo con la función "rellenar (0, 10)".

Si desea saber más sobre las funciones de p5, siempre puede buscarlas aquí: https://p5js.org/reference/ . La página fill() muestra que el primer argumento es el color (0 para negro) y el segundo argumento es la opacidad (10 de 255).

En el boceto que mencionaste, en draw(), escribieron:

 fill( 0, 10 ); noStroke(); rect( 0, 0, width, height );

Dibuja un rectángulo negro semitransparente sobre el lienzo, pero también puedes usar:

 background( 0, 10 );

En la clase de partículas puedes dibujar la partícula con el color que quieras, por ejemplo:

 fill( 255 ); //white color circle( this.pos.x, this.pos.y, this.size );

Todavía no es tan suave como el boceto con maxSpeed establecido en 4, si lo reduce a 2, por ejemplo, ya se verá mejor.

Veo que también hay un prevPos en tu código. Esa es otra forma de dibujar senderos; conecte this.prevPos y this.pos con una línea. es común tener una variedad de posiciones anteriores para conectarse de esa manera.

Solo hay un problema, cuando las partículas salen de la pantalla y se colocan en el otro lado, hay una línea que va de un lado del lienzo al otro. Puede solucionar esto, pero el fondo transparente es más fácil.

over 4 years ago · Santiago Trujillo Relatório

0

Puedes usar:

 background(255, 10)

que: 255 es el número de color; 10 es el color alfa (opacidad);

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda