using System using System Collections Generic using System ComponentMo

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
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<float> knot = new List<float>();
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<float> GetKnot(int n, int k) {
int nKnots = n + k;
List<float> retValue = new List<float>(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);
}
}
}
}