digital-filter-designer/script.js

124 wiersze
3.7 KiB
JavaScript

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 } });
}