Draw polygon with hole inside - octave

I need to draw a rectangle polygon with a rectangle hole inside. I found this piece of code but I couldn't manage to understand how I can modify to meet my requirement.
figure()
p = [0 0; 0 1; 1 1; 1 0]; %ccw
pp = [0 0; 1 0; 1 1; 0 1]; %cw
ph = p + [1.2 0];
# add hole
ph(end+1,:) = nan;
ph = [ph; (pp-[0.5 0.5])*0.5+[1.7 0.5]];
po = polygon2patch (ph);
patch (po(:,1), po(:,2), 'b', 'facecolor', 'c');
axis image

The polygon2patch function certainly seems useful, but maybe for only drawing two rectangles, you could also use just two patch commands, and simply set the inner rectangle, i.e. the hole, to white foreground color, like so:
outer = [0 0; 2 0; 2 1; 0 1];
inner = [0.4 0.2; 1.6 0.2; 1.6 0.8; 0.4 0.8];
patch(outer(:, 1), outer(:, 2), 'c');
patch(inner(:, 1), inner(:, 2), 'w');
axis equal;
This will produce such an output:
Hope that helps!

Related

Octave: Set matrix values according to vector [duplicate]

I'm trying to vectorize the following MATLAB operation:
Given a column vector with indexes, I want a matrix with the
same number of rows of the column and a fixed number of columns. The
matrix is initialized with zeroes and contains ones in the locations
specified by the indexes.
Here is an example of the script I've already written:
y = [1; 3; 2; 1; 3];
m = size(y, 1);
% For loop
yvec = zeros(m, 3);
for i=1:m
yvec(i, y(i)) = 1;
end
The desired result is:
yvec =
1 0 0
0 0 1
0 1 0
1 0 0
0 0 1
Is it possible to achieve the same result without the for loop? I tried something like this:
% Vectorization (?)
yvec2 = zeros(m, 3);
yvec2(:, y(:)) = 1;
but it doesn't work.
Two approaches you can use here.
Approach 1:
y = [1; 3; 2; 1; 3];
yvec = zeros(numel(y),3);
yvec(sub2ind(size(yvec),1:numel(y),y'))=1
Approach 2 (One-liner):
yvec = bsxfun(#eq, 1:3,y)
Yet another approach:
yvec = full(sparse(1:numel(y),y,1));
You could do this with accumarray:
yvec = accumarray([(1:numel(y)).' y], 1);
I did it this way:
classes_count = 10;
sample_count = 20;
y = randi([1 classes_count], 1, sample_count);
y_onehot = zeros(classes_count, size(y, 2));
idx = sub2ind(size(y_onehot), y, [1:size(y, 2)]);
y_onehot(idx) = 1

Color rectangle one by one in a canvas

I have canvas on which there are number of rectangle drawn so that the make a grid. What I want is to color each rectangle one by one in the grid until each of them are colored black and then again select few of them to color white in the same way one by one. I have tried few methods using "for" loop and "setTimeout" but its not working out.
I have recently started javascript that's why I need help to do this.
This code only includes the making of the grid no further because that part was not working out:
var canvas;
var ctx;
canvas = document.getElementById('canvas');
ctx = canvas.getContext('2d');
tileW = 20;
tileH = 20;
tileRowCount = 25;
tileColCount = 40;
var tile = [];
for (c = 0; c < tileColCount; c++) {
tile[c] = [];
for (r = 0; r < tileRowCount; r++){
tile[c][r] = {
x: c * (tileW + 3),
y: r * (tileH + 3),
state: 'e'
}; //state e for empty
}
}
for (c = 0; c < tileColCount; c++)
for (r = 0; r < tileRowCount; r++) {
ctx.beginPath();
ctx.fillStyle = '#AAAAAA';
ctx.rect(tile[c][r].x, tile[c][r].y, tileW, tileH);
ctx.closePath();
ctx.fill();
}
}
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<canvas id="canvas" width='1000' height='600'></canvas>
<script type="text/javascript" src='data.js'></script>
</body>
</html>
Update your rendering code to use the fillRect method from the 2d context.
Replace this:
ctx.beginPath();
ctx.fillStyle = '#AAAAAA';
ctx.rect(tile[c][r].x, tile[c][r].y, tileW, tileH);
ctx.closePath();
ctx.fill();
With this:
ctx.fillStyle = "#AAAAAA";
ctx.fillRect(tile[c][r].x, tile[c][r].y, tileW, tileH);
It is not clear what you want. My guess is that you want a checkerboard. The following will do so.
The Remainder operator
The operator % returns the remainder after division. eg 3 % 2 is 1 and 4 % 2 is 0
We can use the remainder operator to let us know which color to make each square. As we count down the rows the remainder of the row count and 2 will switch between 0 and 1. For each column we want the opposite. If you add the row count to the column count and get the remainder we get the desired result. Example (r + c) will give (0 + 0) % 2 == 0, (1 + 0) % 2 == 1, (2 + 0) % 2 == 0, (3 + 0) % 2 == 1, then the next column (0 + 1) % 2 == 1, (1 + 1) % 2 == 0, (2 + 1) % 2 == 1, (3 + 1) % 2 == 0. and so on.
The % operator has higher precedence than the addition operator + thus we need to put the grouping operators ( ) around the addition.
Eg 3 + 1 % 2 will equal 4. The 1 % 2 is done first then the 3 is added while (3 + 1) % 2 will equal 0. The (3 + 1) is first then the remainder is done
The Ternary operator
We can do this most simply using the ternary operator ?. eg color = (c + r) % 2 ? "white" : "black" which is the same as if ((c + r) % 2 === 1) { color = "white" } else { color = "black" }
Example
const ctx = canvas.getContext('2d');
const tileW = 20;
const tileH = 20;
const tileRowCount = 25;
const tileColCount = 40;
const tiles = [];
for (let c = 0; c < tileColCount; c++) {
for (let r = 0; r < tileRowCount; r++) {
tiles.push({
x: c * (tileW + 3),
y: r * (tileH + 3),
color: (c + r) % 2 ? "white" : "black",
});
}
}
for (const tile of tiles) {
ctx.fillStyle = tile.color;
ctx.fillRect(tile.x, tile.y, tileW, tileH);
}
<canvas id="canvas" width='1000' height='600'></canvas>

multi-sensors fusion using Kalman filter

I need to use the Kalman filter to fuse multi-sensors positions for gaussian measurement (for example 4 positions as the input of the filter and 1 position as output). It is possible to help me with some examples or tutorials because all the examples I found are related to the estimation of the positions?
OPTION 1
Weighted Avarage
In this case you don't need to implement a real Kalman Filter. You just can use the signal variances to calculate the weights and then calculate the weighted avarage of the inputs. The weights can be found as an inverse of the variances.
So if you have two signals S1 and S2 with variances V1 and V2, then the fused result would be
A fusion example can be seen on the next plot.
I simulated two signals. The variance of the second signal changes over the time. As long as it's smaller than the variance of the first signal the fused result is close to the second signal. It is not the case when the variance of the second signal is too high.
OPTION 2
Kalman Filter with Multiple Update Steps
The classical Kalman Filter uses prediction and update steps in a loop:
prediction
update
prediction
update
...
In your case you have 4 independent measurements, so you can use those readings after each other in separate update steps:
prediction
update 1
update 2
update 3
update 4
prediction
update 1
...
A very nice point is that the order of those updates does not matter! You can use updates 1,2,3,4 or 3,2,4,1. In both cases you should get the same fused output.
Compared to the first option you have following pros:
You have a variance propogation
You have the system noise matrix Q,
so you can control the smoothness of the fused output
Here is my matlab code:
function [] = main()
% time step
dt = 0.01;
t=(0:dt:2)';
n = numel(t);
%ground truth
signal = sin(t)+t;
% state matrix
X = zeros(2,1);
% covariance matrix
P = zeros(2,2);
% kalman filter output through the whole time
X_arr = zeros(n, 2);
% system noise
Q = [0.04 0;
0 1];
% transition matrix
F = [1 dt;
0 1];
% observation matrix
H = [1 0];
% variance of signal 1
s1_var = 0.08*ones(size(t));
s1 = generate_signal(signal, s1_var);
% variance of signal 2
s2_var = 0.01*(cos(8*t)+10*t);
s2 = generate_signal(signal, s2_var);
% variance of signal 3
s3_var = 0.02*(sin(2*t)+2);
s3 = generate_signal(signal, s3_var);
% variance of signal 4
s4_var = 0.06*ones(size(t));
s4 = generate_signal(signal, s4_var);
% fusion
for i = 1:n
if (i == 1)
[X, P] = init_kalman(X, s1(i, 1)); % initialize the state using the 1st sensor
else
[X, P] = prediction(X, P, Q, F);
[X, P] = update(X, P, s1(i, 1), s1(i, 2), H);
[X, P] = update(X, P, s2(i, 1), s2(i, 2), H);
[X, P] = update(X, P, s3(i, 1), s3(i, 2), H);
[X, P] = update(X, P, s4(i, 1), s4(i, 2), H);
end
X_arr(i, :) = X;
end
plot(t, signal, 'LineWidth', 4);
hold on;
plot(t, s1(:, 1), '--', 'LineWidth', 1);
plot(t, s2(:, 1), '--', 'LineWidth', 1);
plot(t, s3(:, 1), '--', 'LineWidth', 1);
plot(t, s4(:, 1), '--', 'LineWidth', 1);
plot(t, X_arr(:, 1), 'LineWidth', 4);
hold off;
grid on;
legend('Ground Truth', 'Sensor Input 1', 'Sensor Input 2', 'Sensor Input 3', 'Sensor Input 4', 'Fused Output');
end
function [s] = generate_signal(signal, var)
noise = randn(size(signal)).*sqrt(var);
s(:, 1) = signal + noise;
s(:, 2) = var;
end
function [X, P] = init_kalman(X, y)
X(1,1) = y;
X(2,1) = 0;
P = [100 0;
0 300];
end
function [X, P] = prediction(X, P, Q, F)
X = F*X;
P = F*P*F' + Q;
end
function [X, P] = update(X, P, y, R, H)
Inn = y - H*X;
S = H*P*H' + R;
K = P*H'/S;
X = X + K*Inn;
P = P - K*H*P;
end
And here is the result:

Octave: Replacing element of matix/vector with a vector

I am trying to turn each element in a matrix from a value from 1 to 10 into a 10x1 zeros matrix where the element of the zeros matrix corresponding to the value of the original element is equal to 1.
Here is the code:
function q = convert
% Convert y matrix values to 10x1 vector
load('y.mat');
ZERO = zeros(10,1);
% Set 10x1 Matrix of zeros
for i = 1:length(y)
ZERO(y(i)) = 1; % Set yth element of ZERO to 1
y(i) = ZERO; % Set ith element of y equal to new zero
ZERO = zeros(10,1); % Re-establish zero
endfor
When I run it I get the error A(I) = X: X must have the same size as I. Where the matrix I am trying to input does not agree with the size of element of matrix y. Can I get around this?
Sample input:
y = [1; 2; 3; 4; 5]
Sample output:
y = [[1;0;0;0;0;0;0;0;0;0],
[0;1;0;0;0;0;0;0;0;0],
[0;0;1;0;0;0;0;0;0;0],
[0;0;0;0;1;0;0;0;0;0],
[0;0;0;0;0;1;0;0;0;0]]
I'm going to make a couple of assumptions:
You want the return value to be q as in the function signature, and
You want the output in your sample case to be a 10x5 matrix like so:
1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
0 0 0 1 0
0 0 0 0 1
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
Fixing the loop
The problem that gives the error is that you're assigning a 10x1 vector ZERO to a single (scalar) element of the 5x1 vector y:
y(i) = ZERO;
A vector doesn't fit in a scalar. But even if you change this to assign ZERO to a column of y, it doesn't fit because the lengths of the columns are different. That's not what you want to do anyway, because if it had worked, you would have just wiped out the values in y. So let's set the values in the columns of the output array q. (Changes are marked with <== in the comments.)
function q = convert
% Convert y matrix values to 10xn matrix
%load('y.mat');
y = [1; 2; 3; 4; 5]; % <== replace load temporarily
% Set 10x1 Matrix of zeros
ZERO = zeros(10,1);
% Preallocate output array
q = zeros(10, length(y)); % <== preallocate for speed
for i = 1:length(y)
ZERO(y(i)) = 1; % Set yth element of ZERO to 1
q(:,i) = ZERO; % <== Set ith *column* of *q* equal to new zero
ZERO = zeros(10,1); % Re-establish zero
endfor
Improving the loop
This will work, but if you preallocate q, you've already got the correct number of ZERO vectors, so why not just set the values directly?
function q = convert
% Convert y matrix values to 10xn matrix
%load('y.mat');
y = [1; 2; 3; 4; 5]; % <== replace load temporarily
% Preallocate output array
q = zeros(10, length(y)); % <== preallocate for speed
for i = 1:length(y)
q(y(i),i) = 1; % <== Set element at y(ith) row and ith column of q to 1
endfor
Killing the loop
Either of these loops will give you the desired results, but you can do this whole operation without a loop. This answer summarizes different ways to do this, but I'll just show you the first one using sub2ind:
function q = convert
% Convert y matrix values to 10xn matrix
%load('y.mat');
y = [1; 2; 3; 4; 5]; % <== replace load temporarily
% Preallocate output array
q = zeros(10, length(y)); % <== preallocate for speed
idx = sub2ind(size(q), y, [1:length(y)].');
q(idx) = 1;
Final note
It's best not to use i as a variable name in Octave/MATLAB. It's natural in other languages, but in MATLAB i (or j) is the imaginary unit. If you use i as a variable, it shadows that constant. That doesn't make a difference if you use 1i (or 1j) when assigning complex values, but you're going to have to remember to do that and at some point you're going to forget.

Code Golf: Movement in 3 Dimensions

Assuming a 3 dimensional irregular matrix where y = 1.5(x) and z = .5(y).
Further assuming an object starts at 0,0,0 and must move positively in at least two dimensions, and must move in all three dimensions (x+1, y+1, z-1 is okay, x+1, y+1, z=z is not). It may move any number of "spaces", but must move the same number in all directions.
The object is allowed to wraparound (x(max +1) = x(0)).
Move said object from its starting position to (0, max(y), .5(max(z))) For z, round up for fractions (end point in 4, 6, 3 matrix becomes 0, 6, 2)
Input is an Integer (X).
Output is the list of moves you would make (extra credit for showing the number of spaces you moved)
Sample Input/Output:
X = 4
Y = 6 //(4 * 1.5)
Z = 3 // 6 / 2
0, 0, 0 //Start
2, 5, 2 // (+2, -2, +2)
1, 2, 2 // (+4, +4, +4)
3, 4, 0 // (+2, +2, -2)
1, 6, 2 // (-2, +2, +2)
3, 3, 3 // (-3, -3, -3)
1, 5, 1 // (-2, +2, -2)
0, 6, 2 // (-1, +1, -1)
7 Moves.
Lua, 68 Characters
The long version below always solves the problem with one move by searching for the first all positive move that will solve problem.
x=...
y,z=x*3/2,x*3/4
a,b,c=0,y,math.ceil(z/2)
x,y,z=x+1,y+1,z+1
for i=1,math.huge do
if (x*i)%y==b and (x*i)%z==c then x=x*i break end
end
print("0,0,0\n0,"..b..","..c.."//+"..x..",+"..x..",+"..x.."\n1 move.")
Output for x = 12:
0,0,0
0,18,5//+455,+455,+455
1 move.
Output for x = 1000:
0,0,0
0,1500,375//+557424868,+557424868,+557424868
1 move.
Seems like the search could be replaced with some simple algebraic equation. But why stop there? Rules are easier to bend in golfing then doing the actual work.
So, assuming that there is always a single 1 move answer, and that I do not have to disclose the "number of spaces you moved", here is the 68 character golfed answer:
x=...print("0,0,0\n0,"..(x*3/2)..","..math.ceil(x*3/8).."\n1 move.")
Mathematica - Not Golfed
Just to see if we can get the ball rolling
... and trying to understand the problem ....
f[x_] := (
(* Init code *)
xmax = x;
ymax = 3 Round[xmax]/2;
zmax = Round[ymax]/2;
xobj = 0;
yobj = ymax;
zobj = Ceiling[zmax/2];
p = Join[Permutations[{1, 1, -1}], {{1, 1, 1}}];
Print["X = ", xmax, "\nY = ", ymax, "\nZ = ", zmax];
(* Loop *)
i = 0;
pos = {0, 0, 0};
k = "Start";
While[
(npos= {Mod[pos[[1]], xmax+1], Mod[pos[[2]], ymax+1], Mod[pos[[3]], zmax+1]})
!= {xobj, yobj, zobj},
i++;
Print[npos, " // ", k];
pos= npos+ (k= RandomInteger[{1,xmax}] p[[RandomInteger[{1, Length[p]}]]]);
];
Print[npos, " // ", k];
Print[i, " Moves"];
);
Invoke with
f[4]
Sample Output
X = 4
Y = 6
Z = 3
{0,0,0} // Start
{3,4,3} // {3,-3,3}
{0,0,2} // {-3,3,3}
{2,3,1} // {-3,3,3}
{0,6,2} // {3,3,-3}
4 Moves
Not sure if I'm following the rules ...