diff --git a/index.html b/index.html index b18a679..99590b1 100644 --- a/index.html +++ b/index.html @@ -13,6 +13,10 @@
+
+ + +
@@ -80,7 +84,20 @@ function clearPoles() { setZplane(poles, zeros); } -// this var will hold the index of the selected text +// variables for mag and phase responses +var Z = new Array(100); +var freqAxis = new Array(100); + +for(let i = 0; i < 100; i++){ + Z[i] = Math.complex(Math.cos(Math.PI * (i/100)), Math.sin(Math.PI * (i/100))); + freqAxis[i] = Math.PI * (i/100); +} + +var magResponse = new Array; +var phaseResponse = new Array; + + +// this var will hold the index of the selected point in zplane var selectedPoint = -1; // test if x,y is inside the bounding box of texts[textIndex] @@ -293,6 +310,7 @@ function setZplane(poles, zeros) { ctx.stroke(); } } + drawResponses(); } function showZplane(poles, zeros) { @@ -350,8 +368,51 @@ function showZplane(poles, zeros) { ctx.arc(x + pad, y + pad, zSize, 0, 2*Math.PI); ctx.stroke(); } + drawResponses(); } +function drawResponses() { + for(let i = 0; i < 100; i++){ + let magPoint = Math.complex(0,0); + let phasePoint = Math.complex(0,0); + for(let j = 0; j < zeros.length; j++){ + magPoint *= Math.abs(Math.subtract(Z[i], Math.complex(zeros[j][0], zeros[j][1]))) + phasePoint *= Math.atan(Math.subtract(Z[i], Math.complex(zeros[j][0], zeros[j][1]))) + } + for(let j = 0; j < poles.length; j++){ + magPoint /= Math.abs(Math.subtract(Z[i], Math.complex(poles[j][0], poles[j][1]))) + phasePoint /= Math.atan(Math.subtract(Z[i], Math.complex(poles[j][0], poles[j][1]))) + } + magResponse.push(magPoint); + phaseResponse.push(phasePoint); + } + + // normalize + var maxMag = Math.max(...magResponse); + var maxPhase = Math.max(...phaseResponse); + for(let i = 0; i < magResponse; i++) { + magResponse[i] /= maxMag; + phaseResponse[i] /= maxPhase; + } + + let magData = []; + let phaseData = []; + + for(let i = 0; i < 100; i++){ + magData.push([freqAxis[i], magResponse[i]]); + phaseData.push([freqAxis[i], phaseResponse[i]]); + } + + // plot mag_response + var container = document.getElementById('mag_response'); + graph = Flotr.draw(container, [ magData ], { yaxis: { max : 0, min : -120 } }); + + // plot phase_response + var container = document.getElementById('phase_response'); + graph = Flotr.draw(container, [ phaseData ], { yaxis: { max : 60, min : -60 } }); +} + + setZplane(poles, zeros); diff --git a/script.js b/script.js new file mode 100644 index 0000000..07b0841 --- /dev/null +++ b/script.js @@ -0,0 +1,124 @@ +var svg = d3.select("svg"), + margin = {top: 20, right: 20, bottom: 30, left: 50}, + width = +svg.attr("width") - margin.left - margin.right, + height = +svg.attr("height") - margin.top - margin.bottom; + +// make initial poles and zeros state +let points = d3.range(1, 10).map(function(i) { + return [0, 50 + Math.random() * (height - 100)]; +}); + +// generate x and y axis ranges +var x = d3.scaleLinear() + .rangeRound([0, width]); +var y = d3.scaleLinear() + .rangeRound([height, 0]); + +var xAxis = d3.axisBottom(x), + yAxis = d3.axisLeft(y); + + +let drag = d3.drag() + .on('start', dragstarted) + .on('drag', dragged) + .on('end', dragended); + +svg.append('rect') + .attr('class', 'zoom') + .attr('cursor', 'move') + .attr('fill', 'none') + .attr('pointer-events', 'all') + .attr('width', width) + .attr('height', height) + .attr('transform', 'translate(' + margin.left + ',' + margin.top + ')'); + + var focus = svg.append("g") + .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); + +x.domain(d3.extent(points, function(d) { return d[0]; })); +y.domain(d3.extent(points, function(d) { return d[1]; })); + + +focus.selectAll('circle') + .data(points) + .enter() + .append('circle') + .attr('r', 5.0) + .attr('cx', function(d) { return x(d[0]); }) + .attr('cy', function(d) { return y(d[1]); }) + .style('cursor', 'pointer') + .style('stroke', 'black') + .style('fill', 'blue'); + +focus.selectAll('circle') + .call(drag); + +focus.append('g') + .attr('class', 'axis axis--x') + .attr('transform', 'translate(0,' + height/2 + ')') + .call(xAxis.ticks(0)); + +focus.append('g') + .attr('class', 'axis axis--y') + .attr('transform', 'translate(' + width/2 + ',0)') + .call(yAxis.ticks(0)); + +focus.append('g') + .append('circle') + .style('stroke', 'red') + .style('fill', 'none') + .attr('r', 100.0) + .attr('transform', 'translate(' + width/2 + ',' + height/2 + ')'); + + +var Z = new Array(100); +var freqAxis = new Array(100); + +for(let i = 0; i < 100; i++){ + Z[i] = math.complex(math.cos(math.PI * (i/100)), math.sin(math.PI * (i/100))); + freqAxis[i] = math.PI * (i/100); +} + +var magResponse = new Array; +var phaseResponse = new Array; + +function drawResponses() { + for(let i = 0; i < 100; i++){ + let magPoint = math.complex(0,0); + let phasePoint = math.complex(0,0); + for(let j = 0; j < zeros.length; j++){ + magPoint *= math.abs(math.subtract(Z[i], math.complex(zeros[j][0], zeros[j][1]))) + phasePoint *= math.atan(math.subtract(Z[i], math.complex(zeros[j][0], zeros[j][1]))) + } + for(let j = 0; j < poles.length; j++){ + magPoint /= math.abs(math.subtract(Z[i], math.complex(poles[j][0], poles[j][1]))) + phasePoint /= math.atan(math.subtract(Z[i], math.complex(poles[j][0], poles[j][1]))) + } + magResponse.push(magPoint); + phaseResponse.push(phasePoint); + } + + // normalize + var maxMag = Math.max(...magResponse); + var maxPhase = Math.max(...phaseResponse); + for(let i = 0; i < magResponse; i++) { + magResponse[i] /= maxMag; + phaseResponse[i] /= maxPhase; + } + + let magData = []; + let phaseData = []; + + for(let i = 0; i < 100; i++){ + magData.push([freqAxis[i], magResponse[i]]); + phaseData.push([freqAxis[i], phaseResponse[i]]); + } + + // plot mag_response + var container = document.getElementById('mag_response'); + graph = Flotr.draw(container, [ magData ], { yaxis: { max : 0, min : -120 } }); + + // plot phase_response + var container = document.getElementById('phase_response'); + graph = Flotr.draw(container, [ phaseData ], { yaxis: { max : 60, min : -60 } }); +} \ No newline at end of file diff --git a/script2.js b/script2.js index d0f1457..988b8bf 100644 --- a/script2.js +++ b/script2.js @@ -292,29 +292,29 @@ function setZplane(poles, zeros) { else graph = Flotr.draw(container, [ mag ], { yaxis: { max : 0, min : -120 }, xaxis: { tickFormatter: nullTickFormatter_polezero2 } }); - // show coefficients - var coefsList = "poles at " + poles[0][0]; - var temp = poles[0][1]; - if (temp != 0) - coefsList += " \xB1 " + Math.abs(temp) + "i\n"; - else - coefsList += ", " + poles[1][0] + "\n"; + // // show coefficients + // var coefsList = "poles at " + poles[0][0]; + // var temp = poles[0][1]; + // if (temp != 0) + // coefsList += " \xB1 " + Math.abs(temp) + "i\n"; + // else + // coefsList += ", " + poles[1][0] + "\n"; - coefsList += "zeros at " + zeros[0][0]; - var temp = zeros[0][1]; - if (temp != 0) - coefsList += " \xB1 " + Math.abs(temp) + "i\n"; - else - coefsList += ", " + zeros[1][0] + "\n"; + // coefsList += "zeros at " + zeros[0][0]; + // var temp = zeros[0][1]; + // if (temp != 0) + // coefsList += " \xB1 " + Math.abs(temp) + "i\n"; + // else + // coefsList += ", " + zeros[1][0] + "\n"; - var coefs = getBiquadCoefs_polezero2(poles, zeros, magMax); - coefsList += "\na0 = " + coefs[0] + "\n"; - coefsList += "a1 = " + coefs[1] + "\n"; - coefsList += "a2 = " + coefs[2] + "\n"; - coefsList += "b1 = " + coefs[4] + "\n"; - coefsList += "b2 = " + coefs[5]; + // var coefs = getBiquadCoefs_polezero2(poles, zeros, magMax); + // coefsList += "\na0 = " + coefs[0] + "\n"; + // coefsList += "a1 = " + coefs[1] + "\n"; + // coefsList += "a2 = " + coefs[2] + "\n"; + // coefsList += "b1 = " + coefs[4] + "\n"; + // coefsList += "b2 = " + coefs[5]; - document.getElementById("coefsList_polezero2").value = coefsList; + // document.getElementById("coefsList_polezero2").value = coefsList; } function getBiquadCoefs_polezero2(poles, zeros, gainMax) {