Please help me create a p5.js simulation that helps
students understand Sampling and Aliasing. The Nyquist-Shannon
sampling theorem and the concept of aliasing involve understanding
how continuous signals are represented in discrete form. Grasping
how undersampling leads to frequency overlap (aliasing) can be non-intuitive.
I would like an Interactive p5.js program that can demonstrate how
varying the sampling rate affects the reconstructed signal.
By adjusting parameters in real-time, students can visualize
aliasing effects and the importance of adhering to the Nyquist rate.
Please create a p5.js simulation that allows students to use a
slider to adjust the sampling rate for a waveform using a slider.
Display two waveforms. One is the input with the samples drawn
as radius 7 red circles. The second waveform is one done from
the reconstruction of the sampling points.
Place the original on the top and the reconstruction under
the original.
// region drawing parameters// the width of the entire canvasletcanvasWidth=400;// The top drawing region above the interactive controlsletdrawHeight=400;// control region heightletcontrolHeight=50;// The total hight of both the drawing region height + the control region heightletcanvasHeight=450;// margin around the active plotting regionletmargin=25;// larger text so students in the back of the room can read the labelsletdefaultTextSize=16;functionsetup{constcanvas=createCanvas(canvasWidth,canvasHeight);// canvas.parent('canvas-container');varmainElement=document.querySelector('main');canvas.parent(mainElement);textSize(defaultTextSize);// create a new slider at th bottom of the canvasmySlider=createSlider(0,100,50,1);mySlider.position(sliderLeftMargin,drawHeight+12);mySlider.size(canvasWidth-2*margin);}functiondraw(){// make the background drawing region a very light bluefill('aliceblue');rect(0,0,canvasWidth,drawHeight);// make the background of the controls area whitefill('white')rect(0,drawHeight,canvasWidth,controlHeight);// get the updated slider valueval=mySlider.value();// put your custom code here// draw label and valuetext("MySlider: "+val,10,drawHeight+25)}
ChatGPT Response
o1-preview Thought for 6 seconds
Sure! Below is a p5.js simulation that demonstrates sampling and aliasing. You can adjust the sampling rate using a slider to see how it affects the reconstructed signal.
// Nyquist-Shannon Sampling Rate MicroSim// region drawing parameters// the width of the entire canvasletcanvasWidth=450;// The top drawing region above the interactive controlsletdrawHeight=350;// control region heightletcontrolHeight=50;// The total height of both the drawing region height + the control region heightletcanvasHeight=drawHeight+controlHeight;// margin around the active plotting regionletmargin=30;// larger text so students in the back of the room can read the labelsletdefaultTextSize=16;letsamplingRateSlider;letsamplingRate=22;// Initial sampling rateletsignalFrequency=5;// Frequency of the original signallettime=[];letsignal=[];letsampledSignal=[];functionsetup(){createCanvas(canvasWidth,canvasHeight);constcanvas=createCanvas(canvasWidth,canvasHeight);varmainElement=document.querySelector('main');canvas.parent(mainElement);textSize(defaultTextSize);// slider to allow the user to select the sampling ratesamplingRateSlider=createSlider(1,50,samplingRate,.1);samplingRateSlider.position(20,drawHeight+30);samplingRateSlider.size(canvasWidth-margin);// Generate time valuesfor(lett=0;t<=width;t++){time.push(t);}// Generate original signal valuesfor(leti=0;i<time.length;i++){lett=time[i];signal[i]=sin(TWO_PI*signalFrequency*(t/width));}}functiondraw(){// Fill the drawing region background with 'aliceblue'fill('aliceblue');stroke('black');rect(0,0,canvasWidth,drawHeight);// Fill the control region background with 'white'fill('white');rect(0,drawHeight,canvasWidth,controlHeight);samplingRate=samplingRateSlider.value();// Draw titletextSize(24);fill('black');strokeWeight(0);textAlign(CENTER);text('Nyquist-Shannon Sampling Rate',canvasWidth/2,30);// Draw labelstextSize(16);fill('black');strokeWeight(0);textAlign(CENTER);text('Original Signal with Sampling Points',canvasWidth/2,60);text('Reconstructed Signal from Samples',canvasWidth/2,drawHeight/2+45);textAlign(LEFT);text('Sampling Rate: '+round(samplingRate/5,2)+' samples per period',20,drawHeight+20);// Draw original signalstroke(0);noFill();strokeWeight(1.5);beginShape();for(leti=0;i<signal.length;i++){lety=map(signal[i],-1,1,100,0);vertex(time[i],y+80);}endShape();// Sample the signalsampledSignal=[];letsampleInterval=floor(width/samplingRate);for(leti=0;i<time.length;i+=sampleInterval){lety=map(signal[i],-1,1,100,0);sampledSignal.push({x:time[i],y:y+30});// Draw sampling pointsfill(255,0,0);noStroke();circle(time[i],y+80,7);}// Reconstruct the signal from samplesstroke('blue');strokeWeight(2);noFill();beginShape();for(leti=0;i<sampledSignal.length;i++){vertex(sampledSignal[i].x,sampledSignal[i].y+height/2);}endShape();// Draw reconstructed signalstroke(0);noFill();beginShape();for(leti=0;i<sampledSignal.length-1;i++){letx1=sampledSignal[i].x;lety1=sampledSignal[i].y+height/2;letx2=sampledSignal[i+1].x;lety2=sampledSignal[i+1].y+height/2;line(x1,y1,x2,y2);}endShape();}
How to Use the Simulation
Adjust the Sampling Rate: Use the slider at the bottom of the canvas to change the sampling rate. The sampling rate is displayed above the slider.
Observe the Top Graph: The top waveform represents the original signal. Red circles indicate the sampling points based on the current sampling rate.
Observe the Bottom Graph: The bottom waveform is reconstructed from the sampled points. As you adjust the sampling rate, notice how the reconstructed signal changes.
Explanation of the Code
Variables
samplingRateSlider: The slider control for adjusting the sampling rate.
samplingRate: The current sampling rate value from the slider.
signalFrequency: The frequency of the original signal.
time, signal, sampledSignal: Arrays to store time values, original signal values, and sampled signal points, respectively.
setup()` Function
Initializes the canvas and the slider.
Generates time values and computes the original signal using a sine function.
draw() Function
Clears the background and updates the sampling rate from the slider.
Draws labels and the original signal waveform.
Samples the original signal at intervals based on the sampling rate and draws red circles at the sampling points.
Reconstructs the signal from the sampled points and draws it in the bottom half of the canvas.
Key Concepts Demonstrated
Sampling Rate: The number of samples taken per period of the signal. A higher sampling rate captures the signal more accurately.
Aliasing: When the sampling rate is too low (below the Nyquist rate), the reconstructed signal may differ significantly from the original, demonstrating aliasing effects.
Running the Simulation
To run this simulation:
Copy the code above.
Go to the p5.js online editor.
Paste the code into the editor.
Click the "Play" button to start the simulation.
Feel free to experiment with different signal frequencies or modify the code to explore further concepts related to sampling and aliasing.