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 BSpline { public partial class Form1 : Form { public void displayfunc(int pointCount, int degree, float[] arr, out int sz) { int k = degree + 1; int n = pointCount - 1; for (int i = 1; i <= n + k + 1; ++i) { if (i <= k) { arr[i - 1] = 0; } else if (i <= n + 1) { arr[i - 1] = i - k; } else { arr[i - 1] = n - k + 2; } } sz = n + k + 1; } public Form1() { InitializeComponent(); // displayfunc(pCount, degree, knotArr, out knotSize); tmax = knotArr[knotSize - 1]; } int activeId = -1; float[] knotArr = new float[]{0.0f, 0.0f, 0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 6.0f, 6.0f}; int degree = 2; int pCount = 8; float tmin = 0; float tmax = 0; int knotSize = 11; float getNRec(float t, int ind, int k) { if (k == 1) { if (knotArr[ind] <= t && knotArr[ind + 1] > t) return 1; else return 0; } float retval = 0; float vl1 = ((t - knotArr[ind]) * getNRec(t, ind, k - 1)); float vl2 = (knotArr[ind + k - 1] - knotArr[ind]); if (vl2 > 0.00000001) retval += vl1 / vl2; vl1 = (knotArr[ind + k] - t) * getNRec(t, ind + 1, k - 1); vl2 = (knotArr[ind + k] - knotArr[ind + 1]); if (vl2 > 0.00000001) retval += vl1 / vl2; return retval; } float getN(float t, int ind, int k) { int n = pCount; float[,] koeffs = new float[knotArr.Length, knotArr.Length]; for (int i = 0; i < n; ++i) { if (knotArr[i] <= t && knotArr[i + 1] > t) { koeffs[1, i] = 1; } else { koeffs[1, i] = 0; } } for (int lk = 2; lk <= k; ++lk) { for (int i = 0; i < n; ++i) { float retval = 0; float vl1 = ((t - knotArr[i]) * koeffs[lk - 1, i]); float vl2 = (knotArr[i + lk - 1] - knotArr[i]); if (vl2 > 0.00000001) retval += vl1 / vl2; vl1 = (knotArr[i + lk] - t) * koeffs[lk - 1, i + 1]; vl2 = (knotArr[i + lk] - knotArr[i + 1]); if (vl2 > 0.00000001) retval += vl1 / vl2; koeffs[lk, i] = retval; } } return koeffs[k, ind]; } float[] xpnt = new float[8] { 10, 90, 120, 180, 230, 260, 270, 340 }; float[] ypnt = new float[8] { 10, -20, 10, -10, 20, -40, 20, 0}; float[] h = new float[8] { 1, 1, 1, 1, 1, 1, 1, 1 }; private void Form1_Paint(object sender, PaintEventArgs e) { Graphics v = e.Graphics; v.TranslateTransform(250, 250); for (int i = 0; i < xpnt.Length; ++i) { v.DrawEllipse(new Pen(Color.Red), xpnt[i], ypnt[i], 3, 3); } for (float t = tmin; t <= tmax; t += 0.01f) { float x = 0, y = 0; float sm = 0; for (int i = 0; i < xpnt.Length; ++i) { float basis = getN(t, i, degree + 1); x += xpnt[i] * basis * h[i]; y += ypnt[i] * basis * h[i]; sm += basis * h[i]; } v.DrawEllipse(new Pen(Color.Black), x / sm, y / sm, 1, 1); } } private void Form1_MouseMove(object sender, MouseEventArgs e) { Invalidate(); } private void Form1_MouseDown(object sender, MouseEventArgs e) { activeId = 1; } private void Form1_MouseUp(object sender, MouseEventArgs e) { activeId = -1; } } }