補間法(ベジエ曲線)

/****************************/
/* n次ベジエ曲線           */
/*      coded by Y.Suganuma */
/****************************/
#include <stdio.h>

double *Bezier(int, double **, double);

int main()
{
	double **B, t, step = 0.05, *P;
	int i1, n;
					// 設定
	n = 3;
	B = new double *[n+1];
	for (i1 = 0; i1 <= n; i1++)
		B[i1] = new double [2];

	B[0][0] = 1.0;
	B[0][1] = 1.0;
	B[1][0] = 2.0;
	B[1][1] = 3.0;
	B[2][0] = 4.0;
	B[2][1] = 3.0;
	B[3][0] = 3.0;
	B[3][1] = 1.0;
					// 実行と出力
	t = 0.0;
	for (i1 = 0; i1 <= 20; i1++) {
		P = Bezier(n, B, t);
		printf("%f %f %f\n", t, P[0], P[1]);
		t += step;
	}

	for (i1 = 0; i1 <= n; i1++)
		delete [] B[i1];
	delete [] B;
	delete [] P;

	return 0;
}

/*******************************/
/* n次ベジエ曲線              */
/*      n : 次数               */
/*      B : 多角形の頂点座標   */
/*      t : 計算したい点の位置 */
/*      return : 座標          */
/*      coded by Y.Suganuma    */
/*******************************/
double brend(int, int, double);
double kaijo(int);

double *Bezier(int n, double **B, double t)
{
	double *P, J;
	int i;
					// 初期設定
	P    = new double [2];
	P[0] = 0.0;
	P[1] = 0.0;
					// 計算
	for (i = 0; i <= n; i++) {
		J     = brend(n, i, t);
		P[0] += B[i][0] * J;
		P[1] += B[i][1] * J;
	}

	return P;
}

/*******************************/
/* ベジエ基底関数              */
/*      n,i : 次数             */
/*      t : 計算したい点の位置 */
/*      return : 結果          */
/*******************************/
double brend(int n, int i, double t)
{
	double ni, x = 1.0, y = 1.0;
	int i1;

	ni = kaijo(i) * kaijo(n-i);
	ni = kaijo(n) / ni;

	for (i1 = 1; i1 <= i; i1++)
		x *= t;
	t = 1.0 - t;
	for (i1 = 1; i1 <= n-i; i1++)
		y *= t;

	return ni * x * y;
}

/*****************/
/* nの階乗の計算 */
/*****************/
double kaijo(int n)
{
	double k = 1.0;
	int i1;

	if (n > 1) {
		for (i1 = 2; i1 <= n; i1++)
			k *= i1;
	}

	return k;
}