¿Cómo puedo hacer estos movimientos?

Quiero hacer un programa que genere cuadros como la imagen que se muestra a la derecha.
En este video muestro cómo es mi idea de movimiento para formar las figuras: https://youtu.be/tzWBDpG6hbM

Quiero saber cómo podría hacer que las lineas giren de esa manera.

Hola,

¡Bienvenido a la comunidad!

Cuando quieras hacer algo con Processing, un buen punto de partida es mirar primero la documentación de las funciones que te van a ayudar:

Este es un ejemplo de un programa: (con un poco de geometría para entender)

// The thickness of the lines
float thickness = 4;

// The number of lines
int nbLines = 15;

// The width of the first lines
int x = 0;

// The height of the first lines
int y = 100;

// The size of the "rectangle" formed by the lines
float rectSize = 50;

void setup(){
  size(500, 500);
}

void draw(){
  background(0);
  
  strokeWeight(thickness);
  
  // Use mouseX and mouseY to control the drawing
  x = mouseX;
  rectSize = map(mouseY, 0, height, 0, 100);
  
  for(int i=0; i<nbLines; i++){
    // Interpolate the color with the distance from the middle of the lines
    stroke(lerpColor(color(255), color(#EDE426), ((float) abs(nbLines/2 - i))/nbLines));
    
    // The offset of the end of the lines (the gap between them is twice the thickness)
    float lineOffset = (nbLines - i - 1) * thickness * 2;
    
    float x0 = x + lineOffset;
    float y0 = y + i * thickness * 2;
    line(0, y0, x0, y0);
    
    float y1 = y0 + rectSize + lineOffset * 2;
    line(x0, y0, x0, y1);
    
    float x2 = x0 - rectSize - lineOffset * 2;
    line(x0, y1, x2, y1);
    
    float y3 = y1 - rectSize - lineOffset;
    line(x2, y1, x2, y3);
  }
}

Capture d’écran de 2020-06-16 17-50-22

(Nota: lo siento, los comentarios están en inglés y esta entrada está traducida al español :slight_smile: )

2 Likes

En general, use interpolaciones basadas en listas (“list-based interpolations”) para animar rutas que pasan por una serie de puntos.

Luego puede definir los puntos por los que deben pasar sus dibujos.

Sin embargo, este tipo de problemas no son buenos para los principiantes.

El segundo ejemplo es aún más difícil, porque usa curvas y porque las diferentes líneas curvas pueden viajar a diferentes velocidades, dependiendo de cómo desee animarlas.

2 Likes

Thank you. It helped me a lot.
I spent several weeks trying :c
I will post more questions later hahaha xD

Graciaas!
No sé si soy principiante.
Estoy en segundo año de tecnología multimedia, pero a mí se me complica mucho.
Gracias, todas las respuestas me ayudan :smiley:

¿Algo como esto?

AnimatedPathTest_20200617195625

Puedo obtener algo así trabajando en Processing con una clase de ruta bastante grande y algunas reglas personalizadas, pero todavía es algo hecho a mano y mucho más complejo de lo que me gustaría.

¿Para qué es esto? ¿Es algo para su práctica de portafolio de arte y / o un proyecto escolar?

2 Likes

Es exactamente eso lo que quiero lograr, pero yo pensaba que podía hacerlo solo cambiando la dirección de un line().
Pero veo que eso no es posible, no?
Eso lo hiciste usando el ejemplo que mandaste anteriormente? Es que eso no me enseñaron, no creo que deba usarlo. Estamos usando objetos y diagramas de estado.
Es para un trabajo de la facultad, tengo que crear un código que haga cuadros similares (siempre distintos) a los que mandé en primer lugar.

Si, creo que no podía hacerlo solo cambiando la dirección de un line().

Eso lo hiciste usando el ejemplo que mandaste anteriormente?

Cerca, pero no exactamente. El concepto es un Path con lineas, y “crop” el Path en cada draw().

Aquí hay un ejemplo para una sola línea animada.

/**
 * AnimatedPathTestSimple
 * 2020-07-18 Jeremy Douglass -- Processing 3.5.4
 * 
 * Given a set of points, animate the drawing of that path
 * using the Path class.
 *
 * See: discourse.processing.org/t/como-puedo-hacer-estos-movimientos/21904/2
 */

Path path;
float strokew = 5;  // line settings
int cycle = 470;    // frames

void setup() {
  size(250, 250);
  strokeWeight(strokew);

  // pick waypoints
  PVector[] vecs = new PVector[]{
    new PVector(0, 100), 
    new PVector(200, 100), 
    new PVector(200, 200), 
    new PVector(100, 200), 
    new PVector(100, 100), 
  };

  // create Path
  path = new Path(vecs);
}

void draw() {
  background(0);

  // repeatedly advance from 0.0-1.0
  float amt = (frameCount/(float)cycle)%1.2;

  // crop the path to that distance
  PVector[] crop = path.crop2(amt);

  // draw each line segment of the cropped path
  stroke(255);
  trace(crop);
}

void trace(PVector[] path) {
  for (int i=1; i<path.length; i++) {
    if (path.length>1) {
      line(path[i-1].x, path[i-1].y, path[i].x, path[i].y);
    }
  }
}

class Path extends ArrayList<PVector> {
  /**
   * extra constructor to avoid requiring import for Arrays.asList
   */
  Path(PVector... vecs) {
    super();
    for (int i=0; i<vecs.length; i++) {
      add(vecs[i]);
    }
  }

  PVector[] crop(float dist) {
    return crop(0, dist, toArray(new PVector[]{}));
  }

  /** 
   *
   * @param   begin  path distance from first point to beginning
   * @param   end    path distance from first point to end
   * @return         index  
   */
  PVector[] crop(float begin, float end, PVector... vecs) {
    // if(end<=begin) return null;
    float len = dist();
    if (begin<0) begin=0;
    if (end>dist()) end = len;
    if (begin==0 && end==len) return toArray(new PVector[]{});

    int id1 = getSegmentID(begin);
    int id2 = getSegmentID(end);
    PVector[] cropped = (PVector[])subset(vecs, id1, id2 + 2);
    PVector last = getPoint(end-begin);
    cropped[cropped.length-1] = last;
    return cropped;
  }

  PVector[] crop2(float amt) {
    return crop(dist() * amt);
  }

  PVector[] crop2(float beginAmt, float endAmt, PVector... vecs) {
    return crop(dist() * beginAmt, dist() * endAmt, vecs);
  }

  /**
   * Total length of Path as linear distance through the points in order.
   **/
  float dist() {
    float d = 0;
    for (int i=0; i<this.size()-1; i++) {
      d += PVector.dist(get(i), get(i+1));
    }
    return d;
  }

  /**
   * An ordered list with the length of each Path segment.
   */
  float[] dists() {
    float[] lens = new float[this.size()-1];
    for (int i=0; i<this.size()-1; i++) {
      lens[i] = PVector.dist(get(i), get(i+1));
    }
    return lens;
  }

  PVector getPoint(float dist) {
    if (dist < 0 || dist>dist()) return null;
    //if(dist < 0) return get(0);
    //if(dist > length()) return get(size()-1);
    float[] lens = dists();
    float remain = dist;
    for (int i=0; i<lens.length; i++) {
      remain-=lens[i];
      if (remain<=0) {
        float amt = (remain+lens[i])/lens[i];
        PVector[] seg = getSegment(i);
        return PVector.lerp(seg[0], seg[1], amt);
      }
    }
    return new PVector(0, 0);
  }

  /**
   * Get a line segement composed of an array of two PVectors.
   * 
   * @param   idx    index of the segment
   * @return         segment array of two points [(x1, y1), (x2, v2)]
   */
  PVector[] getSegment(int idx) {
    return new PVector[] {get(idx), get(idx+1)};
  }

  /**
   * Get a line segement composed of an array of two PVectors.
   * 
   * @param   dist   distance from the first point on the Path
   * @return         array of two segment endpoints [(x1, y1), (x2, v2)]
   */
  PVector[] getSegment(float dist) {
    int idx = getSegmentID(dist);
    return getSegment(idx);
  }

  /**
   * Get the index of a line segment based on distance.
   * 
   * @param   dist   distance from the first point on the Path
   * @return         index  
   */
  int getSegmentID(float dist) {
    if (dist < 0 || dist>dist()) return -1;
    float[] lens = dists();
    for (int i=0; i<lens.length-1; i++) {
      dist-=lens[i];
      if (dist<=0) return i;
    }
    return lens.length-1;
  }

  /**
   * Get an array of each line segement.
   * 
   * @return         array of arrays of two segment endpoints
   */
  PVector[][] getSegments() {
    PVector[][] segs = new PVector[this.size()-1][];
    for (int i=0; i<this.size()-2; i++) {
      segs[i] = getSegment(i);
    }
    return segs;
  }
}
3 Likes