Search code examples
javascriptprocessingp5.js

noisy line between two specific points P5.js


I'm trying to draw a noisy line (using perlin noise) between two specific points. for example A(100, 200) and B(400,600). The line could be a points series. Drawing random noisy line is so clear but I dont know how can I calculate distance specific points. working of P5.js. I don't have any code written yet to upload. Please can anyone help me?


Solution

  • I tried to add sufficient comments that you would be able to learn how such a thing is done. There are a number of things that you should make yourself aware of if you aren't already, and it's hard to say which if these you're missing:

    // The level of detail in the line in number of pixels between each point.
    const pixelsPerSegment = 10;
    const noiseScale = 120;
    const noiseFrequency = 0.01;
    const noiseSpeed = 0.1;
    
    let start;
    let end;
    
    function setup() {
      createCanvas(400, 400);
      noFill();
      
      start = createVector(10, 10);
      end = createVector(380, 380);
    }
    
    function draw() {
      background(255);
      
      let lineLength = start.dist(end);
      // Determine the number of segments, and make sure there is at least one.
      let segments = max(1, round(lineLength / pixelsPerSegment));
      // Determine the number of points, which is the number of segments + 1
      let points = 1 + segments;
      
      // We need to know the angle of the line so that we can determine the x
      // and y position for each point along the line, and when we offset based
      // on noise we do so perpendicular to the line.
      let angle = atan2(end.y - start.y, end.x - start.x);
      
      let xInterval = pixelsPerSegment * cos(angle);
      let yInterval = pixelsPerSegment * sin(angle);
      
      beginShape();
      // Always start with the start point
      vertex(start.x, start.y);
      
      // for each point that is neither the start nor end point
      for (let i = 1; i < points - 1; i++) {
        // determine the x and y positions along the straight line
        let x = start.x + xInterval * i;
        let y = start.y + yInterval * i;
        
        // calculate the offset distance using noice
        let offset =
          // The bigger this number is the greater the range of offsets will be
          noiseScale *
          (noise(
            // The bigger the value of noiseFrequency, the more erretically
            // the offset will change from point to point.
            i * pixelsPerSegment * noiseFrequency,
            // The bigger the value of noiseSpeed, the more quickly the curve
            // fluxuations will change over time.
            (millis() / 1000) * noiseSpeed
          ) - 0.5);
          
        // Translate offset into x and y components based on angle - 90°
        // (or in this case, PI / 2 radians, which is equivalent)
        let xOffset = offset * cos(angle - PI / 2);
        let yOffset = offset * sin(angle - PI / 2);
        
        vertex(x + xOffset, y + yOffset);
      }
      
      vertex(end.x, end.y);
      endShape();
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script>

    This code makes jaggy lines, but they could be smoothed using curveVertex(). Also, making the line pass through the start and end points exactly is a little tricky because the very next point may be offset by a large amount. You could fix this by making noiseScale very depending on how far from an endpoint the current point is. This could be done by multiplying noiseScale by sin(i / points.length * PI) for example.