Используя следы объектов и данные пикселей вместе, я не получил того, на что надеялся?

Я очень новый кодер, честно говоря, большую часть времени запутался, любой совет был бы замечательным. Я делал упражнение из видео Дэна Шиффмана. Я пытаюсь нарисовать линию или штрих с помощью пиксельных данных с веб-камеры в реальном времени. Два холста, один крошечный веб-камера в реальном времени и большой холст с множеством эллипсов, окрашенных в пикселях rgb из массива пикселей Это изображение моего конечного продукта

Я сделал отдельный файл для частицы, а затем использовал функцию-конструктор и цикл для отображения и обновления в draw(), а в файле частицы я попытался использовать линию вместо эллипса, используя массив прошлых позиций точки. объект. Однако не получится? Холст просто кажется серым. В файле частиц.js, когда я использовал функцию line() и когда я использую ellipse(), я не получаю эффект живописного мазка. Не уверен, что моя логика верна. Вот код -> извините, что много. Первый бит — это файл частиц.js, а второй — основной файл скетча.

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 того, на что я надеялся, определенно есть некоторое дополнительное флокирование усреднения цвета в движении объект, однако я просто пытаюсь заставить работать базовую функцию line()


person Laiqa Mohid    schedule 02.04.2020    source источник


Ответы (1)


Есть 2 простых вопроса.

Вы получили ошибку в show, потому что индекс i+1 выходит за пределы в this.history[i + 1].x. Запустите цикл for от 0 до history.length-1, чтобы решить проблему:

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

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

Строка не может быть заполнена (fill). Линия должна быть проведена stroke. например:

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 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-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>

person Rabbid76    schedule 02.04.2020