//--------------------------------------------------------------
//	周波数特性（振幅特性）描画用メソッド
//
//		作成者：三上直樹，2022/11/15 作成，ⓒ三上直樹 2022
//--------------------------------------------------------------

using System.Drawing;
using System.Windows.Forms;
//using System.Numerics;
using System.Drawing.Drawing2D;	// SmoothingMode で使用

using static System.Math;
using static System.Numerics.Complex;

namespace IIRフィルタ1次_振幅特性
{
	public partial class Form1 : Form
	{
		// 座標軸の描画
		private void DrawAxis(Graphics gr)
		{
			for (int n=0; n<=5; n++)
				gr.DrawLine(Pens.Black, DX_*n, Y0_, DX_*n, pictureBox1.Height);
			for (int n=0; n<=6; n++)
				gr.DrawLine(Pens.Black, 0, Y0_+DY_*n, pictureBox1.Width, Y0_+DY_*n);
		}

		// 座標軸の目盛値やタイトルの描画
		private void DrawGraphStringt(Graphics gr)
		{
			Font myFont = new Font("Meiryo UI", 9);
			Brush myBrush = Brushes.Black;

			// 周波数軸
			float x0 = 44*dpiFactor_;
			float y0 = pictureBox1.Height + 2*dpiFactor_;
			gr.TranslateTransform(x0, y0);
			for (int n=0; n<=5; n++)
				gr.DrawString(n.ToString(), myFont, myBrush, DX_*n, 0);
			gr.DrawString("周波数 [kHz]", myFont, myBrush,
						  pictureBox1.Width/2-35*dpiFactor_, 20*dpiFactor_);

			// dB 軸
			gr.ResetTransform();
			float x1 = 25*dpiFactor_;
			float y1 = -9*dpiFactor_ + Y0_;
			gr.TranslateTransform(x1, y1);
			gr.DrawString("0", myFont, myBrush, 14, 0);
			for (int n=2; n<=6; n+=2)
				gr.DrawString((-n*10).ToString(), myFont, myBrush, 0, DY_*n);
			gr.RotateTransform(-90);
			gr.DrawString("利得 [dB]", myFont, myBrush,
						  -pictureBox1.Height/2-32*dpiFactor_, -16*dpiFactor_);

			gr.ResetTransform();
	}

		// 周波数応答の絶対値の描画
		private void DrawHz(Graphics gr)
		{
			const int DIV = 100;
			const double dw = PI/DIV;
			float dx = (pictureBox1.Width-1)/(float)DIV;
			PointF[] pt = new PointF[DIV+1];

			// 係数 b の設定
			double b = radioButton1.Checked ? 1.0 - a1_ : 1.0 + a1_;

			for (int n=0; n<=DIV; n++)
			{
				float db = 20.0f*(float)Log10(Hz(n*dw, a1_, b));
				if (db < -80.0f) db = -80.0f;
				pt[n] = new PointF(dx*n, Y0_-DY_*db/10.0f);
			}

			Pen myPen = new Pen(Color.Navy, 2) { LineJoin = LineJoin.Round };
			gr.SmoothingMode = SmoothingMode.AntiAlias;
			gr.DrawLines(myPen, pt);
			gr.SmoothingMode = SmoothingMode.Default;
		}

		// 一次 IIR フィルタの周波数応答の絶対値
		//		周波数応答	H(z) = b/(1 - a*exp(-jω))
		//		omega	正規化角周波数
		//		a, b	フィルタの係数
		private double Hz(double omega, double a, double b)
			=> Abs(b/(1.0 - a*Exp(-omega*ImaginaryOne)));
	}
}