xxxxxxxxxx
232
const size = window.innerWidth * 1.5;
const h = window.innerHeight * 0.75;
const dist = h / 2 + 25;
const pixel_ampli = h / 3; // amplitude = 1 equals this amount of pixels
var pixel_second = 0.015; // one pixel equals x seconds
var inscreen = false;
var radius = 0;
var period = 0;
var angle = 0;
var vec;
var timeframe;
function round_text(num, decimals, add_zeroes = true) {
num = round(num * pow(10, decimals)) / pow(10, decimals);
num += "";
// adding the zeroes ensures that the text always has a uniform length
// for example it prevents the flickering sometimes showing up when
// the periodtime-text that is displayed changes length:
// ==> 0.11 / 7.5 seconds
// ==> 1 / 7.5 seconds
// ==> 0.1 / 7.5 seconds
//
// No flickering when same length:
// ==> 0.11 / 7.5 seconds
// ==> 0.10 / 7.5 seconds
if (add_zeroes && decimals > 0) {
if (!num.includes(".")) num += ".";
// num of digits before decimal sign + sign itself
const len = num.split(".")[0].length + 1;
while (num.length - len < decimals) {
num += "0";
}
}
return num;
}
const wave_sin = new Wave(
(angle) => sin(angle),
1,
period,
angle,
pixel_second,
pixel_ampli / 2.5,
"#ff0000",
"sin: "
);
const wave_cos = new Wave(
(angle) => cos(angle),
1,
period,
angle,
pixel_second,
pixel_ampli / 2.5,
"#00ff00",
"cos: "
);
function setup() {
can = createCanvas(size, h);
can.mouseOver(() => (inscreen = true));
can.mouseOut(() => (inscreen = false));
sl1 = createSlider(0.25, 30, 7.5, 0.25);
sl1.parent(document.querySelector(".controls .period"));
sl2 = createSlider(0.5, 1.5, 1, 0.05);
sl2.parent(document.querySelector(".controls .amplitude"));
sl3 = createSlider(0.005, 0.05, (0.005 + 0.05) / 2, 0.0005);
sl3.parent(document.querySelector(".controls .graph"));
wave_sin.map_pixel_second(() => sl3.value());
wave_sin.map_amplitude(() => sl2.value());
wave_sin.map_period(() => sl1.value());
wave_sin.map_phase(() => angle);
wave_cos.map_pixel_second(() => sl3.value());
wave_cos.map_amplitude(() => sl2.value());
wave_cos.map_period(() => sl1.value());
wave_cos.map_phase(() => angle);
}
function calculate_current_values() {
period = sl1.value();
radius = sl2.value() * pixel_ampli;
pixel_second = sl3.value();
if (inscreen && mouseIsPressed) {
vec = createVector(mouseX, mouseY)
.sub(h / 2, h / 2)
.setMag(radius);
angle = -vec.heading();
if (angle < 0) angle += TWO_PI;
} else {
// calculate seconds passed in current period
timeframe = (millis() / 1000) % period;
// 1/period = frequency ==> ratio of angle moved in one timeunit (here: seconds)
// 1/period * TWO_PI ==> angle covered in one second
// 1/period * TWO_PI * timeframe ==> angle covered at current timeframe
angle = ((1 / period) * TWO_PI * timeframe) % TWO_PI;
vec = p5.Vector.fromAngle(-angle).setMag(radius);
}
}
function draw_metadata() {
push();
noStroke();
textSize(16);
translate(0, 10);
text("Graph: 1 pixel equals " + pixel_second + " seconds", 15, 15);
text(
"Graph: 1 sec equals " + round_text(1 / pixel_second, 2) + " pixels",
15,
55
);
text(
"Graph: 1 period equals " +
round_text(period / pixel_second, 0) +
" pixels",
15,
35
);
text("Amplitude: " + round_text(sl2.value(), 2, false), 15, 135);
text(
"Periodtime: " + round_text(timeframe, 2) + " / " + period + " seconds",
15,
95
);
text("Clocktime: " + round_text(millis() / 1000, 1) + " seconds", 15, 75);
text("Period: " + period + " seconds", 15, 115);
//text('Frequency: '+ round_text(1/period, 2) +' per second (ratio)',335, 15);
//text('Movement: '+ round_text(1/period*360, 3) +'° per second', 335,35);
pop();
}
// draw angle (blue parts)
function draw_angle() {
push();
noStroke();
fill("#0000ff");
arc(0, 0, radius / 2, radius / 2, vec.heading(), 0);
fill(0);
noStroke();
circle(0, 0, radius * 0.4);
// text for angle
fill("#0000ff");
textSize(20);
textAlign(RIGHT);
translate(-h / 2 + 16, -h / 2 + 182);
display_angle = -vec.heading();
if (display_angle < 0) display_angle += TWO_PI;
const disp_deg = round_text(degrees(display_angle), 2) + "°";
text(disp_deg, 75, 0);
text(round_text(display_angle / PI, 2) + " PI", 75, 20);
text(round_text(display_angle / TAU, 2) + " TAU", 95, 40);
pop();
}
function draw() {
background(0);
calculate_current_values();
draw_metadata();
translate(h / 2, h / 2);
strokeWeight(2);
stroke(255);
draw_angle();
// draw main circles
noFill();
push();
strokeWeight(0.25);
circle(0, 0, (h / 3) * 2);
pop();
circle(0, 0, radius * 2);
// draw coordinates system
line(-h / 2, 0, h / 2, 0);
line(0, -h / 2, 0, h / 2);
//draw x-component
push();
noFill();
stroke("#00ff00");
strokeWeight(4);
line(0, 0, vec.x, 0);
translate(dist, h / 4);
wave_cos.draw(size);
pop();
//draw y-component
push();
noFill();
stroke("#ff0000");
strokeWeight(4);
line(vec.x, 0, vec.x, vec.y);
translate(dist, -h / 4);
wave_sin.draw(size);
pop();
// Draw moving circle
fill(255);
circle(vec.x, vec.y, radius / 16);
line(0, 0, vec.x, vec.y);
}