Using cell fun to extract data from a cell containing objects
    14 visualizzazioni (ultimi 30 giorni)
  
       Mostra commenti meno recenti
    
    Alexander James
 il 30 Apr 2020
  
    
    
    
    
    Modificato: Alexander James
 il 24 Mag 2020
            Hello, everyone, first of I'm just beginning to learn MATLAB and trying to write an object oriented program to plant and manage a forest
I'm trying to programme an opertation which will "plant" a tree then check it's position againt all of the other tree's in the domain. Tree's cannot be planted closer than 0.5 away from each other. I succeded partially but then realised I was only checking the postion of the newly planted tree against the preceeding one, not against all the other trees in the "forest". I tried to change the operation to sqrt((Forest{i}.x - Forest{1:i-1}.x)^2 + (Forest{i}.y - Forest{1:i-1}.y))^2 < 0.5 but the planting of the third tree, I recieved this error
Expected one output from a curly brace or dot indexing expression, but there were 2 results. 
I looked into and I cannot check the position against all of the objects in the cell this way. I looked into using cellfun but I'm not sure that's the right approach as it's ouput only be one figure, would it best to create a for loop within the while loop? Or some other apporach
Thanks
Forest={};
first = Oak((68-1).*rand(1,1)+1, (78-1).*rand(1,1)+1,0.25);
Forest{1}=first;
i=1;
while numel(Forest)<Size_of_intialforest
    i=i+1;
    if rand(1,1)>0.5
        shoot(i) = Oak((68-1).*rand(1,1)+1, (78-1).*rand(1,1)+1,0.25);
    else 
        shoot(i) = Birch((68-1).*rand(1,1)+1, (78-1).*rand(1,1)+1,0.2);
    end
    Forest{i}= shoot(i)
        % Check location   
    if sqrt((Forest{i}.x - Forest{i-1}.x)^2 + (Forest{i}.y - Forest{i-1}.y))^2 < 0.5
        Forest{i} = {};  % Tree planted too close to the last and is removed by the local community
        i=i-1; % step the clock back one to replant the next tree      
    end
    %if sqrt((Forest{i}.x - cellfun(Tree.x,Forest{1:i-1})^2 + (Forest{i}.y - cellfun(Tree.y,Forest{1:i-1}))^2 < 0.5
end
2 Commenti
  Stephen23
      
      
 il 30 Apr 2020
				
      Modificato: Stephen23
      
      
 il 30 Apr 2020
  
			"Expected one output from a curly brace or dot indexing expression, but there were 2 results."
The error is because of how you are using this syntax:
Forest{1:i-1}
Read these to know what that syntax actually does:
It would probably be easier to use a non-scalar structure (rather than that cell array of scalar structures/objects):
Risposta accettata
  Guillaume
      
      
 il 30 Apr 2020
        
      Modificato: Guillaume
      
      
 il 30 Apr 2020
  
      "I don't understant what a non-scalar structure implies at the moment but I'll look into it"
A non-scalar structure is simply a structure array:
s(1).x = 1234;
s(2).x = 4567;
%s is a 1x2 structure with field x
Whereas at the moment what you're doing is storing 1x1 structures (actually from your description I think it's 1x1 objects) into a 1D cell array, so instead you have:
c{1} = struct('x', 1234);
c{2} = struct('x', 4567);
I think you're using objects not structures, but what Stephen said about structures also applies to objects. You can use an array of objects as long as they are the same class, instead of storing them in a cell array.
However, in your case it appears that you're using two different classes. In that case, in order to put all these objects in an array, you will have to derive each class from matlab.mixin.heterogeneous. If it's beyond your current level, then stay with a cell array but you have to be aware that indeed you won't be able to write anything like Forest{a:b}. You will have to loop over the elements of the cell array either with a explicit loop or with cellfun and co.
To calculate the distance of a tree against all other trees:
curtree = Forest{i};
dist = cellfun(@(tree) hypot(tree.x - curtree.x, tree.y - curtree.y), Forest(1:i-1));
if any(dist < 0.5)
    %tree is to close to at least one other tree
    %...
end
edit: actually looking a bit more closely at your code, it looks like your Oak and Birch are already heterogeneous arrays since you have:
        shoot(i) = Oak(..)
    else
        shoot(i) = Birch(..)
Functionally, there's no difference between the cell array Forest of scalar objects and the non-scalar heterogeneous object shoot. So you could also do:
dist = hypot([shoot(1:i-1).x] - shoot(i).x, [shoot(1:i-1).y] - shoot(i).y);
if any(dist < 0.5)
    %tree is to close to at least one other tree
    %...
end
and never bother with Forest.
10 Commenti
Più risposte (0)
Vedere anche
Categorie
				Scopri di più su Data Type Identification in Help Center e File Exchange
			
	Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!

