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 Form1()
{
InitializeComponent();
generateKnot(pCount, degree, knotArr, out knotSize);
tmax = knotArr[knotSize - 1];
}
int activeId = -1;
public void generateKnot(int pointCount, int degree, float[] knot, out int knotSize)
{
int k = degree + 1;
int n = pointCount - 1;
for (int i = 1; i <= n + k + 1; ++i)
{
if (i <= k)
{
knot[i - 1] = 0;
}
else
if (i <= n + 1)
{
knot[i - 1] = i - k;
}
else
{
knot[i - 1] = n - k + 2;
}
}
knotSize = n + k + 1;
}
float[] knotArr = new float[500];
int degree = 2;
int pCount = 8;
float tmin = 0;
float tmax = 0;
int knotSize = 0;
float getN(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]) * getN(t, ind, k - 1));
float vl2 = (knotArr[ind + k - 1] - knotArr[ind]);
if (vl2 > 0.00000001)
retval += vl1 / vl2;
vl1 = (knotArr[ind + k] - t) * getN(t, ind + 1, k - 1);
vl2 = (knotArr[ind + k] - knotArr[ind + 1]);
if (vl2 > 0.00000001)
retval += vl1 / vl2;
return retval;
}
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, 2, 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;
}
}
}