Circle with Alternating coloured segments

조회 수: 2(최근 30일)
David
David 2022년 12월 5일
편집: DGM 2022년 12월 6일
I wanted to reverse engineer this colour wheel code so that I can specify what colour each segment has: segment 1 - green, segment 2-13, red and segment 14-26, black (like a roulette wheel). I'm a little stuck on how to approach this (I've experimented with a simpler code to see if I could use cartesian only but can't see a way to merge them):
% Set parameters (these could be arguments to a function)
rInner = 80; % inner radius of the colour ring
rOuter = 200; % outer radius of the colour ring
ncols = 27; % number of colour segments
% Get polar coordinates of each point in the domain
[x, y] = meshgrid(-rOuter:rOuter);
[theta, rho] = cart2pol(x, y);
% Set up colour wheel in hsv space
hue = (theta + pi) / (2 * pi); % hue into range (0, 1]
hue = ceil(hue * ncols) / ncols; % quantise hue
saturation = ones(size(hue)); % full saturation
brightness = double(rho >= rInner & rho <= rOuter); % black outside ring
% Convert to rgb space for display
rgb = hsv2rgb(cat(3, hue, saturation, brightness));
% Check result
imshow(rgb);
My experiment code:
figure
N = 37;
a = linspace(0, 2*pi, N*10);
r = 1;
x = r*cos(a);
y = r*sin(a);
plot(x, y)
hold on
plot([zeros(1,N); x(1:10:end)], [zeros(1,N); y(1:10:end)])
axis equal
axis off
Additionally I was wondering what tweaks I would need to make so that I can perform a matrix transformation to it (For a rotation animation):
function rShape = rotateShape(shape, a)
%Rotates shape by angle a
%Matrix operation to rotate shape
rShape = [cos(a) -sin(a); sin(a) cos(a)] * shape;
end

채택된 답변

DGM
DGM 2022년 12월 6일
Here's one example. I'm sure this can be simplified. It's flexible enough that you can adapt it for different standard wheel configurations.
% Set parameters (these could be arguments to a function)
rInner = 150; % inner radius of the colour ring
rOuter = 200; % outer radius of the colour ring
% this is the clockwise sequence for a european pattern single-green wheel
slotnums = [0 32 15 19 4 21 2 25 17 34 6 27 13 36 11 30 8 23 10 5 24 16 33 1 20 14 31 9 22 18 29 7 28 12 35 3 26];
slotidx = [1 3 2 3 2 3 2 3 2 3 2 3 2 3 2 3 2 3 2 3 2 3 2 3 2 3 2 3 2 3 2 3 2 3 2 3 2];
CT = [0 0.5 0; 0.1 0.1 0.1; 0.5 0 0]; % make up some colors
nslots = numel(slotnums); % number of colour segments
offset = 45; % specify angle offset (degrees)
% Get polar coordinates of each point in the domain
[x, y] = meshgrid(-rOuter:rOuter);
[theta, rho] = cart2pol(x, y);
% generate segments
outpict = mod(rad2deg(theta)+offset,360)/360; % normalize
outpict = ceil(outpict * nslots); % quantise
outpict = ind2rgb(outpict,CT(slotidx,:));
% mask off annular region
mk = double(rho >= rInner & rho <= rOuter);
outpict(repmat(~mk,[1 1 3])) = 0;
% show result
imshow(outpict); hold on
% add numbers
textrad = rInner + 0.65*(rOuter-rInner); % or pick some radius
th0 = 360/nslots;
th = linspace(0,360-th0,nslots) - offset + th0/2;
cen = size(outpict(:,:,1))/2;
for k = 1:numel(th)
x = textrad*cosd(th(k)) + cen(2);
y = textrad*sind(th(k)) + cen(1);
ht = text(x,y,sprintf('%d',slotnums(k)));
ht.Color = [1 1 1];
ht.FontSize = 10;
ht.FontWeight = 'bold';
ht.HorizontalAlignment = 'center';
ht.Rotation = 270-th(k);
end
  댓글 수: 8
DGM
DGM 2022년 12월 6일
편집: DGM 2022년 12월 6일
I'm not sure exactly how the text 'fontsize' relates to axes units, but otherwise if you want to be able to adjust the zoom level, you might do that by manipulating xlim and ylim. If xlim and ylim are equal to the limits given in the call to imagesc(), then the image will always fill the axes regardless of its scale.
If you don't necessarily want to adjust the zoom, but just want more padding around the wheel, then you can just make the image bigger to start with.
% ...
maxr = 300; % the maximum image radius (independent of the wheel)
% ...
[x, y] = meshgrid(-maxr:maxr);
% ...
imagesc(-maxr:maxr, -maxr:maxr, segm);
% ...

댓글을 달려면 로그인하십시오.

추가 답변(0개)

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by