- The for statement is taking one column, not row, at a time.
- The value of A keeps changing.
For loop of distance equation returning a confusing output
3 visualizaciones (últimos 30 días)
Mostrar comentarios más antiguos
Michael J
el 24 de Feb. de 2015
Hello,
I have two matrices of coordinate points for two surfaces, one inside the other, and I am trying to create a third surface by cutting the outer surface down to a certain size (get rid of excess noise). To do this I am using two for loops, for each matrix and an if statement with the Euclidean distance equation to see if the points are within a predetermined distance. As shown below:
A = [];
for pointr = boundred
for pointb = blue
if sqrt((pointb(1)-pointr(1))^2 + (pointb(2)-pointr(2))^2 + (pointb(3)-pointr(3))^2) < 100
A = pointb;
end
end
end
The output of A is just the Z coordinates of surface blue, which confuses me. To my understanding the
for pointb = blue
iterates the loop over all of the rows, so pointb should be a row of the matrix blue. I don't understand why it only outputs pointb(3), the Z coordinate. If someone could explain why my code outputs only a part of what I am hoping to get, I would greatly appreciate it!
0 comentarios
Respuesta aceptada
Andrew Newell
el 24 de Feb. de 2015
Editada: Andrew Newell
el 24 de Feb. de 2015
When something is going wrong, it's a good idea to look at the intermediate results. You could use the debugger, or you could just make some things print out as you go. As a crude check of what's going on, try the following code:
boundred = 0.3*[1 1 1; 2 2 2].'
blue = 0.2*[1 1 1; 2 2 2].'
A = [];
for pointr = boundred
pointr
for pointb = blue
pointb
if sqrt((pointb(1)-pointr(1))^2 + (pointb(2)-pointr(2))^2 + (pointb(3)-pointr(3))^2) < 100
A = pointb
end
end
end
A few things should be evident:
If you want to collect the values of A, you'll need to change the assignment line to
A = [A pointb];
But if you do that, you'll find that there are repeated values of pointb in A. In essence, you're keeping each point of blue if it is within a sphere of radius 10 around any point in boundred. Is that what you want?
3 comentarios
Andrew Newell
el 25 de Feb. de 2015
The biggest slowdown in many MATLAB programs is due to commands like
A = [A pointb];
because it keeps changing the size of A (see Programming Patterns: Maximizing Code Performance by Optimizing Memory Access). You should pre-allocate vectors so MATLAB doesn't have to keep allocating new memory. But how can you do that if you don't know how large A is going to be?
By looking at the problem differently. In your code, you're deciding whether to keep each point in blue. So you could create an index idx that has an entry for each point, and then operate on that:
idx = true(1,size(blue,2));
for pointb = blue
pb = repmat(pointb,1,length(boundred));
idx = idx & sum((pb-boundred).^2) < r^2;
end
A = blue(idx);
This uses logical indexing (each component is true or false) because that is faster than numerical indexing. For 1000 points, the above code is about 100 times faster than yours.
Más respuestas (0)
Ver también
Categorías
Más información sobre Creating and Concatenating Matrices en Help Center y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!