我建议使用模板部分专业化的解决方案,这样可以最大限度地减少写作。代码中没有条件,运行时也没有条件。让我们定义依赖于 X 或 Y 作为 sin 或 cos 工作的特殊函数。
为 X 和 Y 定义枚举以引用:
typedef enum { X, Y } xy_enum;
用于编译时选择的部分专用模板类:
template<xy_enum T>
struct _xcys // x cos y sin
{
static double f( double t ) { return cos(t); }
};
template<> // explicit specialization for T = Y
struct _xcys<Y> // x cos y sin
{
static double f( double t ) { return sin(t); }
};
template<xy_enum T>
struct _xsyc // x sin y cos
{
static double f( double t ) { return sin(t); }
};
template<> // explicit specialization for T = Y
struct _xsyc<Y> // x sin y cos
{
static double f( double t ) { return cos(t); }
};
定义依赖于 X 或 Y 作为 sin 或 cos 工作的函数。所以xcys() 将 X 作为 cos 和 Y 作为 sin 工作。 xsyc() 为 X 工作为 sin,为 Y 工作为 cos。
template<xy_enum T> // x sin y cos
double xcys ( double t ) { return _xcys<T>::f(t); }
template<xy_enum T> // x sin y cos
double xsyc ( double t ) { return _xsyc<T>::f(t); }
简单测试
std::cout << xcys<X>(0) << " " << xcys<Y>(0) << std::endl;
std::cout << xcys<X>(M_PI/2) << " " << xcys<Y>(M_PI/2) << std::endl;
std::cout << xsyc<X>(0) << " " << xsyc<Y>(0) << std::endl;
std::cout << xsyc<X>(M_PI/2) << " " << xsyc<Y>(M_PI/2) << std::endl;
结果输出:
1 0
~0 1
0 1
1 ~0
最后你的代码有两个这样的函数:
double calculateObstaclePosition(double robotX, double sesnorReading, double robotDegree, int angleBetweenSensors){
return robotX + sesnorReading * cos((robotDegree + i * angleBetweenSensors) * PI / 180);
}
double calculateObstaclePosition(double robotY, double sesnorReading, double robotDegree, int angleBetweenSensors){
return robotY + sesnorReading * sin((robotDegree + i * angleBetweenSensors) * PI / 180);
}
可以用一个模板函数重写:
template< xy_enum T >
double calculateObstaclePosition(double robotXY, double sesnorReading, double robotDegree, int angleBetweenSensors){
return robotXY + sesnorReading * xcys<T>((robotDegree + i * angleBetweenSensors) * PI / 180);
}
并为 x 和 y 调用单个函数两次:
obstacleX = calculateObstaclePosition<X>(robot.x, robot.sensorReadings.at(i), robot.deg, angleBetweenSensors);
obstacleY = calculateObstaclePosition<Y>(robot.y, robot.sensorReadings.at(i), robot.deg, angleBetweenSensors);