This feature was built with Sergio de Miguel in the Optimist module. This module contains several models (one is chosen at simulation start time). These models may be spatialized or not. It is possible to view all stands in a spatialized viewer by using the capsis.defaulttype.Spatializer interface and the SVAvatar viewer.
Spatializer is available for the Capsis modules which scene class extends capsis.defaulttype.TreeList and the trees extends capsis.defaulttype.Tree. The Model class must implement Spatializer and provide a getAvatars () method.
/** * Returns a list of individual spatialized avatars for the trees * (individuals or class widths) in the given treeList. */ public List<TreeAvatar> getAvatars(TreeList treeList);
The method must return a list of capsis.defaulttype.TreeAvatar instances, i.e. spatialized individual images of the trees in the stand. Thus, for a model with Numberable tree classes (i.e. represents several trees), the method will return n avatars with n = tree.getNumer () for each tree class.
It is important that the avatars of a single Numberable tree are kept on the same locations all along the simulation. To spatialize in a consistent manner the avatars of a single Numberable tree, the following kind of method can be used. The trick is to pass the tree id (unique in the scene) at instanciation time to the random number generator. Then if you draw n times an x and a y, they will be the same at each call of the method, consequently each time the viewer is synchronized on a different step of the simulation.
You may notice that each avatar holds a reference to the original tree it represents at its current location. TreeAvatars provide a simple description for the crown. Other avatar classes could be built to represent more complex crowns if needed.
Random random = new Random(t.getId()); double xSize = treeList.getXSize(); double ySize = treeList.getYSize(); for (int i = 0; i < t.getNumber(); i++) { String name = ""; double x = random.nextDouble() * xSize; double y = random.nextDouble() * ySize; double z = 0; TreeAvatar a = new TreeAvatar(t.getId(), name, x, y, z, t.getDbh(), t.getHeight(), trunkColor); double crownBaseHeight = 0.5d * t.getHeight(); double crownRadius = 0.33 * crownBaseHeight; double[][] crownProfile = BrutiauaModel.crownProfile; a.setCrown(crownBaseHeight, crownRadius, crownColor, crownProfile); a.setRealTree(t); Vertex3d relativeMin = new Vertex3d(-crownRadius, -crownRadius, 0); Vertex3d relativeMax = new Vertex3d(crownRadius, crownRadius, t.getHeight()); a.setRelativeMin(relativeMin); a.setRelativeMax(relativeMax); list.add(a); }