PHPでベジエ曲線を描く

(1/1)
ベジエ曲線(Bézier Curve)は、コンピュータ・グラフィックで滑らかな曲線を描く時に使われるもので、HTMLのSVGやcanvasで使えるほか、PHPでもメソッド ImagickDraw::bezier を使って描くことができる。
今回は、これらの機能を使わず、PHPで数式をプログラミングし、任意次元のベジエ曲線を描くプログラムを作る。

(2026年2月21日)PHP8.5対応:imagedestroyを使わない, pahooInputData.php導入

目次

サンプル・プログラム:実行例

PHPでベジエ曲線を描く

サンプル・プログラム

圧縮ファイルの内容
BezierCurve.phpサンプル・プログラム本体
pahooInputData.phpデータ入力に関わる関数群。
使い方は「数値入力とバリデーション」「文字入力とバリデーション」などを参照。include_path が通ったディレクトリに配置すること。
BezierCurve.php 更新履歴
バージョン 更新日 内容
1.2.0 2022/04/24 PHP8.5対応:imagedestroyを使わない, pahooInputData.php導入
1.1 2022/04/24 パラメータ定数化,PHP8対応,リファラ・チェック改良
1.0 2019/04/15 初版
pahooInputData.php 更新履歴
バージョン 更新日 内容
2.0.1 2025/08/11 getParam() bug-fix
2.0.0 2025/08/11 pahooLoadEnv() 追加
1.9.0 2025/07/26 getParam() 引数に$trim追加
1.8.1 2025/03/15 validRegexPattern() debug
1.8.0 2024/11/12 validRegexPattern() 追加

ベジエ曲線とは

ベジエ曲線の軌跡は、バーンスタイン基底関数によって次のように表現できる。 $$ \displaystyle \left \{ \begin{align*} B_k(t) &= (1 - t)B_{k-1} + t B_{k}(t) \ \small \ldots 1 < k \leq n,\ 0 \leq t \leq 1 \\ \\ B_1 &= P_1\ \small \ldots 0 \leq t \leq 1 \end{align*} \right. $$
2点間を結ぶ直線
まず、2点P0, P1 を結ぶ直線を考える。
2次ベジエ曲線
3点P0, P1, P2 を通るベジエ曲線が左図である。個の3点を制御点と呼び、始点と終点を含み、軌跡は途中の点に引っ張られるが、通過はしない。
制御点が3つあるものを2次ベジエ曲線と呼ぶ。
3次ベジエ曲線
制御点が4つになったものが、左図の3次ベジエ曲線となる。
SVGやcanvas、Adobe Flash Player 11.0以降では3次ベジエ曲線まで描くことができる。

準備:制御点

BezierCurve.php

  58: // 各種定数(START) ===========================================================
  59: 
  60: // 表示幅(ピクセル)
  61: define('WIDTH', 600);
  62: // 表示高(ピクセル)
  63: define('HEIGHT', 400);
  64: // マージン(ピクセル)
  65: define('MARGIN', 20);
  66: 
  67: // 制御点
  68: $p = array(
  69: array(MARGIN, MARGIN),                      // 制御点(0始点
  70: array(MARGIN, HEIGHT - MARGIN),             // 制御点(1)
  71: array(WIDTH - MARGIN, MARGIN),              // 制御点(2)
  72: array(WIDTH - MARGIN, HEIGHT - MARGIN),     // 制御点(3終点
  73: );
  74: 
  75: // 各種定数(END) ===============================================================

配列変数 $p に制御点の座標(X, Y)を用意する。
ここでは、制御点が4つある3次ベジエ曲線を描くが、制御点の座標及び数(次数)は任意に設定可能である。

解説:ベジエ曲線の座標計算

BezierCurve.php

 155: /**
 156:  * ベジエ曲線の座標計算
 157:  * @param   array  $p[$n][0] 制御点のX座標
 158:  *                       [1] 制御点のY座標
 159:  *                   $n = 0 は始点
 160:  * @param   float  $t 0.0≦$t≦1.0
 161:  * @return  array(X, Y)
 162: */
 163: function BezierCurve($p, $t) {
 164:     $len = count($p);
 165:     if ($len == 1)  return $p[0];
 166: 
 167:     $left  = BezierCurve(array_slice($p, 0, $len - 1), $t);
 168:     $right = BezierCurve(array_slice($p, 1, $len), $t);
 169: 
 170:     return array((int)((1 - $t* $left[0+ $t * $right[0]), (int)((1 - $t* $left[1+ $t * $right[1]));
 171: }

これを再帰手続きで実装したのが、ユーザー関数 BezierCurve である。
呼び出す側で、引数 $t を0.0から1.0の間で変化させることで、対応する座標(X, Y)を配列として戻す。

解説:ベジエ曲線を描く

BezierCurve.php

 173: /**
 174:  * ベジエ曲線を描く
 175:  * @param   array  $p[$n][0] 制御点のX座標
 176:  *                       [1] 制御点のY座標
 177:  *                   $n = 0 は始点
 178:  * @param   obj   $image イメージストリーム
 179:  * @param   int   $color 色ID(描画色)
 180:  * @param   int   $thick 太さ(省略時=1)
 181:  * @return  array(X, Y)
 182: */
 183: function drawBezierCurve($p, $image, $color, $thick=1) {
 184:     $n = count($p- 1;
 185: 
 186:     // 始点
 187:     list($x1, $y1) = array($p[0][0], $p[0][1]);
 188: 
 189:     // ベジエ曲線
 190:     for ($t = 0$t <1$t +0.01) {
 191:         list($x2, $y2) = BezierCurve($p, $t);
 192:         imagesetthickness($image, $thick);
 193:         $res = imageline($image, $x1, $y1, $x2, $y2, $color);
 194:         if ($res == FALSE)  return FALSE;
 195:         list($x1, $y1) = array($x2, $y2);
 196:     }
 197: 
 198:     // 終点
 199:     list($x2, $y2) = array($p[$n][0], $p[$n][1]);
 200:     imagesetthickness($image, $thick);
 201:     $res = imageline($image, $x1, $y1, $x2, $y2, $color);
 202: 
 203:     return $res;
 204: }

ユーザー関数 drawBezierCurve は、前述の BezierCurve を呼び出し、ベジエ曲線を描く。

参考サイト

(この項おわり)
header