Hi Dr. Treeby,
In the original makeCartCircle and makeCircle functions, the argument arc_angle should be a scalar, which means the start point of the arc angle is fixed to be 0 radians. So to allow users to specify the start point and end point of the arc angle, I modified makeCartCircle and makeCircle so that arc_angle can be in form of [angle0, angle1], where angle0 and angle1 are the start and end of the arc angle, respectively. It requires 0<=angle0<angle1<=2*pi. Here are the modified codes:
function circle = makeCartCircle(radius, num_points, center_pos, arc_angle, plot_circle)
%MAKECARTCIRCLE Create a 2D Cartesian circle or arc.
%
% DESCRIPTION:
% MakeCartCircle creates a 2 x num_points array of the Cartesian
% coordinates of points evenly distributed over a circle or arc (if
% arc_angle is given).
%
% USAGE:
% circle = makeCartCircle(radius, num_points)
% circle = makeCartCircle(radius, num_points, center_pos)
% circle = makeCartCircle(radius, num_points, center_pos, arc_angle)
% circle = makeCartCircle(radius, num_points, center_pos, arc_angle, plot_circle)
%
% INPUTS:
% radius - circle radius [m]
% num_points - number of points in the circle
%
% OPTIONAL INPUTS:
% center_pos - [x, y] position of the circle center [m]
% (default = [0, 0])
% arc_angle - arc angle for incomplete circle [radians]
% (default = 2*pi)
% plot_circle - Boolean controlling whether the Cartesian points
% are plotted (default = false)
%
% OUTPUTS:
% circle - 2 x num_points array of Cartesian coordinates
%
% ABOUT:
% author - Bradley Treeby
% date - 5th June 2009
% last update - 21st September 2012
%
% This function is part of the k-Wave Toolbox (http://www.k-wave.org)
% Copyright (C) 2009-2012 Bradley Treeby and Ben Cox
%
% See also cart2grid, makeCartSphere, makeCircle
% This file is part of k-Wave. k-Wave is free software: you can
% redistribute it and/or modify it under the terms of the GNU Lesser
% General Public License as published by the Free Software Foundation,
% either version 3 of the License, or (at your option) any later version.
%
% k-Wave is distributed in the hope that it will be useful, but WITHOUT ANY
% WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
% FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
% more details.
%
% You should have received a copy of the GNU Lesser General Public License
% along with k-Wave. If not, see <http://www.gnu.org/licenses/>.
% check for plot_circle input
if nargin < 5
plot_circle = false;
end
% check for arc_angle input
if nargin < 4
angle0 = 0;
angle_range = 2*pi;
full_circle = true;
elseif numel(arc_angle) == 1
angle0 = 0;
angle_range = arc_angle;
if arc_angle == 2*pi;
full_circle = true;
else
full_circle = false;
end
else
angle0 = arc_angle(1);
angle_range = arc_angle(2) - arc_angle(1);
if arc_angle(1) == 0 && arc_angle(1) == 2*pi
full_circle = true;
else
full_circle = false;
end
end
% check for center_pos input
if nargin < 3 || isempty(center_pos)
cx = 0;
cy = 0;
else
cx = center_pos(1);
cy = center_pos(2);
end
% ensure there is only a total of num_points including the endpoints when
% arc_angle is not equal to 2*pi
if ~full_circle
num_points = num_points - 1;
end
% create angles
angles = (0:(num_points))*angle_range/(num_points) + angle0 + pi/2;
% discard repeated final point if arc_angle is equal to 2*pi
if full_circle
angles = angles(1:end-1);
end
% create cartesian grid
% circle = flipud([radius*cos(angles); radius*sin(-angles)]); % B.0.3
circle = ([radius*cos(angles); radius*sin(-angles)]); % B.0.4
% offset if needed
circle(1, :) = circle(1, :) + cx;
circle(2, :) = circle(2, :) + cy;
% plot results
if plot_circle
% select suitable axis scaling factor
[x_sc, scale, prefix] = scaleSI(max(abs(circle(:))));
% create the figure
figure;
plot(circle(2,:)*scale, circle(1,:)*scale, 'b.');
set(gca, 'YDir', 'reverse');
xlabel(['y-position [' prefix 'm]']);
ylabel(['x-position [' prefix 'm]']);
axis equal;
end
function circle = makeCircle(Nx, Ny, cx, cy, radius, arc_angle, plot_circle)
%MAKECIRCLE Create a binary map of a circle within a 2D grid.
%
% DESCRIPTION:
% makeCircle creates a binary map of a circle or arc (using the
% midpoint circle algorithm) within a two-dimensional grid (the
% circle position is denoted by 1's in the matrix with 0's
% elsewhere). A single grid point is taken as the circle centre thus
% the total diameter will always be an odd number of grid points.
%
% USAGE:
% circle = makeCircle(Nx, Ny, cx, cy, radius)
% circle = makeCircle(Nx, Ny, cx, cy, radius, arc_angle)
% circle = makeCircle(Nx, Ny, cx, cy, radius, arc_angle, plot_circle)
%
% INPUTS:
% Nx, Ny - size of the 2D grid [grid points]
% cx, cy - centre of the circle [grid points], if set
% to 0, the centre of the grid is used
% radius - circle radius [grid points]
%
% OPTIONAL INPUTS:
% arc_angle - arc angle for incomplete circle [radians]
% (default = 2*pi)
% plot_circle - Boolean controlling whether the circle is plotted
% using imagesc (default = false)
%
% OUTPUTS:
% circle - 2D binary map of a circle
%
% ABOUT:
% author - Bradley Treeby
% date - 1st May 2009
% last update - 20th December 2011
%
% This function is part of the k-Wave Toolbox (http://www.k-wave.org)
% Copyright (C) 2009-2012 Bradley Treeby and Ben Cox
%
% See also makeCartCircle, makeDisc
% This file is part of k-Wave. k-Wave is free software: you can
% redistribute it and/or modify it under the terms of the GNU Lesser
% General Public License as published by the Free Software Foundation,
% either version 3 of the License, or (at your option) any later version.
%
% k-Wave is distributed in the hope that it will be useful, but WITHOUT ANY
% WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
% FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
% more details.
%
% You should have received a copy of the GNU Lesser General Public License
% along with k-Wave. If not, see <http://www.gnu.org/licenses/>.
% check for plot_circle input
if nargin < 7
plot_circle = false;
end
% check for arc_angle input
if nargin < 6
angle0 = 0;
angle1 = 2*pi;
elseif numel(arc_angle) == 1
angle0 = 0;
angle1 = arc_angle;
if angle1 > 2*pi
angle1 = 2*pi;
elseif angle1 < 0
angle1 = 0;
end
else
angle0 = arc_angle(1);
angle1 = arc_angle(2);
end
% force integer values
Nx = round(Nx);
Ny = round(Ny);
cx = round(cx);
cy = round(cy);
radius = round(radius);
% check for zero values
if cx == 0
cx = floor(Nx/2) + 1;
end
if cy == 0
cy = floor(Ny/2) + 1;
end
% check the inputs
if cx < 1 || cx > Nx || cy < 1 || cy > Ny
error('The center of the circle must be within the grid');
end
% define literals
MAGNITUDE = 1;
% create empty matrix
circle = zeros(Nx, Ny);
% initialise loop variables
x = 0;
y = radius;
d = 1 - radius;
% draw the first cardinal point
try
circle(cx, cy - y) = MAGNITUDE;
catch
error('The circle must fit within the grid');
end
% draw the remaining cardinal points
py = [cx, cx+y, cx-y];
px = [cy+y, cy, cy];
for point_index = 1:length(py)
% check whether the point is within the arc made by arc_angle
if (atan2(py(point_index) - cx, px(point_index) - cy) + pi) >= angle0 && (atan2(py(point_index) - cx, px(point_index) - cy) + pi) <= angle1
circle(py(point_index), px(point_index)) = MAGNITUDE;
end
end
% loop through the remaining points using the midpoint circle algorithm
while ( x < y - 1 )
x = x + 1;
if ( d < 0 )
d = d + x + x + 1;
else
y = y - 1;
a = x - y + 1;
d = d + a + a;
end
% setup point indices
py = [x+cx, y+cx, y+cx, x+cx, -x+cx, -y+cx, -y+cx, -x+cx];
px = [y+cy, x+cy, -x+cy, -y+cy, -y+cy, -x+cy, x+cy, y+cy];
% loop through each point
for point_index = 1:length(py)
% check whether the point is within the arc made by arc_angle
if (atan2(py(point_index) - cx, px(point_index) - cy) + pi) >= angle0 && (atan2(py(point_index) - cx, px(point_index) - cy) + pi) <= angle1
circle(py(point_index), px(point_index)) = MAGNITUDE;
end
end
end
% create the figure
if plot_circle
figure;
imagesc(circle, [-1 1]);
colormap(getColorMap);
axis image;
xlabel('y-position [grid points]');
ylabel('x-position [grid points]');
end
Hope they could be useful.
Chao