<commit_before>﻿
#ifndef	__EFFEKSEER_CURVE_H__
#define	__EFFEKSEER_CURVE_H__

//----------------------------------------------------------------------------------
// Include
//----------------------------------------------------------------------------------
#include "Effekseer.Base.h"
#include "Effekseer.Manager.h"
#include "Effekseer.Vector3D.h"

#include <vector>
#include <cmath>

namespace Effekseer
{


class dVector4
{
public:
	double X, Y, Z, W;

public:
	dVector4(double x = 0, double y = 0, double z = 0, double w = 0) :
		X(x), Y(y), Z(z), W(w)
	{
	}
};

/**
@brief
\~English	Curve class
\~Japanese	カーブクラス
*/
class Curve
{
	friend class CurveLoader;
public:
	static const int32_t Version = 1;

private:
	int mControllPointCount;
	std::vector<dVector4> mControllPoint;

	int mKnotCount;
	std::vector<double> mKnotValue;

	int mOrder;
	int mStep;
	int mType;
	int mDimension;

	float mLength;

private:
	/**
	 * CalcBSplineBasisFunc : B-スプライン基底関数の計算
	 * 
	 * const vector<double>& knot : ノット列
	 * unsigned int j : ノット列の開始番号
	 * unsigned int p : 次数
	 * double t : 計算対象の独立変数
	 * 
	 * ノット列は昇順である必要があるが、そのチェックは行わない
	 * 
	 * 戻り値 : 計算結果
	 */
	double CalcBSplineBasisFunc(const std::vector<double>& knot, unsigned int j, unsigned int p, double t)
	{
		if (knot.size() == 0) return  std::nan("");

		// ノット列のデータ長が充分でない場合は nan を返す
		unsigned int m = static_cast<unsigned int>(knot.size()) - 1;
		if (m < j + p + 1) return  std::nan("");

		// 正値をとる範囲外ならゼロを返す
		if ((t < knot[j]) || (t > knot[j + p + 1])) return(0);
		// p = 0 かつ knot[j] <= t <= knot[j + p + 1] なら 1 を返す
		if (p == 0) return(1);
		// p = 1 の場合、三角の頂点の値は特別扱い
		if (p == 1 && t == knot[j + 1]) return(1);

		// 漸化式の計算
		double d1 = (knot[j + p] == knot[j]) ? 0 :
			(t - knot[j]) * CalcBSplineBasisFunc(knot, j, p - 1, t) / (knot[j + p] - knot[j]);
		double d2 = (knot[j + p + 1] == knot[j + 1]) ? 0 :
			(knot[j + p + 1] - t) * CalcBSplineBasisFunc(knot, j + 1, p - 1, t) / (knot[j + p + 1] - knot[j + 1]);

		return (d1 + d2);
	}

public:
	Curve()
	{
	}
<commit_msg>fix nan<commit_after>﻿
#ifndef	__EFFEKSEER_CURVE_H__
#define	__EFFEKSEER_CURVE_H__

//----------------------------------------------------------------------------------
// Include
//----------------------------------------------------------------------------------
#include "Effekseer.Base.h"
#include "Effekseer.Manager.h"
#include "Effekseer.Vector3D.h"

#include <vector>
#include <limits>
#include <cmath>

namespace Effekseer
{


class dVector4
{
public:
	double X, Y, Z, W;

public:
	dVector4(double x = 0, double y = 0, double z = 0, double w = 0) :
		X(x), Y(y), Z(z), W(w)
	{
	}
};

/**
@brief
\~English	Curve class
\~Japanese	カーブクラス
*/
class Curve
{
	friend class CurveLoader;
public:
	static const int32_t Version = 1;

private:
	int mControllPointCount;
	std::vector<dVector4> mControllPoint;

	int mKnotCount;
	std::vector<double> mKnotValue;

	int mOrder;
	int mStep;
	int mType;
	int mDimension;

	float mLength;

private:
	/**
	 * CalcBSplineBasisFunc : B-スプライン基底関数の計算
	 * 
	 * const vector<double>& knot : ノット列
	 * unsigned int j : ノット列の開始番号
	 * unsigned int p : 次数
	 * double t : 計算対象の独立変数
	 * 
	 * ノット列は昇順である必要があるが、そのチェックは行わない
	 * 
	 * 戻り値 : 計算結果
	 */
	double CalcBSplineBasisFunc(const std::vector<double>& knot, unsigned int j, unsigned int p, double t)
	{
		if (knot.size() == 0) return std::numeric_limits<double>::quiet_NaN();

		// ノット列のデータ長が充分でない場合は nan を返す
		unsigned int m = static_cast<unsigned int>(knot.size()) - 1;
		if (m < j + p + 1) return std::numeric_limits<double>::quiet_NaN();

		// 正値をとる範囲外ならゼロを返す
		if ((t < knot[j]) || (t > knot[j + p + 1])) return(0);
		// p = 0 かつ knot[j] <= t <= knot[j + p + 1] なら 1 を返す
		if (p == 0) return(1);
		// p = 1 の場合、三角の頂点の値は特別扱い
		if (p == 1 && t == knot[j + 1]) return(1);

		// 漸化式の計算
		double d1 = (knot[j + p] == knot[j]) ? 0 :
			(t - knot[j]) * CalcBSplineBasisFunc(knot, j, p - 1, t) / (knot[j + p] - knot[j]);
		double d2 = (knot[j + p + 1] == knot[j + 1]) ? 0 :
			(knot[j + p + 1] - t) * CalcBSplineBasisFunc(knot, j + 1, p - 1, t) / (knot[j + p + 1] - knot[j + 1]);

		return (d1 + d2);
	}

public:
	Curve()
	{
	}

{'fraction_non_alphanumeric': 0.2363328495403967, 'fraction_numerical': 0.018867924528301886, 'mean_word_length': 2.361788617886179, 'pattern_counts': {'":': 0, '<': 28, '<?xml version=': 0, '>': 22, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3621830', 'n_tokens_mistral': 2024, 'n_tokens_neox': 1877, 'n_words': 427}