html, body { height: 100%; }
body {
	display: flex;
	justify-content: center;
	align-items: center;
}
View Compiled
const app = {
	px : null,
	py : null,
	angle : 0,
	frequency : 3,
	x : 0,
	cx : null,
	cy : null,
	radius : 60,
	xlimit : null
}

const wave = {
    px : null,
    py : null,
    angle : app.angle,
    frequency : app.frequency,
}

function setup() {
	
	// Inicializar
	createCanvas(640, 200);
	rectMode(CENTER);
	background(255);
	frameRate(60);

	// Establecer valores iniciales
	app.cx = width / 8;
	app.cy = 85;
	app.xlimit = width - 160;
}

function draw() {

	// - Fondo Global
    background(255);

	// - Guías
	stroke(212);
	line( app.cx-app.radius, app.cy, app.xlimit+app.cx+app.radius, app.cy );
	line( app.cx, app.cy-app.radius, app.cx, app.cy+app.radius );

	// - Círculo principal
	stroke(128);
    noFill();
    ellipse( app.cx, app.cy, app.radius * 2, app.radius * 2);
	
    // - Rotación del puntero alrededor del círculo
    app.px = app.cx + cos(radians(app.angle)) * (app.radius);
    app.py = app.cy + sin(radians(app.angle)) * (app.radius);

	// - Dibuja los punteros del círculo
	fill(0, 96, 128);
	noStroke();
    rect(app.px, app.py, 5, 5);  // Puntero sobre la circunferencia
	rect(app.cx, app.cy, 5, 5);  // Puntero en el centro del círculo 

	// - Linea del círculo
	stroke(0, 96, 128);
    line(app.cx, app.cy, app.px, app.py);
	
    // - Mantener establecido el valor a 0 para evitar el flasheo
    wave.angle = 0;

    // - Dibuja curva estática - y = sin(x)
	stroke(196);
    for (let i = 0; i < app.xlimit; i++) {
        wave.px = app.cx + cos(radians(wave.angle)) * (app.radius);
        wave.py = app.cy + sin(radians(wave.angle)) * (app.radius);
        point( app.cx + app.radius + i, wave.py);
        wave.angle -= wave.frequency;
    }

    // - Puntero junto a la curva del Seno para ilustrar la relacion del círculo con la onda
    noStroke();
    rect(app.cx + app.radius + app.x, app.py, 5, 5);
    app.angle -= app.frequency;
    app.x += 1;

    // - Resetear valores cuando el puntero de onda alcanza el límite en X
    if (app.x >= app.xlimit ) {
        app.x = 0;
        app.angle = 0;
    }

    // - Linea dinámica conectando el puntero de la circunferencia y la onda
    stroke(0, 96, 128);
    line(app.px, app.py, app.cx + app.radius + app.x, app.py);

    // - Sacar los calculos en pantalla
	fill(128);
	noStroke();
	textSize(12);
	textFont('monospace');
	text("y = sin(x)", 30, 180);
    text("px = " + app.px.toFixed(1), 130, 180);
    text("py = " + app.py.toFixed(1), 230, 180);
}
View Compiled
Run Pen

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.3/p5.min.js