mixC++ 技術開発者の日記
C言語交流フォーラム ~ mixC++ ~ の技術管理者を務めている、御津凪(みつなぎ)の日誌。
自分のHPは既に持っているので、ここの内容は mixC++ 中心の日誌です。
こっちの作業に注力して中々自HPに手をつけれていないものの、訪れてくれると嬉しいです。
HP : http://mitsunagistudio.net/

スプライン曲線をなぞるクラスの公開

アバター
御津凪
管理人
記事: 200
登録日時: 15年前
住所: 道内
連絡を取る:

スプライン曲線をなぞるクラスの公開

投稿記事 by 御津凪 » 14年前

仕事で組み込むことになったスプライン曲線のプログラムを使いやすい形にして公開してみることにしました。
※1 仕事で使っているコードではありません。
※2 曲線を計算する部分はWebから取って来たものです。

サンプルアプリも用意しましたが、クラスにしたコードだけここに貼り付けておきます。

CODE:

#ifndef SPLINE_H
#define SPLINE_H

/*!
 * @brief	2次元座標用3次スプライン関数の計算用クラス
 *
 * @sec	使い方	
 *			1.コンストラクタで座標と個数をセット、もしくは SetPos() と SetCount() で座標と個数をセットする
 *			2.Setup() 関数を使用して移動速度を元に時間を設定する
 *			3.GetNowInfo() 関数で現在の座標と向きを取得する
 *			4.Step() 関数で次の位置へ移動する
 *			5. 3.と4.を繰り返し、 Step() 関数が false を返したら終端
 *			6.Reset() 関数で最初の位置へ戻る
 */
template
class Spline2D
{
	float h[MAX];
	float b[MAX];
	float d[MAX];
	float g[MAX];
	float u[MAX];
	float r[MAX+1];

	float t[MAX+1];
	float x[MAX+1];
	float y[MAX+1];

	unsigned int	count;
	unsigned int	step;
	float			unit;

	float xp, yp;
	float xn, yn;
	float dir;

	void spline( unsigned int st, float& x, float& y )
	{
		float tm = st * unit;
		x = spline(count, t, this->x, tm);
		y = spline(count, t, this->y, tm);
	}

	float spline( int n, const float* x, const float* y, float x1 )
	{
		int i = -1, j, k;
		float fRes, fQ, fS, fX;

		for (j = 1;j  1) ? i : 1;
		r[0]   = 0.0f;
		r[n]   = 0.0f;
		r[n-1] = u[n-1];
		for (j = n-2;j >= k;--j)
		{
			r[j] = u[j] - g[j] * r[j+1];
		}
		fX = x1 - x[i];
		fQ = (y[i+1] - y[i]) / h[i] - h[i] * (r[i+1] + 2.0f * r[i]) / 3.0f;
		fS = (r[i+1] - r[i]) / (3.0f * h[i]);
		fRes = y[i] + fX * (fQ + fX * (r[i] + fS * fX));

		return fRes;
	}
public:
	Spline2D( const float* (&pos)[2], unsigned int n ) : count(n), step(0)
	{
		if (count > MAX) { count = MAX - 1; }
	}
	Spline2D( unsigned int n ) : count(n), step(0)
	{
		if (count > MAX) { count = MAX - 1; }
	}
	Spline2D( void ) : count(MAX), step(0)
	{
	}

	unsigned int GetCount( void )const{ return count; }
	float GetPosX( unsigned int i )const{ return x[i]; }
	float GetPosY( unsigned int i )const{ return y[i]; }
	float GetPosT( unsigned int i )const{ return t[i]; }

	void SetPos( unsigned int i, float x, float y ) { this->x[i] = x; this->y[i] = y; }
	void SetCount( unsigned int n )
	{
		if (count > MAX) { count = MAX - 1; }
	}

	void Setup( float scale, float unit )
	{
		float tm = 0.0f;
		t[0] = 0.0f;

		for (unsigned int i = 1;i unit = unit;
		Reset();
	}

	void Reset()
	{
		spline(0, xp, yp);
		spline(1, xn, yn);
		step = 1;

		dir = atan2f(yn - yp, xn - xp);
	}

	bool Step()
	{
		float tm = (step + 1) * unit;

		xp = xn;
		yp = yn;
		if (tm dir;
	}
};

#endif // SPLINE_H
これを弄って更に使いやすくするもよし、3次元用に拡張するもよし。
自由に使っちゃってください。もちろん自己責任で。

サンプルアプリを含んだソースコードは添付しておきますね。(アプリは Windows 専用です)
添付ファイル

[拡張子 zip は無効化されているため、表示できません]


アバター
しょこらふれっくす
記事: 66
登録日時: 15年前

Re: スプライン曲線をなぞるクラスの公開

投稿記事 by しょこらふれっくす » 14年前

頂きました><
いじいじして遊びます!!

アバター
みけCAT
記事: 6734
登録日時: 14年前

Re: スプライン曲線をなぞるクラスの公開

投稿記事 by みけCAT » 14年前

3次元のスプライン曲線って、2次元と同じように2点の間をとっていけばおkなのかな?

アバター
御津凪
管理人
記事: 200
登録日時: 15年前
住所: 道内
連絡を取る:

Re: スプライン曲線をなぞるクラスの公開

投稿記事 by 御津凪 » 14年前

みけCAT さんが書きました:3次元のスプライン曲線って、2次元と同じように2点の間をとっていけばおkなのかな?
一応多次元用に拡張できるように軸ごとに計算できるように分離しているので、z軸を含めるようにするだけで可能ですよ。