简体   繁体   中英

Using object trails and pixel data together , not getting what I hoped for?

I'm a very new coder, honestly confused most of the time, Any advice would be great. I was doing an exercise from Dan Shiffman vids. I'm trying to paint a line or a stroke with pixel data from a live webcam. Two canvas, one live webcam tiny and a large canvas that has a lot of ellipse that are colored in pixel rgb from pixel array This is an image of my final product

I made a separate file for the particle and then used a constructor function and a loop to display and update in draw(), while in the particle file I tried to use a line instead of an ellipse by using an array of past positions of the object. However, it won't work? The canvas just appears grey. In the particle.js file, when I used the line() function, and when I use the ellipse() I don't get a painterly brushstroke effect, Not sure if my logic is correct. Here is the code -> I'm sorry there's a lot. The first bit is the particle.js file and the second is the main sketch file.

function P(x, y) {
    this.x = x;
    this.y = y;
    this.r = random(4, 32);
    this.history = [];

    this.update = function() {
        this.x = constrain(this.x, 0, width);
        this.y = constrain(this.y, 0, height);

        this.x += random(-10,10);   
        this.y += random(-10,10); // accelaration

        this.history.push(createVector(this.x,this.y));
    }



    this.show = function() {
        noStroke();
        // fill(255);
        let px = floor(this.x/vScale); // formula to convert from small orignal video to large canvas - ratio is 16
        let py = floor(this.y/vScale);
        let col = video.get(px,py); // get() gives you an array of r, g, b and a value from the corresponding pixel
        // console.log(col);
        fill(col[0], col[1], col[2], slider.value); // for r g b value in array
        // ellipse(this.x,this.y, this.r);
        // line(this.x, this.y, this.x,this.y)
        for (let i = 0; i < this.history.length; i++) {
            let pos = this.history[i]; // pos stores each array item as we are cycling through the loop
            // ellipse(pos.x,pos.y,8,8);
            // console.log(pos);
            line(this.history[i].x, this.history[i].y, this.history[i + 1].x, this.history[i + 1].y);
    }
    }
}
let video;
let vScale = 16;

let p = [];
// const flock = [];
let slider;

function setup() {
    createCanvas(640,480);
    pixelDensity(1);
    video = createCapture(VIDEO);
    video.size(width/vScale,height/vScale);

    for (let i = 0; i < 50; i ++) {
        p[i] = new P(random(width),random(height));
    }
    background(51);
    slider = createSlider(0,255,127);

}

function draw() {
    // background(51);
    video.loadPixels(); // to put all the pixels of capture in an array
    for (let i = 0; i < p.length; i ++) {
        p[i].update();
        p[i].show();
    }
}

Img of what I hoped it would look like, there is definitely some additional flocking color averaging in the movement of the object however I'm just trying to get the basic line() function to work

There are 2 simple issues.

You got an error in show , because the index i+1 is out of bounds in this.history[i + 1].x . Run the for loop from 0 to history.length-1 , to solve the issue:

for (let i = 0; i < this.history.length; i++)

for (let i = 0; i < this.history.length-1; i++)

A line can't be filled ( fill ). A line has to be drawn by stroke . eg:

noStroke();

stroke(255);

 function P(x, y) { this.x = x; this.y = y; this.r = random(4, 32); this.history = []; this.update = function() { this.x = constrain(this.x, 0, width); this.y = constrain(this.y, 0, height); this.x += random(-10,10); this.y += random(-10,10); // accelaration this.history.push(createVector(this.x,this.y)); } this.show = function() { //noStroke(); stroke(255); // fill(255); let px = floor(this.x/vScale); // formula to convert from small orignal video to large canvas - ratio is 16 let py = floor(this.y/vScale); let col = video.get(px,py); // get() gives you an array of r, g, b and a value from the corresponding pixel // console.log(col); fill(col[0], col[1], col[2], slider.value); // for rgb value in array // ellipse(this.x,this.y, this.r); // line(this.x, this.y, this.x,this.y) for (let i = 0; i < this.history.length-1; i++) { let pos = this.history[i]; // pos stores each array item as we are cycling through the loop // ellipse(pos.x,pos.y,8,8); // console.log(pos); line(this.history[i].x, this.history[i].y, this.history[i + 1].x, this.history[i + 1].y); } } } let video; let vScale = 16; let p = []; // const flock = []; let slider; function setup() { createCanvas(640,480); pixelDensity(1); video = createCapture(VIDEO); video.size(width/vScale,height/vScale); for (let i = 0; i < 50; i ++) { p[i] = new P(random(width),random(height)); } background(51); slider = createSlider(0,255,127); } function draw() { // background(51); video.loadPixels(); // to put all the pixels of capture in an array for (let i = 0; i < p.length; i ++) { p[i].update(); p[i].show(); } }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.0.0/p5.min.js"></script>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM