Workaround for matrix dimension error

1 Ansicht (letzte 30 Tage)
Benedikt Schwarz
Benedikt Schwarz am 3 Sep. 2019
Bearbeitet: Benedikt Schwarz am 4 Sep. 2019
Hello guys,
I already asked a few questions about my LED-Matrix project and it is getting closer to its final state.
So when implementing my mousemode I wanted to switch between several figures which I "draw" in an array around the Mouseposition.
unction Transmit = MouseFigure(MousePos,Transmit,handles)
global click
%click = 3;
brtn = get(handles.slider1, 'Value');
switch click
case 1 %%Kreuz%%
Transmit(MousePos(1),MousePos(2)) = 255*brtn;
Transmit(MousePos(1)+1,MousePos(2)) = 255*brtn;
if MousePos(1) > 1
Transmit(MousePos(1)-1,MousePos(2)) = 255*brtn;
end
if MousePos(2) > 1
Transmit(MousePos(1),MousePos(2)-1) = 255*brtn;
end
Transmit(MousePos(1),MousePos(2)+1) = 255*brtn;
case 2 %%Rechteck 3x3 Pixel%%
for i = 1:3
if MousePos(1) < 2
i = 2;
end
Transmit(MousePos(1)-2+i,MousePos(2)+1) = 255*brtn;
Transmit(MousePos(1)-2+i,MousePos(2)) = 255*brtn;
Transmit(MousePos(1)-2+i,MousePos(2)+1) = 255*brtn;
Transmit(MousePos(1)-2+i,MousePos(2)) = 255*brtn;
if MousePos(2) > 2
Transmit(MousePos(1)-2+i,MousePos(2)-1) = 255*brtn;
end
end
case 3 %%Kreis 3,5,5,5,3%%
for i = 1:5
if MousePos(1) > 3
Transmit(MousePos(1)-3+i,MousePos(2)+1) = 255*brtn;
Transmit(MousePos(1)-3+i,MousePos(2)) = 255*brtn;
end
if MousePos(2) > 1
Transmit(MousePos(1)-3+i,MousePos(2)-1) = 255*brtn;
end
if MousePos(1) > 4
Transmit(MousePos(1)-4+i,MousePos(2)+2) = 255*brtn;
if MousePos(2) > 2
Transmit(MousePos(1)-4+i,MousePos(2)-2) = 255*brtn;
end
end
end
end
Transmit = Transmit([1:32],[1:32]);
Transmit = rot90(Transmit,1);
Transmit = reshape(Transmit,[1,1024]);
But when doing this in my method as you can see there are always those if-cases for the outer line of the drawn figure to avoid matrix dimension errors. Now my question is, is there a smarter workaround for this error or even for "drawing" those figures in my array?

Akzeptierte Antwort

Jan
Jan am 3 Sep. 2019
Bearbeitet: Jan am 3 Sep. 2019
Hints:
Avoid repeated code. Prefer:
brtn = 255 * get(handles.slider1, 'Value');
instead of writing 255*brtn whenever brtn is used. Typing "MousePos(1)" repeatedly is a source of typos also. What about:
x = MousePos(1);
y = MousePos(2);
The standard method for comments is to start with a % and a space. "%%Kreuz%%" looks fancy, but not Matlab'ish.
X(1:32) is faster than X([1:32]). The reason is not documented, but it seems like Matlab checks the limits for 1 and 32 only, while in the latter case the vector 1:32 is created explicitly and the limits are checked for each element. Remember that [] is the Matlab operator for concatenation, so there is no need to concat teh vector 1:32 with nothing else.
The actual question: Replace e.g.:
Transmit(MousePos(1),MousePos(2)) = 255*brtn;
Transmit(MousePos(1)+1,MousePos(2)) = 255*brtn;
if MousePos(1) > 1
Transmit(MousePos(1)-1,MousePos(2)) = 255*brtn;
end
if MousePos(2) > 1
Transmit(MousePos(1),MousePos(2)-1) = 255*brtn;
end
Transmit(MousePos(1),MousePos(2)+1) = 255*brtn;
by
xi = max( 1, x - 1);
xf = min(32, x + 1);
yi = max( 1, y - 1);
yf = min(32, y + 1);
Transmit(xi:xf, y) = brtn;
Transmit(x, yi:yf) = brtn;
An alternative approach:
T = zeros(40, 40);
x = MousePos(1) + 4;
y = MousePos(2) + 4;
... % Insert the values without considering the limits
Transmit = T(5:36, 5:36);
...
So you draw without considering the limits and crop out the visible area afterwards. I'd prefer this, because it is much easier to expand for other objects.
  1 Kommentar
Benedikt Schwarz
Benedikt Schwarz am 4 Sep. 2019
Bearbeitet: Benedikt Schwarz am 4 Sep. 2019
T = zeros(40, 40);
x = MousePos(1) + 4;
y = MousePos(2) + 4;
... % Insert the values without considering the limits
Transmit = T(5:36, 5:36);
...
Awesome I never thought of this approach... Thanks a lot, looks way better now!

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (0)

Community Treasure Hunt

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

Start Hunting!

Translated by