function tcp = scale_torso_xy(scp, tcp, factors, scaling_options, baby_measured_mass, baby_volume, selIdx, file_pointers, format_options)
% scales the torso in the xy direction.
%
% :param scp:                      Source control points
% :param tcp:                      Current target control points
% :param factors:                  Scaling factors
% :param scaling_options:          Settings for the scaling
% :param baby_measured_mass:       Measured baby mass
% :param baby_volume:              Volume of unmorphed surface-bounded volume
% :param selIdx:                   CP indices associated with the torso
% :param file_pointers:            File pointers for I/O operations
% :param format_options:           Misc formating options
%
% :return tcp:                     Updated tcp positions
%
% Created by : ABR august@lightness.eu
% Date : 2024-06-13

centre_of_body = mean(tcp);
vectors_to_centre_of_body = tcp(selIdx,:) - centre_of_body;

 % 1b. Shrink the torso in the x and y direction
if scaling_options.scale_torso_in_plane_method == 1
    % Isotropic
    tcp(selIdx,1:2) = centre_of_body(1:2) + factors(3) .* vectors_to_centre_of_body(:,1:2);

elseif scaling_options.scale_torso_in_plane_method == 2
    % y-scaling only
    tcp(selIdx,2) = centre_of_body(2) + factors(3) .* vectors_to_centre_of_body(:,2);

elseif scaling_options.scale_torso_in_plane_method == 3
    % Scaling by "matching mass"

    mfac = baby_measured_mass ./ (1000.0 * baby_volume *1e-9 * 1000.0);
    yfac = factors(3); % Shoulder width scaling
    zfac = factors(2); % Shoulder to groin scaling

    torso_x_scaling = mfac / ( yfac * zfac);

    tcp(selIdx,1) = centre_of_body(1) + torso_x_scaling .* vectors_to_centre_of_body(:,1);
    tcp(selIdx,2) = centre_of_body(2) + factors(3) .* vectors_to_centre_of_body(:,2);
else
    disp(['scaling_options.scale_torso_in_plane_method = ' num2str(scaling_options.scale_torso_in_plane_method) ' is not supported.'])
end

if format_options.plot_flag
  figure()
  scatter(scp(:,1), scp(:,2))
  hold on
  axis equal
  scatter(tcp(:,1), tcp(:,2))
  scatter( 0 , 0 , 'sr', 'filled')
  xlabel('X'); ylabel('Y');
  print([file_pointers.plot_dir 'XY_scale2'], format_options.pngprintOptions{:})

  figure()
  scatter(scp(:,1), scp(:,3))
  hold on
  axis equal
  scatter(tcp(:,1), tcp(:,3))
  xlabel('X'); ylabel('Z');
  scatter( 0 , 0 , 'sr', 'filled')
  print([file_pointers.plot_dir 'XZ_scale2'], format_options.pngprintOptions{:})

  figure()
  scatter(scp(:,2), scp(:,3))
  hold on
  axis equal
  scatter(tcp(:,2), tcp(:,3))
  scatter( 0 , 0 , 'sr', 'filled')
  xlabel('Y'); ylabel('Z');
  print([file_pointers.plot_dir 'YZ_scale2'], format_options.pngprintOptions{:})
end
