using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace openBS { public partial class Form1 : Form { public int n, k; public List knot = new List(); public float tmin = 0.0f, tmax = 0.0f; public float[,] ctrlPoint = new float[,] {{50, 100, 150, 200, 250, 300, 350}, {20, 120, 20, 120, 20, 120, 20}}; public Pen black = new Pen(Color.Black), yellow = new Pen(Color.Red); Graphics view; public Form1() { InitializeComponent(); } // получение открытого узлового вектора public List GetKnot(int n, int k) { int nKnots = n + k; List retValue = new List(new float[nKnots]); int value = 0; for (int i = 0; i < nKnots; ++i) { if (i >= k && nKnots - i >= k) ++value; retValue[i] = value; } return retValue; } // нерекурсивный расчет базисных функций public float GetNormalizedFunction2(int i, int k, float t) { float[,] N = new float[k, i + k]; for (int height = 1; height <= k; ++height) { for (int width = i; width <= i + (k - height); ++width) { float downValue = 0.0f, downRightValue = 0.0f; if (height == 1) { if ((t >= knot[width]) && (t < knot[width + 1])) downValue = 1.0f; else downValue = 0.0f; N[height - 1, width] = downValue; continue; } else { downValue = N[height - 2, width]; downRightValue = N[height - 2, width + 1]; } float fNum = (t - knot[width]) * downValue, fDenum = knot[width + height - 1] - knot[width], sNum = (knot[width + height] - t) * downRightValue, sDenum = knot[width + height] - knot[width + 1], retValue = 0.0f; if (!fDenum.Equals(0.0f)) retValue += fNum / fDenum; if (!sDenum.Equals(0.0f)) retValue += sNum / sDenum; N[height - 1, width] = retValue; } } return N[k - 1, i]; } private void btn_draw_Click(object sender, EventArgs e) { n = int.Parse(tb_n.Text); k = int.Parse(tb_k.Text); knot = GetKnot(n, k); tmax = knot[knot.Count - 1]; drawBS(); drawBasis(); } // отрисовка базисных функций public void drawBasis() { view = pb_basis.CreateGraphics(); for (float t = tmin; t <= tmax; t += 0.005f) { for (int i = 0; i < ctrlPoint.GetLength(1); ++i) { float basis = GetNormalizedFunction2(i, k, t); view.DrawEllipse(black, t * 50.0f, 100.0f - basis * 100.0f, 1, 1); } } } // отрисовка b-сплайна public void drawBS() { view = pb_bs.CreateGraphics(); // отрисовка контрольных точек for (int i = 0; i < ctrlPoint.GetLength(1); ++i) view.DrawEllipse(yellow, ctrlPoint[0, i], ctrlPoint[1, i], 4, 4); // отрисовка кривой float x = 0.0f, y = 0.0f, curBasis = 0.0f; for (float t = tmin; t <= tmax; t += 0.005f) { x = 0.0f; y = 0.0f; for (int i = 0; i < ctrlPoint.GetLength(1); ++i) { curBasis = GetNormalizedFunction2(i, k, t); x += ctrlPoint[0, i] * curBasis; y += ctrlPoint[1, i] * curBasis; } view.DrawEllipse(black, x, y, 1, 1); } } } }