xxxxxxxxxx
328
p5.disableFriendlyErrors = true;
// serial globals
var serial; // variable to hold an instance of the serialport library
var fromSerial = 0,
fromSerial2 = 0; //variable to hold the data
// Previously defined globals
let img; // image
let pxls = []; // saved pixel array
let nSz = 1 / 20;
let nImg = []; // noise image
let bbox;
let box;
let asp;
let pxd;
let x;
let y;
let halfImag;
let myFont;
let bgColor = [190, 190, 190, 255]; //[25,25,25,255];
let res;
function preload() {
// Load image
// NOTE: You may have to replace this with another URL in case nothing shows up
img = loadImage(
"https://images.unsplash.com/photo-1497752531616-c3afd9760a11?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1350&q=80"
);
// OR
// Load local image. (should be URL if running with local socket (127.0.0.1:8431))
// img = loadImage("data/stag_cutout_v001.png");
}
function setup() {
// Set canvas size based on input image's aspect ratio
asp = img.width / img.height;
let w = 720;
let h = 460; //w / asp;
createCanvas(w, h);
console.log(w, h);
img.resize(150, 0);
// Set pixel density
pixelDensity(1);
pxd = pixelDensity();
// Load box
bbox = [100, 100, img.width, img.height];
box = new CtrlBox(bbox[0], bbox[1], bbox[2], bbox[3]);
// Load noise img
for (let x = bbox[0]; x < bbox[0] + bbox[2]; x++) {
for (let y = bbox[1]; y < bbox[1] + bbox[3]; y++) {
nImg[y * width + x * 4] = noise(x * nSz, y * nSz);
}
}
// Cache pixel array
image(img, bbox[0], bbox[1]);
loadPixels();
let bounds = box.getBounds();
for (x = bounds[0]; x < bounds[2]; x++) {
for (y = bounds[1]; y < bounds[3]; y++) {
let col = fget(x, y, (src = pixels));
fset(x, y, col, (src = pxls));
}
}
//SERIAL
serial = new p5.SerialPort(); // make a new instance of the serialport library
serial.on('list', printList); // set a callback function for the serialport list event
serial.on('connected', serverConnected); // callback for connecting to the server
serial.on('open', portOpen); // callback for the port opening
serial.on('data', serialEvent); // callback for when new data arrives
serial.on('error', serialError); // callback for errors
serial.on('close', portClose); // callback for the port closing
serial.list(); // list the serial ports
}
// get the list of ports:
function printList(portList) {
// make a select menu and position it:
portSelector = createSelect();
portSelector.position(10, 10);
// portList is an array of serial port names
for (var i = 0; i < portList.length; i++) {
// Display the list the console:
// console.log(i + " " + portList[i]);
// add item to the select menu:
portSelector.option(portList[i]);
}
// set a handler for when a port is selected from the menu:
portSelector.changed(openPort);
}
function openPort() {
var thisPort = portSelector.value();
if (thisPort != null) {
serial.open(thisPort);
}
}
function serverConnected() {
console.log('connected to server.');
}
function portOpen() {
console.log('the serial port opened.')
// send a byte to prompt the microcontroller to send:
serial.write('x');
}
function serialError(err) {
console.log('Something went wrong with the serial port. ' + err);
}
function portClose() {
console.log('The serial port closed.');
}
function serialEvent() {
// this is called when data is recieved, data will then live in fromSerial
var stringFromSerial = serial.readLine(); // reads everything till the new line charecter
if (stringFromSerial.length > 0) {
if (stringFromSerial !== "hello") {
// if you get hello, ignore it// is the something there ?
var trimmedString = trim(stringFromSerial); // get rid of all white space
var myArray = split(trimmedString, ","); // splits the string into an array on commas
fromSerial = Number(myArray[0]); // get the first item in the array and turn into integer
fromSerial2 = Number(myArray[1]); // get the second item in the array and turn into integer
}
}
serial.write('x');
}
function fget(x, y, src = pixels) {
x = parseInt(x);
y = parseInt(y);
let off = (y * width + x) * pxd * 4;
return [src[off], src[off + 1], src[off + 2], src[off + 3]];
}
function fset(x, y, col, src = pixels) {
x = parseInt(x);
y = parseInt(y);
let off = (y * width + x) * pxd * 4;
src[off] = col[0];
src[off + 1] = col[1];
src[off + 2] = col[2];
src[off + 3] = col[3];
}
/** Calculates (normalized) mouse position relative to (and from center of) box. */
function CtrlBox(x, y, w, h) {
let bbox = [x, y, x + w, y + h];
let whBbox = [x, y, w, h];
let mx = bbox[0]; // MouseX relative to box x
let my = bbox[1]; // MouseY relative to box y
let xpos = bbox[0];
let ypos = bbox[1];
let relative = true; // relative to box?
let invX = false; // x 0 is at the right and increasing toward left
let invY = true; // y 0 is at the bottom and increasing toward top
let nrml = false; // remap to 0-1
let cntr = false; // Set to center of box
return {
show: function (box = true, point = true, txt = true) {
if (box) {
noFill();
stroke(50);
rect(bbox[0], bbox[1], bbox[2] - bbox[0], bbox[3] - bbox[1]);
}
if (point) {
noStroke();
fill(50);
ellipse(mx, my, 10, 10);
}
if (txt) {
textSize(10);
text(
`x: ${xpos.toFixed(2)} y: ${ypos.toFixed(2)}`,
bbox[0],
bbox[3] + 10
);
}
},
getBounds: function () {
return bbox;
},
getRect: function () {
return whBbox;
},
getMousePos: function () {
// Returns (constrained) mouseXY
return [mx, my];
},
getValue: function (
normalize = false,
center = false,
invertX = true,
invertY = true
) {
// Returns relative value according to specifications
nrml = normalize;
cntr = center;
invX = invertX;
invY = invertY;
this._calcValue();
return [xpos, ypos];
},
_calcValue: function () {
// Get absolute position to place stuff in canvas
//------------------------------
let translated_x = map(fromSerial, 0, 1024, 0, width);
let translated_y = map(fromSerial2, 0, 1024, 0, height);
mx = Math.max(bbox[0], Math.min(bbox[2], translated_x));
my = Math.max(bbox[1], Math.min(bbox[3], translated_y));
// Get special value
//------------------------------
xpos = mx;
ypos = my;
// Remap absolute position to whBbox
if (relative == true) {
xpos = xpos - bbox[0];
ypos = ypos - bbox[1];
}
// Normalize to 0-1 for easier calculations
xpos = xpos / whBbox[2];
ypos = ypos / whBbox[3];
if (invX) {
xpos = 1 - xpos;
}
if (invY) {
ypos = 1 - ypos;
}
// Offset to center
if (cntr == true) {
xpos = xpos - 0.5;
ypos = ypos - 0.5;
if (nrml == true) {
xpos *= 2;
ypos *= 2;
}
}
// Remap normalized range back to whBbox range
if (nrml == false) {
xpos = xpos * whBbox[2];
ypos = ypos * whBbox[3];
}
return [xpos, ypos];
},
};
}
function draw() {
//==============================
// WEBGL METHOD
//==============================
// background(255)
// // Show image points
// for (x = 0; x < img.width; x++) {
// for (y = 0; y < img.height; y++) {
// plane(1, 1, 1, 1)
// }
// }
// // SHOW FRAME RATE
// fill(255, 0, 0);
// textFont(myFont);
// textSize(14);
// text(frameRate().toFixed(2), -width/2, height/2, 0);
//==============================
// P2D METHOD
//==============================
let col;
let nv;
let nvx;
let nvy;
let xv;
let yv;
image(img, bbox[0], bbox[1]);
background(bgColor);
loadPixels();
let val = box.getValue(
(normalize = true),
(center = true),
(invertX = false),
(invertY = false)
);
let rect = box.getRect();
let bounds = box.getBounds();
let distx = 100;
for (x = bounds[0]; x < bounds[2]; x++) {
for (y = bounds[1]; y < bounds[3]; y++) {
nv = nImg[y * width + x * 4];
nvx = nv * (val[0] * rect[2]);
nvy = nv * (val[1] * rect[3]);
// nvx = val[0]*rect[2]
// nvy = val[1]*rect[3]
xv = x + nvx;
yv = y + nvy;
col = [0, 0, 0, 0];
if (x > 0 && x <= bounds[2] && y > 0 && y <= bounds[3]) {
}
col = fget(x, y, (src = pxls));
// Show normal rect
// fset(xv, yv, [xv, yv, 0.5*255, 255])
// Make bg transparent
// fset(x, y, bgColor)
// Show color
fset(xv, yv, col);
// Show stMap
// fset(x, y, [(val[0]/rect[2])*255,(val[1]/rect[3])*255,0,255])
// Show distorted stMap
// fset(x, y, [(xv/bounds[2])*255,(yv/bounds[3])*255,0,255])
}
}
updatePixels();
fill(255, 0, 0);
stroke(255, 0, 0);
text(`xv: ${x}`, 0, height - 30);
text(`yv: ${y}`, 0, height - 20);
box.show();
// SHOW FRAME RATE
fill(255, 0, 0);
stroke(255, 0, 0);
text(frameRate().toFixed(2), 0, height);
}