/* curve.h */
/* Programed by AZO */
/* This code is free. Use at Your Own Risk. */

#ifndef _CURVE_H_
#define _CURVE_H_

#include <math.h>

typedef struct pos2d {
	double x;
	double y;
} pos2d_t;

typedef struct pos3d {
	double x;
	double y;
	double z;
} pos3d_t;

typedef struct ellipse2d {
	pos2d_t center;
	double radius1;
	double radius2;
} ellipse2d_t;

/* 0.0 <= i_dT <= i_uiControlCount - 1 */
extern void bspline2(pos2d_t* o_ptPos, const unsigned int i_uiControlCount, const pos2d_t* i_ltControls, const double i_dT);
/* 0.0 <= i_dT <= i_uiControlCount - 1 */
extern void bspline3(pos2d_t* o_ptPos, const unsigned int i_uiControlCount, const pos2d_t* i_ltControls, const double i_dT);
/* 0.0 <= i_dRatio <= 1.0 */
extern void quadratic_bezier(pos2d_t* o_ptPos, const pos2d_t* i_ptFrom, const pos2d_t* i_ptControl, const pos2d_t* i_ptTo, const double i_dRatio);
/* 0.0 <= i_dRatio <= 1.0 */
extern void cubic_bezier(pos2d_t* o_ptPos, const pos2d_t* i_ptFrom, const pos2d_t* i_ptControl1, const pos2d_t* i_ptControl2, const pos2d_t* i_ptTo, const double i_dRatio);
/* i_dRotate & i_dAngle : radian */
extern void ellipse(pos2d_t* o_ptPos, const ellipse2d_t* i_ptEllipse, const double i_dRotate, const double i_dAngle);
/* i_dRotate & idAngle & i_dShearAngle : radian / -M_PI/2 < i_dShearAngle < M_PI/2 */
extern void sheared_ellipse(pos2d_t* o_ptPos, const ellipse2d_t* i_ptEllipse, const double i_dRotate, const double i_dShearAngle, const double i_dAngle);
/* i_dRotate & idAngle & i_dShearAngle : radian / -M_PI/2 < i_dShearAngle < M_PI/2 */
extern void sheared_ellipse_convert(ellipse2d_t* o_ptEllipse, double* o_pdRotate, const ellipse2d_t* i_ptEllipse, const double i_dRotate, const double i_dShearAngle);
/* i_dAngle : radian */
extern void involute(pos2d_t* o_ptPos, const pos2d_t* i_ptCenter, const double i_dRadius, const double i_dAndle);
/* i_dAngle : radian / i_dRadius = i_dLength -> cycroid */
void trochoid(pos2d_t* o_ptPos, const double i_dRadius, const double i_dLength, const double i_dAndle);
/* i_dAngle : radian / i_dDynRadius = i_dLength -> epicycroid */
void epitrochoid(pos2d_t* o_ptPos, const double i_dConstRadius, const double i_dDynRadius, const double i_dLength, const double i_dAndle);
/* i_dAngle : radian / i_dDynRadius = i_dLength -> hypocycroid */
void hypotrochoid(pos2d_t* o_ptPos, const double i_dConstRadius, const double i_dDynRadius, const double i_dLength, const double i_dAndle);

/* 0.0 <= i_dT <= i_uiControlCount - 1 */
extern void bspline2_3d(pos3d_t* o_ptPos, const unsigned int i_uiControlCount, const pos3d_t* i_ltControls, const double i_dT);
/* 0.0 <= i_dT <= i_uiControlCount - 1 */
extern void bspline3_3d(pos3d_t* o_ptPos, const unsigned int i_uiControlCount, const pos3d_t* i_ltControls, const double i_dT);
/* 0.0 <= i_dRatio <= 1.0 */
extern void quadratic_bezier_3d(pos3d_t* o_ptPos, const pos3d_t* i_ptFrom, const pos3d_t* i_ptControl, const pos3d_t* i_ptTo, const double i_dRatio);
/* 0.0 <= i_dRatio <= 1.0 */
extern void cubic_bezier_3d(pos3d_t* o_ptPos, const pos3d_t* i_ptFrom, const pos3d_t* i_ptControl1, const pos3d_t* i_ptControl2, const pos3d_t* i_ptTo, const double i_dRatio);

#endif	/* _CURVE_H_ */

