digital-filter-designer/index.html

342 wiersze
9.9 KiB
HTML

<!DOCTYPE html>
<style>
#zplane_polezero2{border:2px solid black;}
</style>
<body>
<canvas id="zplane_polezero2" width=300 height=300></canvas>
<div id="zeros"></div>
<div id="poles"></div>
<button onclick="addNewPole()">New Pole</button>
<button onclick="addNewZero()">New Zero</button>
</body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script>
// variables used to get mouse position on the canvas
var $canvas = $("#zplane_polezero2");
var canvasOffset = $canvas.offset();
var offsetX = canvasOffset.left;
var offsetY = canvasOffset.top;
var scrollX = $canvas.scrollLeft();
var scrollY = $canvas.scrollTop();
// variables to save last mouse position
// used to see how far the user dragged the mouse
// and then move the text by that distance
var startX;
var startY;
var zeros = new Array;
var poles = new Array;
var zerosNum = 0;
var polesNum = 0;
function addNewPole() {
// console.log("I'm here!");
points = document.getElementById("poles");
var div = document.createElement("div");
div.id = 'pole' + polesNum + '_polezero2';
points.appendChild(div);
poles.push([0, 0]);
polesNum = polesNum + 1;
setZplane(poles, zeros);
}
function addNewZero() {
points = document.getElementById("zeros");
var div = document.createElement('div');
div.id = 'zero' + zerosNum + '_polezero2';
points.appendChild(div);
zeros.push([0, 0]);
zerosNum = zerosNum + 1;
setZplane(poles, zeros);
}
// function updateZplane() {
// let p = [];
// let z = [];
// // for(let i = 1; i < zeros.length; i++){
// // p.append(document.getElementById("pole" + i + "_polezero2").value / 200);
// // }
// // for(let i = 1; i < zeros.length; i++){
// // z.append(document.getElementById("zero" + i + "_polezero2").value / 200);
// // }
// // var p1 = document.getElementById("pole1_polezero2").value / 200;
// // var p2 = document.getElementById("pole2_polezero2").value / 200;
// // var z1 = document.getElementById("zero1_polezero2").value / 200;
// // var z2 = document.getElementById("zero2_polezero2").value / 200;
// // var poles = [];
// // var zeros = [];
// // var polesPaired = document.getElementById("polePair_polezero2").checked;
// // var zerosPaired = document.getElementById("zeroPair_polezero2").checked;
// var x1, y1;
// if (polesPaired) {
// // complex conjugate poles and zeros
// x1 = Math.cos(p2 * Math.PI) * p1;
// if (Math.abs(x1) < 1E-14)
// x1 = 0;
// y1 = Math.sin(p2 * Math.PI) * p1;
// if (Math.abs(y1) < 1E-14)
// y1 = 0;
// poles.push([x1, y1]);
// poles.push([x1, -y1]);
// }
// else {
// poles.push([p1 * 2 - 1, 0]);
// poles.push([p2 * 2 - 1, 0]);
// }
// if (zerosPaired) {
// x1 = Math.cos(z2 * Math.PI) * z1;
// if (Math.abs(x1) < 1E-14)
// x1 = 0;
// y1 = Math.sin(z2 * Math.PI) * z1;
// if (Math.abs(y1) < 1E-14)
// y1 = 0;
// zeros.push([x1, y1]);
// zeros.push([x1, -y1]);
// }
// else {
// zeros.push([z1 * 2 - 1, 0]);
// zeros.push([z2 * 2 - 1, 0]);
// }
// setZplane(poles, zeros);
// }
// this var will hold the index of the selected text
var selectedPoint = -1;
// test if x,y is inside the bounding box of texts[textIndex]
function pointHittest(x, y, textIndex) {
console.log([x, y]);
console.log("poles.length is " + poles.length);
if(textIndex >= polesNum){
console.log("check some zero!");
return (x >= zeros[textIndex - polesNum][0] - 0.05 && x <= zeros[textIndex - polesNum][0] + 0.05 && y >= zeros[textIndex - polesNum][1] - 0.05 && y <= zeros[textIndex - polesNum][1] + 0.05);
}
if(textIndex < polesNum){
console.log("check some pole!");
return (x >= poles[textIndex][0] - 0.05 && x <= poles[textIndex][0] + 0.05 && y >= poles[textIndex][1] - 0.05 && y <= poles[textIndex][1] + 0.05);
}
}
// handle mousedown events
// iterate through texts[] and see if the user
// mousedown'ed on one of them
// If yes, set the selectedText to the index of that text
function handleMouseDown(e) {
e.preventDefault();
startX = parseInt(e.clientX - offsetX);
startY = parseInt(e.clientY - offsetY);
console.log("you selected point [" + startX + ", " + startY + "]");
console.log("which is point [" + (startX-150)/100 + ", " + -(startY-150)/100 + "]");
console.log("poles number is " + poles.length);
console.log("zeros number is " + zeros.length);
totalLength = polesNum + zerosNum;
// Put your mousedown stuff here
for (var i = 0; i < totalLength; i++) {
if (pointHittest((startX-150)/100, -(startY-150)/100, i)) {
selectedPoint = i;
if(i >= polesNum){
console.log("selected zero" + (i - polesNum));
}else if(i < polesNum){
console.log("selected pole" + (i));
}
}
}
}
// handle mousemove events
// calc how far the mouse has been dragged since
// the last mousemove event and move the selected text
// by that distance
function handleMouseMove(e) {
if (selectedPoint < 0) {
return;
}
console.log("Mouse is Moving!...");
e.preventDefault();
mouseX = parseInt(e.clientX - offsetX);
mouseY = parseInt(e.clientY - offsetY);
// Put your mousemove stuff here
var dx = (mouseX - startX)/100;
var dy = -(mouseY - startY)/100;
console.log("MouseXY -> [" + mouseX + ", " + mouseY + "]");
console.log("MouseXY -> [" + startX + ", " + startY + "]");
startX = mouseX;
startY = mouseY;
console.log("moved to point [" + startX + ", " + startY + "]");
console.log("which is point [" + (startX-150)/100 + ", " + -(startY-150)/100 + "]");
console.log("moved by [" + dx + ", " + dy + "]");
if(selectedPoint >= poles.length){
zeros[selectedPoint - poles.length][0] += dx;
zeros[selectedPoint - poles.length][1] += dy;
}else if(selectedPoint < poles.length){
poles[selectedPoint][0] += dx;
poles[selectedPoint][1] += dy;
}
// addNewPole([dx, dy]);
setZplane(poles, zeros);
}
// done dragging
function handleMouseUp(e) {
e.preventDefault();
selectedPoint = -1;
}
// also done dragging
function handleMouseOut(e) {
e.preventDefault();
selectedPoint = -1;
}
// listen for mouse events
$("#zplane_polezero2").mousedown(function (e) {
handleMouseDown(e);
});
$("#zplane_polezero2").mousemove(function (e) {
handleMouseMove(e);
});
$("#zplane_polezero2").mouseup(function (e) {
handleMouseUp(e);
});
$("#zplane_polezero2").mouseout(function (e) {
handleMouseOut(e);
});
function setZplane(poles, zeros) {
// console.log("drawing..");
// console.log("poles number is " + poles.length);
// console.log("zeros number is " + zeros.length);
var radius = 100; // radius of unit circle
var pSize = 4; // size of pole and zero graphic
var zSize = 4;
var c=document.getElementById("zplane_polezero2");
var ctx=c.getContext("2d");
ctx.clearRect(0, 0, c.width, c.height);
var pad = (c.width - 2 * radius) / 2; // padding on each side
// unit circle
ctx.beginPath();
ctx.strokeStyle="red";
ctx.arc(radius+pad,radius+pad,radius,0,2*Math.PI);
ctx.stroke();
// y axis
ctx.beginPath();
//ctx.lineWidth="1";
ctx.strokeStyle="lightgray";
ctx.moveTo(radius+pad,0);
ctx.lineTo(radius+pad,c.height);
ctx.font = "italic 8px sans-serif";
ctx.fillText("Im", radius+pad+2, pad-2);
// x axis
ctx.moveTo(0,radius+pad);
ctx.lineTo(c.width,radius+pad);
ctx.fillText("Re", radius+radius+pad+2, radius+pad-2);
ctx.stroke(); // Draw it
// poles
ctx.strokeStyle="blue";
var idx;
for (idx = 0; idx < poles.length; idx++) {
var x = radius + Math.round(radius * poles[idx][0]);
var y = radius - Math.round(radius * poles[idx][1]);
ctx.beginPath();
ctx.moveTo(x - pSize + pad, y - pSize + pad);
ctx.lineTo(x + pSize + pad, y + pSize + pad);
ctx.moveTo(x - pSize + pad, y + pSize + pad);
ctx.lineTo(x + pSize + pad, y - pSize + pad);
ctx.stroke();
}
// zeros
for (idx = 0; idx < zeros.length; idx++) {
var x = radius + Math.round(radius * zeros[idx][0]);
var y = radius - Math.round(radius * zeros[idx][1]);
ctx.beginPath();
ctx.arc(x + pad, y + pad, zSize, 0, 2*Math.PI);
ctx.stroke();
}
}
function showZplane(poles, zeros) {
var radius = 100; // radius of unit circle
var pSize = 4; // size of pole and zero graphic
var zSize = 4;
var c=document.getElementById("all_pass_filter");
var ctx=c.getContext("2d");
ctx.clearRect(0, 0, c.width, c.height);
var pad = (c.width - 2 * radius) / 2; // padding on each side
// unit circle
ctx.beginPath();
ctx.strokeStyle="red";
ctx.arc(radius+pad,radius+pad,radius,0,2*Math.PI);
ctx.stroke();
// y axis
ctx.beginPath();
//ctx.lineWidth="1";
ctx.strokeStyle="lightgray";
ctx.moveTo(radius+pad,0);
ctx.lineTo(radius+pad,c.height);
ctx.font = "italic 8px sans-serif";
ctx.fillText("Im", radius+pad+2, pad-2);
// x axis
ctx.moveTo(0,radius+pad);
ctx.lineTo(c.width,radius+pad);
ctx.fillText("Re", radius+radius+pad+2, radius+pad-2);
ctx.stroke(); // Draw it
// poles
ctx.strokeStyle="blue";
var idx;
for (idx = 0; idx < poles.length; idx++) {
var x = radius + Math.round(radius * poles[idx][0]);
var y = radius - Math.round(radius * poles[idx][1]);
ctx.beginPath();
ctx.moveTo(x - pSize + pad, y - pSize + pad);
ctx.lineTo(x + pSize + pad, y + pSize + pad);
ctx.moveTo(x - pSize + pad, y + pSize + pad);
ctx.lineTo(x + pSize + pad, y - pSize + pad);
ctx.stroke();
}
// zeros
for (idx = 0; idx < zeros.length; idx++) {
var x = radius + Math.round(radius * zeros[idx][0]);
var y = radius - Math.round(radius * zeros[idx][1]);
ctx.beginPath();
ctx.arc(x + pad, y + pad, zSize, 0, 2*Math.PI);
ctx.stroke();
}
}
setZplane(poles, zeros);
addNewPole([0, 0]);
</script>