kopia lustrzana https://github.com/badra022/digital-filter-designer
added drawResponse function - still debugging
rodzic
4d4c46f460
commit
17d08f9d26
63
index.html
63
index.html
|
@ -13,6 +13,10 @@
|
|||
<button onclick="clearAllPoints()">clear All</button><br>
|
||||
<input type="checkbox" id="conjugate" onclick="setZplane(poles, zeros)">
|
||||
<label> add Conjugates</label>
|
||||
<div align="right">
|
||||
<canvas id="mag_response" width=600 height=300></canvas>
|
||||
<canvas id="phase_response" width=600 height=300></canvas>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
||||
|
|
|
@ -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 } });
|
||||
}
|
40
script2.js
40
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) {
|
||||
|
|
Ładowanie…
Reference in New Issue