You could implement something complicated with object oriented programming, but to keep things simple I propose to store all different types of coordinates as structs that all have a member type
and whatever other members needed for that particular type of coordinate.
You could then define all your conversion functions that do a single step to all have the same function signature function out_coord = A2B(in_coord)
, e.g.:
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);
These functions can be called from one universal convert
function like this:
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
which does one conversion step at a time, until output_coord
has the correct type. The only missing step is then a function that determines which conversion to do next, based on the current type and the target type. In your case with a 'linear' conversion chain, this is not so hard. In more complex cases, where the types are connected in a complex graph, this might require some shortest path algorithm. Unfortunately, this is a bit cumbersome to implement in Matlab, but one hard-coded solution might be something like:
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
For sure, there are smarter ways to implement this, this is basically a dispatch table that says in which direction to go based on the current type and the target type.
EDIT
Following Jonas' suggestion of doing all conversions via one central type (let's say C
), all of this can be simplified to
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