sinewave.js

total 0
used 0
limit 0
/* categories: curve files: head ../point_src/point-content.js pointlist point mouse stage dragging ../point_src/setunset.js ../point_src/stroke.js */ let time = 0 const frequency = 10; // Hz const amplitude = 100; const speed = 0 // time scaling const offset = {x: 100, y:0} const width = 600 const height = 500 // const points = []; class MainStage extends Stage { canvas='playspace' // In your stage's draw method draw(ctx) { this.clear(ctx); drawSineWave(ctx, width, height); drawSineWaveLimited(ctx, 50, width, height); // drawSineWaveTips(ctx, width, height, time); let rps = drawSineWaveTips(ctx, width, height, time); let ps = PointList.from(rps).cast() this.ps = ps ps.offset(offset) ps.pen.line(ctx) // ps.pen.quadCurve(ctx) time += 1 / 600; } } function drawSineWave(ctx, width, height) { let points = plotSineWave(width, height) generalDrawPoints(ctx, points, offset) } function drawSineWaveLimited(ctx, numPoints, width, height) { let points = plotSineWaveLimited(numPoints, width, height) generalDrawPoints(ctx, points, offset, '#FF6699') } function drawSineWaveTips(ctx, width, height, time) { let points = plotSineWaveTips(width, height, time) // let points = plotSineWaveLimited(10, width, height) generalDrawPoints(ctx, points, offset, '#AA66DD', drawTips) return points } function generalDrawPoints(ctx, points, offset, color='#66AAFF', func=drawPoints){ ctx.beginPath(); func(ctx, points, offset) ctx.strokeStyle = color; ctx.stroke(); } const drawPoints = function(ctx, points, o={x:0, y:0}) { for (let i = 0; i < points.length; i++) { const p = points[i]; if (i === 0) ctx.moveTo(p.x + o.x, p.y + o.y); else ctx.lineTo(p.x + o.x, p.y + o.y); } } function drawTips(ctx, points, o={x:0, y:0}) { ctx.fillStyle = 'yellow'; for (let p of points) { ctx.beginPath(); ctx.arc(p.x + o.x, p.y + o.y, 3, 0, Math.PI * 2); ctx.fill(); } } // function plotSineWaveTips(width, height, time = 0) { // const centerY = height * 0.5; // const numTips = frequency * 2; // 2 tips (peak + trough) per full wave // let points = []; // for (let i = 0; i < numTips; i++) { // const t = time + i / (2 * frequency); // step by 1/(2f) to hit peaks/troughs // const x = (t - time) * width * frequency; // map time to width space // const y = centerY + Math.sin(2 * Math.PI * frequency * t) * amplitude; // points.push({ x, y }); // } // return points; // } function plotSineWave(width, height) { const centerY = height * .5; let points = []; for (let x = 0; x < width; x++) { const t = time + x / width; const y = centerY + Math.sin(2 * Math.PI * frequency * t) * amplitude; points.push({ x, y }); } return points } function plotSineWaveLimited(numPoints, width, height) { /* Given a number of points, plot along the spline.*/ const centerY = height * .5; let points = []; for (let i = 0; i < numPoints; i++) { const x = (i / (numPoints - .1)) * width; const t = time + i / numPoints; // still time-based spacing const y = centerY + Math.sin(2 * Math.PI * frequency * t) * amplitude; points.push({ x, y }); } return points } function plotSineWavePoints(width, height, time=0) { /* Plot static tips: drawSineWaveTips(ctx, 500, 400, Math.PI); */ const centerY = height * 0.5; const numTips = frequency * 2; // 2 tips per full wave let points = []; for (let i = 0; i < numTips; i++) { const x = (i / (numTips - .01)) * width; const t = time + i / (2 * frequency); // still time-based for phase const y = centerY + Math.sin(2 * Math.PI * frequency * t) * amplitude; points.push({ x, y }); } return points; } // function plotSineWaveTips(width, height, time = 0) { // const centerY = height * 0.5; // const numCycles = frequency; // const tips = []; // // Peaks/troughs occur every half cycle // for (let i = 0; i < numCycles * 2; i++) { // const tipTime = i / (2 * frequency); // actual time tip occurs // const phase = time - tipTime; // time difference between now and tip // const x = width - (phase * frequency * width); // shift right to left // if (x >= 0 && x <= width) { // const y = centerY + Math.sin(2 * Math.PI * frequency * (tipTime)) * amplitude; // tips.push({ x, y }); // } // } // return tips; // } function plotSineWaveTipsSliding(width, height, time = 0) { const centerY = height * 0.5; const tips = []; const wavePeriod = 1 / frequency; // seconds per full wave const pixelsPerCycle = width / frequency; // Tips (peaks/troughs) occur every half cycle: every pixelsPerCycle / 2 pixels const spacing = pixelsPerCycle / 2; // Walk across the screen and check each expected tip location for (let x = 0; x <= width; x += spacing) { const t = time + x / width; // same logic as your wave formula const y = centerY + Math.sin(2 * Math.PI * frequency * t) * amplitude; tips.push({ x, y }); } return tips; } function plotSineWaveTipsAtTime(width, height, time = 0) { const centerY = height * 0.5; const tips = []; // estimate how many tips to check const totalTips = Math.ceil(width / (width / frequency / 2)) + 2; for (let i = -totalTips; i < totalTips; i++) { const phaseOffset = (0.25 + i * 0.5) / frequency; // when tip occurs in time const x = width * (phaseOffset - time); // where it lands onscreen if (x >= 0 && x <= width) { const y = centerY + Math.sin(2 * Math.PI * frequency * (time + x / width)) * amplitude; tips.push({ x, y }); } } return tips; } function x_plotSineWaveTips(width, height, time = 0) { const centerY = height * 0.5; const tips = []; // Tips happen at: x = width * ((0.25 + n*0.5)/frequency - time) // Solve for n range such that x in [0, width] const minN = Math.ceil((frequency * time - 1) / 0.5); const maxN = Math.floor((frequency * time + 1) / 0.5); for (let n = minN; n <= maxN; n++) { const phaseOffset = (0.25 + n * 0.5) / frequency; const x = width * (phaseOffset - time); if (x >= 0 && x <= width) { const y = centerY + Math.sin(2 * Math.PI * frequency * (time + x / width)) * amplitude; tips.push({ x, y }); } } return tips; } function plotSineWaveTips(width, height, time = 0) { const centerY = height * 0.5; const tips = []; const pixelsPerCycle = width / frequency; const tipSpacing = pixelsPerCycle / 2; const maxVisibleTips = Math.ceil(width / tipSpacing) + 2; const currentPhase = frequency * time; const nCenter = Math.round(currentPhase / 0.5); // center tip index at current time const nStart = nCenter - maxVisibleTips; const nEnd = nCenter + maxVisibleTips; for (let n = nStart; n <= nEnd; n++) { const phaseOffset = (0.25 + n * 0.5) / frequency; const x = width * (phaseOffset - time); if (x >= 0 && x <= width) { const y = centerY + Math.sin(2 * Math.PI * frequency * (time + x / width)) * amplitude; tips.push({ x, y }); } } return tips; } ;stage = MainStage.go();
Run
Meta Data
imports ()
files ('head', '../point_src/point-content.js', 'pointlist', 'point', 'mouse', 'stage', 'dragging', '../point_src/setunset.js', '../point_src/stroke.js')
unused_keys ('title',)
unknown_keys ('categories',)
categories ['curve']
filepath_exists True
path sinewave.js
filepath sinewave.js
clean_files ('../point_src/core/head.js', '../point_src/compass.js', '../point_src/center.js', '../point_src/point-content.js', '../point_src/pointlistdraw.js', '../point_src/pointlistgradient.js', '../point_src/pointlistshape.js', '../point_src/pointlistgenerator.js', '../point_src/unpack.js', '../point_src/pointlist.js', '../point_src/pointlistpen.js', '../point_src/pointpen.js', '../point_src/pointdraw.js', '../point_src/relative-xy.js', '../point_src/pointcast.js', '../point_src/point.js', '../point_src/events.js', '../point_src/automouse.js', '../point_src/stage-resize.js', '../point_src/functions/resolve.js', '../point_src/stage.js', '../point_src/functions/clamp.js', '../point_src/distances.js', '../point_src/protractor.js', '../point_src/text/beta.js', '../point_src/dragging.js', '../point_src/setunset.js', '../point_src/stroke.js')
markdown {'html': '', 'content': 'categories: curve\nfiles:\n head\n ../point_src/point-content.js\n pointlist\n point\n mouse\n stage\n dragging\n ../point_src/setunset.js\n ../point_src/stroke.js'}