xxxxxxxxxx
220
let cam;
let axis;
let video;
let arrowArray = [];
let grayPixelArray;
let o = 50;
let p = 50;
function setup() {
createCanvas(windowWidth, windowHeight, WEBGL);
axis = createGraphics(windowWidth, windowHeight, WEBGL);
drawAxis();
arrowArray.push(new Arrow(0, 0, 0));
// Create a video capture from the webcam
video = createCapture(VIDEO, { flipped:true });
video.size(o, p); // Set the size of the video
// video.hide(); // Hide the default video element
videoToGray();
grayPixelArray = video.pixels.filter((_, index) => index % 4 === 0);
grayPixelArray = applyHighContrast(grayPixelArray);
}
function draw() {
background(10);
lights();
//ambientLight(50);
/*pointLight(
255, 0, 0, // color
0, 0, 0 // position
);*/
// frameRate(60);
// ortho()
// orbitControl();
videoToGray()
// Apply high contrast transformation
grayPixelArray = applyHighContrast(grayPixelArray);
// use Graphics.axis as the texture of a plane
// create 2D objects in 3D space
texture(axis);
plane(windowWidth, windowHeight);
// display all arrows in arrowArray for 1 frame
if (arrowArray[0]) {
for (let i = 1; j = arrowArray[i] ;i += 1) {
if (j._3Dz < -5) {
arrowArray.splice(i, 1);
} else {
j.arrowDisplay();
}
}
}
grayPixelArray = video.pixels.filter((_, index) => index % 4 === 0);
// console.log(grayPixelArray)
// drawGrayscaleArray(50, 50);
for (let n = 0; n < 3000; n ++) {
let x = random(-axis.width / 2, axis.width / 2);
let y = random(-axis.height / 2, axis.height / 2);
// Add point based on probability
if (shouldDrawPoint(x, y, o, p)) {
arrowArray.push(new Arrow(x, y, 50));
}
}
}
function drawAxis() {
// translate to 2D coordinate system
axis.translate(-axis.width / 2, -axis.height / 2);
// axis.background(10);
// draw the axises
axis.stroke('white');
axis.line(0, axis.height / 2, axis.width, axis.height / 2);
axis.line(axis.width / 2, 0, axis.width / 2, axis.height);
// draw the marks on the y axis
for (let i = 0; i < axis.width; i += axis.height / 20) {
axis.line(axis.width / 2,
0 + i,
axis.width / 2 + 5,
0 + i);
}
// draw the marks on the x axis
for (let i = 0; i < axis.width; i += axis.width / 20) {
axis.line(0 + i,
axis.height / 2,
0 + i,
axis.height / 2 - 5);
}
}
class Arrow {
constructor (x, y, z) {
this._3Dx = x;
this._3Dy = y;
this._3Dz = z;
}
// display the arrow for 1 frame
arrowDisplay() {
if (this._3Dz > 0) { // if the arrow hasn't reach the axis
this._3Dz -= 45; // the speed in which the arrows move
} else if (this._3Dz <= 0) {
this._3Dz -= 2.5;
}
push();
translate(this._3Dx, this._3Dy, this._3Dz);
rotateX(PI / 2); // rotate to make the top/bottom facing the axis
fill('white');
noStroke();
cylinder(3.5, 20);
pop();
}
}
function videoToGray() {
// Load the pixels from the video
video.loadPixels();
// Check if the video has pixels loaded
if (video.pixels.length > 0) {
// Convert to grayscale
for (let i = 0; i < video.pixels.length; i += 4) {
let r = video.pixels[i]; // Red
let g = video.pixels[i + 1]; // Green
let b = video.pixels[i + 2]; // Blue
// Calculate grayscale value
let gray = (r + g + b) / 3;
// Set the pixel color to the grayscale value
video.pixels[i] = gray; // Red
video.pixels[i + 1] = gray; // Green
video.pixels[i + 2] = gray; // Blue
// pixels[i + 3] stays the same (Alpha)
}
// Update the video pixels
video.updatePixels();
}
}
function applyHighContrast(array) {
// Stretch the grayscale values to increase contrast
let minVal = Math.min(array);
let maxVal = Math.max(array);
// Prevent division by zero if all values are the same
if (minVal === maxVal) {
return array.map(() => 255);
}
// Apply contrast stretching with a scaling factor
const contrastFactor = 6; // Increase this value for more contrast
return array.map(value => {
// Apply contrast stretching
let stretchedValue = ((value - minVal) * (255 / (maxVal - minVal))) * contrastFactor;
// Clip the value to ensure it stays within bounds
return constrain(Math.round(stretchedValue), 0, 255);
});
}
function drawGrayscaleArray(j, k) {
// Draw the pixel array as a grid of rectangles
for (let y = 0; y < k; y++) {
for (let x = 0; x < j; x++) {
let index = x + y * j;
let grayValue = grayPixelArray[index];
console.log(grayValue)
// Set fill color based on the grayscale value
fill(grayValue);
noStroke();
axis.rect((x / j) * width, (y / k) * height, width / j, height / k);
}
}
}
function mapToPixelIndex(x, y, j, k) {
// Map the y-coordinate to the pixel array
let pixelX = Math.floor((x + width / 2) * j / width);
let pixelY = Math.floor((y + height / 2) * k / height);
// Ensure the pixel indices are within bounds
pixelX = constrain(pixelX, 0, j - 1);
pixelY = constrain(pixelY, 0, k - 1);
// Convert 2D indices to 1D index
return pixelX + pixelY * j;
}
function shouldDrawPoint(x, y, j, k) {
let index = mapToPixelIndex(x, y, j, k);
let grayscaleValue = grayPixelArray[index];
// Convert grayscale value to probability
let probability = 1 - (grayscaleValue / 255);
// Decide to draw the point based on probability
return random() < probability; // Return true or false based on random chance
}