xxxxxxxxxx
412
let r, theta,
bgColor = '#101010',
color1 = '#E8175D',
color2 = '#F26B38',
color3 = '#F7DB4F',
color4 = '#A7226E',
color5 = '#00F900',
sincolor = '#861D59',
coscolor = '#F7DB4F',
tancolor = '#F26B38',
dragged = false,
ra = 15,
oscope,
cpsb,
t = 0.0;
/* Additional Content for every sketch */
let port, receivedData
function keyPressed(e) {
if (keyIsDown(CONTROL) && key == 'z') {
port.postMessage({
operation: 'keyPress',
Key: 'z'
})
}
if (keyIsDown(CONTROL) && key == 'y') {
port.postMessage({
operation: 'keyPress',
Key: 'y'
})
}
if (keyIsDown(CONTROL) && key == 's') {
port.postMessage({
operation: 'keyPress',
Key: 's'
})
}
if (key == 'd') {
port.postMessage({
operation: 'keyPress',
Key: 'd'
})
}
}
Object.prototype.isEmpty = function() {
for (let key in this) {
if (this.hasOwnProperty(key))
return false;
}
return true;
}
var handleData = {
functions: [],
add: function(func) {
this.functions.push(func);
}
}
onmessage = function(e) {
if (e.data.operation == 'sendingPort') {
if (!port)
port = e.ports[0]
if (port) {
loadData()
}
} else if (e.data.operation == 'load') {
receivedData = e.data.data
if (receivedData.isEmpty())
return
for (i = 0; i < handleData.functions.length; i++)
handleData.functions[i]();
}
}
function saveData(data) {
port.postMessage({
operation: 'save',
data
})
}
function loadData() {
port.postMessage({
operation: 'load'
})
}
/* Additional content over */
handleData.add(function() {
theta = receivedData.theta
})
class SignalBuffer {
constructor(n, sf, c, lbl) {
this.lbl = lbl;
this.n = n;
this.c = c;
this.tbuf = [];
this.sf = sf;
}
feedinput(v) {
if (this.tbuf.length > this.n) {
this.tbuf.shift();
}
this.tbuf.push(v);
}
}
class Oscilloscope {
constructor(x, y, w, h, cs, sfs, sn) {
this.x = x;
this.y = y;
this.w = w;
this.h = h;
this.cs = cs;
this.ns = cs.length;
this.n = floor(0.75 * w);
this.sbuf = [];
for (let i = 0; i < this.ns; i++) {
this.sbuf[i] = new SignalBuffer(this.n, sfs[i], cs[i], sn[i]);
}
}
feedsignal(vs) {
if (vs.length != this.ns) {
console.log("[SIGINPUTERR] need array of length: " + this.n + "; doing nothing.");
return;
}
for (let i = 0; i < this.ns; i++) {
this.sbuf[i].feedinput(vs[i]);
}
this.render();
}
wipe() {
fill(bgColor);
noStroke();
rect(this.x, this.y - this.h / 2, this.w, this.h);
}
showdisplaypanel() {
stroke(96);
noFill();
rect(this.x, this.y - this.h / 2, this.w, this.h);
textAlign(LEFT, CENTER);
textSize(10);
textStyle(NORMAL);
fill(64);
strokeWeight(0.25);
line(this.x, this.y - this.sbuf[0].sf, this.x + 5, this.y - this.sbuf[0].sf);
text('1.0', this.x + 8, this.y - this.sbuf[0].sf);
line(this.x, this.y + this.sbuf[0].sf, this.x + 5, this.y + this.sbuf[0].sf);
text('-1.0', this.x + 8, this.y + this.sbuf[0].sf);
line(this.x, this.y, this.x+0.74*this.w, this.y);
}
showsignal(sb, x, y) {
for (let i = 0; i < sb.tbuf.length; i++) {
let sv = sb.tbuf[i] * sb.sf;
fill(bgColor);
strokeWeight(0.25);
rect(x, y, 0.23 * this.w, 55);
fill(sb.c);
stroke(sb.c);
rect(x + 4, y + 5, 15, 10);
strokeWeight(0);
textStyle(NORMAL);
textAlign(LEFT, TOP);
textSize(11);
text(sb.lbl, x + 22, y + 6);
let legalsv = constrain(nfc(sv, 2), -this.h / 2, this.h / 2);
text('f(' + round(degrees(theta)) + '):' + legalsv, x + 3, y + 28);
point(this.x + i, this.y - constrain(sv, -0.5 * this.h, 0.5 * this.h));
}
}
render() {
push();
translate(width / 2, height / 2);
this.wipe();
this.showdisplaypanel();
stroke(64);
line(this.x + 0.75 * this.w, this.y - this.h / 2, this.x + 0.75 * this.w, this.y + this.h / 2);
for (let k = 0; k < this.sbuf.length; k++) {
let sb = this.sbuf[k];
this.showsignal(sb, this.x + 0.76 * this.w, this.y - 0.24 * (k) * this.h);
}
pop();
}
}
class CPSwitch {
constructor(x, y, w, h) {
this.x = x;
this.y = y;
this.w = w;
this.h = h;
this.d = 4;
this.onlbl = 'click to stop'
this.offlbl = 'click to start'
this.state = false;
}
render() {
stroke(color3);
fill(bgColor);
rect(this.x, this.y, this.w, this.h);
textAlign(CENTER, TOP);
textSize(12);
textStyle(NORMAL);
if (this.state) {
fill(0, 240, 0);
noStroke();
rect(this.x + this.d, this.y + this.d, this.w - 2 * this.d, this.h - 2 * this.d);
fill(bgColor);
text(this.onlbl, this.x + this.w / 2, this.y + this.d + 10);
} else {
fill(0, 255, 144);
noStroke();
text(this.offlbl, this.x + this.w / 2, this.y + this.d + 10);
}
}
handleclick() {
this.state = !this.state;
this.render();
}
}
function setup() {
createCanvas(800, 800);
oscope = new Oscilloscope(
-0.495 * width, -0.327 * height, 360, 270,
[sincolor, coscolor, tancolor],
[70.0, 70.0, 10.0],
['sine', 'cosine', 'tangent']
);
cpsb = new CPSwitch(width - 110, 20, 90, 40);
r = width / 7
theta = PI / 4
}
const detectDrag = () => {
if (dist(mouseX - width / 2, -(mouseY - height / 2), r * cos(theta), r * sin(theta)) < 15) {
ra = 20
ellipse(r * cos(theta), r * sin(theta), 15, 15)
return true
}
}
function mousePressed() {
if (detectDrag()) {
dragged = true
}
if (mouseX > cpsb.x && mouseY > cpsb.y && mouseX < (cpsb.x + cpsb.w) && mouseY < (cpsb.y + cpsb.h)) {
cpsb.handleclick();
}
}
function drawLabels() {
textSize(25)
fill(255)
noStroke()
textAlign(CENTER, CENTER);
text('A', width / 2, height / 2 + 20);
text('B', width / 2 + (r + 20) * cos(theta), height / 2 + 20);
text('C', width / 2 + (r + 25) * cos(theta), height / 2 - (r + 25) * sin(theta));
fill(230, 20, 250)
text('x', width - 20, height / 2 + 20);
text('y', width / 2 - 20, 20);
noFill()
}
function mouseReleased() {
dragged = false
ra = 15
saveData({
theta
})
}
function drawCoord() {
stroke(100)
strokeWeight(1)
line(0, height / 2, width, height / 2)
line(width / 2, height / 2, width, height / 2)
line(width / 2, 0, width / 2, height)
stroke(255)
push()
let k = 12
translate(width - k, height / 2)
fill(100)
triangle(k, 0, 0, k / 1.5, 0, -k / 1.5)
pop()
push()
fill(100)
translate(width / 2, k)
triangle(k / 1.5, 0, 0, -k, -k / 1.5, 0)
pop()
}
function draw() {
background(bgColor);
drawCoord()
cpsb.render();
let f1 = sin(theta);
let f2 = cos(theta);
let f3 = tan(theta);
if(cpsb.state){
oscope.feedsignal([f1, f2, f3]);
}else{
oscope.render();
}
noFill()
strokeWeight(3)
drawLabels()
applyMatrix(1, 0, 0, -1, 0, 0)
push()
translate(width / 2, -height / 2)
//line(0,0,mouseX-width/2, -(mouseY-height/2))
stroke(color1)
ellipse(0, 0, 2 * r, 2 * r)
stroke(color2)
line(0, 0, r * cos(theta), r * sin(theta))
stroke(color3)
line(0, 0, r * cos(theta), 0)
stroke(color4)
line(r * cos(theta), 0, r * cos(theta), r * sin(theta))
stroke(color3)
fill(100)
noFill()
arc(0, 0, 50, 50, 0, theta)
if (dragged)
fill(255, 255, 0)
else
noFill()
line(0, 0, 25, 0)
strokeWeight(2)
ellipse(r * cos(theta), r * sin(theta), ra, ra)
if (dragged === true) {
theta = atan2(-(mouseY - height / 2), mouseX - width / 2)
}
pop()
drawLabels()
applyMatrix(1, 0, 0, -1, 0, 0)
// automatic rotation and theta bound checks
if (cpsb.state) {
t += 0.10;
theta += 0.03;
if (theta > 2 * PI) {
theta -= 2 * PI;
}
}
}