Nicely done! Do you think we've converged on the optimum yet?
Cheers, obviously I shamelessly adopted your favourite function.
I honestly thought we'd converged to an optimum (although a slightly distorted use of that word) back at around 64, then 55, then 48... so I only tentatively think we've reached the end. I'd certainly be relieved to call it a draw :)
I thought that maybe we could get rid of the extra arguments to sum(,2) and any(,2) by converting to a row matrix, but doing so would add arguments circshift(), so that way may not have any improvements left.
I do know that *every single line* of our function generates an MLint warning :) Oh, except the function name now.
Yeah, I tried all sorts of ways to do that too! I was trying to figure out a better way to normalise the matrix. I discovered normr, posted my solution, and then realised that it was actually a toolbox function. I'd be happy to have that entry removed : If you replace the normalisation line with normr(diff(P)) you can get the 36
Hah, "Undefined function or variable 'normr'." A while back I had a version with normalizeVector3d(), part of the geom3d() package I use all the time...
I'd be interested to see under the hood of normr... I hope it's vectorized via bsxfun()
no it doesn't! it does something like:
n = sqrt(sum(x.^2,2));
x = x ./ n(:, ones(1, size(x,2)));
Well then, I bet that the following would run faster and work on any dimensioned data (such as a [10,2,50] sized matrix representing 50 sets of 10 XY vectors):
normr = @(v)bsxfun(@rdivide, v, sqrt(sum(v.^2, 2)));
Test  Status  Code Input and Output 

1  Pass 
%% Edge case: no vertices
P = zeros(0,2);
P2 = zeros(0,2);
assert(isequal(simplify_polygon(P), P2));

2  Pass 
%% Edge case: one vertex
P = [1 1];
P2 = [1 1];
assert(isequal(simplify_polygon(P), P2));

3  Pass 
%% Edge case: three vertices (a single line segment)
P = [...
1 1
1 2
1 1 ];
P2 = [...
1 1
1 2
1 1];
assert(isequal(simplify_polygon(P), P2));

4  Pass 
%% Single line segment with multiple vertices
P = [ ...
1 1
2 1
3 1
4 1
5 1
4 1
3 1
2 1
1 1];
P2 = [ ...
1 1
5 1
1 1];
assert(isequal(simplify_polygon(P), P2));

5  Pass 
%% Single line segment, different spacing
P = [ ...
1 1
2 1
4 1
5 1
1 1];
P2 = [ ...
1 1
5 1
1 1];
assert(isequal(simplify_polygon(P), P2));

6  Pass 
%% Rectangle
P = [ ...
1 1
2 1
3 1
4 1
4 2
4 3
3 3
2 3
1 3
1 2
1 1];
P2 = [ ...
1 1
4 1
4 3
1 3
1 1];
assert(isequal(simplify_polygon(P), P2));

7  Pass 
%% Two rectangles separated by line segment
P = [ ...
1 2
1 1
2 1
2 2
1 2
1 3
1 4
1 5
2 5
2 4
1 4
1 3
1 2];
P2 = [ ...
1 1
2 1
2 2
1 2
1 5
2 5
2 4
1 4
1 1];
assert(isequal(simplify_polygon(P), P2));

8  Pass 
%% Nonsimple polygon (figure eight)
P = [ ...
1 1
2 2
3 3
1 3
2 2
3 1
1 1];
P2 = [ ...
1 1
3 3
1 3
3 1
1 1];
assert(isequal(simplify_polygon(P), P2));

9  Pass 
%%
P = [ ...
1 1
2 2
3 3
4 4
5 5
5 4
6 3
8 1
7 1
1 1];
P2 = [ ...
1 1
5 5
5 4
8 1
1 1];
assert(isequal(simplify_polygon(P), P2));

10  Pass 
%% Circle; no points should be removed
theta = linspace(0,2*pi,200);
theta(end) = 0;
x = 20*cos(theta);
y = 20*sin(theta);
P = [x', y'];
P2 = P;
assert(isequal(simplify_polygon(P), P2));

11  Pass 
%% Starting vertex can be removed
P = [ ...
2 1
3 1
3 2
3 3
2 3
1 3
1 2
1 1
2 1];
P2 = [ ...
3 1
3 3
1 3
1 1
3 1];
assert(isequal(simplify_polygon(P), P2));

2722 Solvers
7556 Solvers
275 Solvers
511 Solvers
Find third Side of a right triangle given hypotenuse and a side. No *  or other functions allowed
169 Solvers