補間法(ベジエ曲線)

<?php

/****************************/
/* n次ベジエ曲線           */
/*      coded by Y.Suganuma */
/****************************/

					// 設定
	$step = 0.05;
	$n    = 3;
	$B    = array($n+1);
	for ($i1 = 0; $i1 <= $n; $i1++)
		$B[$i1] = array(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;
	}

/*******************************/
/* n次ベジエ曲線              */
/*      n : 次数               */
/*      B : 多角形の頂点座標   */
/*      t : 計算したい点の位置 */
/*      return : 座標          */
/*      coded by Y.Suganuma    */
/*******************************/
function Bezier($n, $B, $t)
{
					// 初期設定
	$P    = array(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 : 結果          */
/*******************************/
function brend($n, $i, $t)
{
	$x  = 1.0;
	$y  = 1.0;
	$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の階乗の計算 */
/*****************/
function kaijo($n)
{
	$k = 1.0;

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

	return $k;
}

?>