kopia lustrzana https://github.com/badra022/digital-filter-designer
124 wiersze
3.7 KiB
JavaScript
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 } });
|
|
} |