您可以使用面向对象的编程来实现一些复杂的东西,但为了简单起见,我建议将所有不同类型的坐标存储为结构,这些结构都有一个成员type
以及该特定类型坐标所需的任何其他成员。
然后,您可以定义所有转换函数,这些函数只需一步即可具有相同的函数签名function out_coord = A2B(in_coord)
,例如:
function cart = sphere2cart(sphere)
assert(strcmp(sphere.type, 'sphere')) % make sure input is correct type
cart.type = 'cart';
cart.x = sphere.R * sin(sphere.theta) * cos(sphere.omega);
cart.y = sphere.R * sin(sphere.theta) * sin(sphere.omega);
cart.z = sphere.R * cos(sphere.theta);
这些函数可以从一个通用convert
函数中调用,如下所示:
function output_coord = convert(input_coord, target_type)
output_coord = input_coord;
while ~strcmp(output_coord.type, target_type)
func = get_next_conversion_func(input_coord.type, target_type);
output_coord = func(output_coord);
end
它一次执行一个转换步骤,直到output_coord
具有正确的类型。唯一缺少的步骤是一个函数,该函数根据当前类型和目标类型确定下一步要进行的转换。在您使用“线性”转换链的情况下,这并不难。在更复杂的情况下,类型在复杂图中连接,这可能需要一些最短路径算法。不幸的是,这在 Matlab 中实现起来有点麻烦,但是一个硬编码的解决方案可能是这样的:
function func = get_next_conversion_func(current_type. target_type);
switch current_type
case 'A'
func = @A2B;
case 'B'
switch target_type
case 'A'
func = @B2A;
case {'C','D','E'}
func = @B2C;
end
case 'C'
switch target_type
case {'A','B'}
func = @C2B;
case {'D','E'}
func = @C2D;
end
...
end
当然,有更聪明的方法来实现这一点,这基本上是一个调度表,它根据当前类型和目标类型说明前进的方向。
编辑
按照 Jonas 的建议,通过一种中心类型(比如说C
)进行所有转换,所有这些都可以简化为
function output_coord = convert(input_coord, target_type)
output_coord = input_coord;
if strcmp(output_coord.type, target_type)
return % nothing to convert
end
if ~strcmp(output_coord.type, 'C')
switch output_coord.type
case 'A'
output_coord = A2C(output_coord)
case 'B'
output_coord = B2C(output_coord)
case 'D'
output_coord = D2C(output_coord)
case 'E'
output_coord = E2C(output_coord)
end
end
assert(strcmp(output_coord.type, 'C'))
if ~strcmp(output_coord.type, target_type)
switch target_type
case 'A'
output_coord = C2A(output_coord)
case 'B'
output_coord = C2B(output_coord)
case 'D'
output_coord = C2D(output_coord)
case 'E'
output_coord = C2E(output_coord)
end
end