Author: luc
Date: Fri Jun  1 20:02:04 2012
New Revision: 1345328

URL: http://svn.apache.org/viewvc?rev=1345328&view=rev
Log:
Replaced Characterization by an internal class in AbstractRegion.

Note that the suppresses class was a package private one and did not
belong to the public API. It was used only when building the boundaries
in the AbstractRegion class. The change simplifies the package and makes
better use of the existing visitor pattern.

Removed:
    
commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/partitioning/Characterization.java
Modified:
    
commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/partitioning/AbstractRegion.java

Modified: 
commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/partitioning/AbstractRegion.java
URL: 
http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/partitioning/AbstractRegion.java?rev=1345328&r1=1345327&r2=1345328&view=diff
==============================================================================
--- 
commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/partitioning/AbstractRegion.java
 (original)
+++ 
commons/proper/math/trunk/src/main/java/org/apache/commons/math3/geometry/partitioning/AbstractRegion.java
 Fri Jun  1 20:02:04 2012
@@ -16,6 +16,7 @@
  */
 package org.apache.commons.math3.geometry.partitioning;
 
+import java.lang.reflect.Array;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Comparator;
@@ -278,94 +279,125 @@ public abstract class AbstractRegion<S e
     public BSPTree<S> getTree(final boolean includeBoundaryAttributes) {
         if (includeBoundaryAttributes && (tree.getCut() != null) && 
(tree.getAttribute() == null)) {
             // we need to compute the boundary attributes
-            recurseBuildBoundary(tree);
+            tree.visit(new BoundaryBuilder<S>());
         }
         return tree;
     }
 
-    /** Recursively build the boundary shell tree.
-     * @param node current node in the inout tree
+    /** Visitor building boundary shell tree.
+     * <p>
+     * The boundary shell is represented as {@link BoundaryAttribute boundary 
attributes}
+     * at each internal node.
+     * </p>
      */
-    private void recurseBuildBoundary(final BSPTree<S> node) {
-        if (node.getCut() != null) {
+    private static class BoundaryBuilder<S extends Space> implements 
BSPTreeVisitor<S> {
+
+        /** {@inheritDoc} */
+        public Order visitOrder(BSPTree<S> node) {
+            return Order.PLUS_MINUS_SUB;
+        }
+
+        /** {@inheritDoc} */
+        public void visitInternalNode(BSPTree<S> node) {
 
             SubHyperplane<S> plusOutside = null;
             SubHyperplane<S> plusInside  = null;
 
             // characterize the cut sub-hyperplane,
             // first with respect to the plus sub-tree
-            final Characterization<S> plusChar = new Characterization<S>();
+            @SuppressWarnings("unchecked")
+            final SubHyperplane<S>[] plusChar = (SubHyperplane<S>[]) 
Array.newInstance(SubHyperplane.class, 2);
             characterize(node.getPlus(), node.getCut().copySelf(), plusChar);
 
-            if (plusChar.hasOut()) {
-                // plusChar.getOut() corresponds to a subset of the cut
-                // sub-hyperplane known to have outside cells on its plus
-                // side, we want to check if parts of this subset do have
-                // inside cells on their minus side
-                final Characterization<S> minusChar = new 
Characterization<S>();
-                characterize(node.getMinus(), plusChar.getOut(), minusChar);
-                if (minusChar.hasIn()) {
-                    plusOutside = minusChar.getIn();
+            if (plusChar[0] != null && !plusChar[0].isEmpty()) {
+                // plusChar[0] corresponds to a subset of the cut 
sub-hyperplane known to have
+                // outside cells on its plus side, we want to check if parts 
of this subset
+                // do have inside cells on their minus side
+                @SuppressWarnings("unchecked")
+                final SubHyperplane<S>[] minusChar = (SubHyperplane<S>[]) 
Array.newInstance(SubHyperplane.class, 2);
+                characterize(node.getMinus(), plusChar[0], minusChar);
+                if (minusChar[1] != null && !minusChar[1].isEmpty()) {
+                    // this part belongs to the boundary,
+                    // it has the outside on its plus side and the inside on 
its minus side
+                    plusOutside = minusChar[1];
                 }
             }
 
-            if (plusChar.hasIn()) {
-                // plusChar.getIn() corresponds to a subset of the cut
-                // sub-hyperplane known to have inside cells on its plus
-                // side, we want to check if parts of this subset do have
-                // outside cells on their minus side
-                final Characterization<S> minusChar = new 
Characterization<S>();
-                characterize(node.getMinus(), plusChar.getIn(), minusChar);
-                if (minusChar.hasOut()) {
-                    plusInside = minusChar.getOut();
+            if (plusChar[1] != null && !plusChar[1].isEmpty()) {
+                // plusChar[1] corresponds to a subset of the cut 
sub-hyperplane known to have
+                // inside cells on its plus side, we want to check if parts of 
this subset
+                // do have outside cells on their minus side
+                @SuppressWarnings("unchecked")
+                final SubHyperplane<S>[] minusChar = (SubHyperplane<S>[]) 
Array.newInstance(SubHyperplane.class, 2);
+                characterize(node.getMinus(), plusChar[1], minusChar);
+                if (minusChar[0] != null && !minusChar[0].isEmpty()) {
+                    // this part belongs to the boundary,
+                    // it has the inside on its plus side and the outside on 
its minus side
+                    plusInside = minusChar[0];
                 }
             }
 
+            // set the boundary attribute at non-leaf nodes
             node.setAttribute(new BoundaryAttribute<S>(plusOutside, 
plusInside));
-            recurseBuildBoundary(node.getPlus());
-            recurseBuildBoundary(node.getMinus());
 
         }
-    }
 
-    /** Filter the parts of an hyperplane belonging to the boundary.
-     * <p>The filtering consist in splitting the specified
-     * sub-hyperplane into several parts lying in inside and outside
-     * cells of the tree. The principle is to call this method twice for
-     * each cut sub-hyperplane in the tree, once one the plus node and
-     * once on the minus node. The parts that have the same flag
-     * (inside/inside or outside/outside) do not belong to the boundary
-     * while parts that have different flags (inside/outside or
-     * outside/inside) do belong to the boundary.</p>
-     * @param node current BSP tree node
-     * @param sub sub-hyperplane to characterize
-     * @param characterization placeholder where to put the characterized parts
-     */
-    private void characterize(final BSPTree<S> node, final SubHyperplane<S> 
sub,
-                              final Characterization<S> characterization) {
-        if (node.getCut() == null) {
-            // we have reached a leaf node
-            final boolean inside = (Boolean) node.getAttribute();
-            characterization.add(sub, inside);
-        } else {
-            final Hyperplane<S> hyperplane = node.getCut().getHyperplane();
-            switch (sub.side(hyperplane)) {
-            case PLUS:
-                characterize(node.getPlus(), sub, characterization);
-                break;
-            case MINUS:
-                characterize(node.getMinus(), sub, characterization);
-                break;
-            case BOTH:
-                final SubHyperplane.SplitSubHyperplane<S> split = 
sub.split(hyperplane);
-                characterize(node.getPlus(),  split.getPlus(),  
characterization);
-                characterize(node.getMinus(), split.getMinus(), 
characterization);
-                break;
-            default:
-                // this should not happen
-                throw new MathInternalError();
+        /** {@inheritDoc} */
+        public void visitLeafNode(BSPTree<S> node) {
+        }
+
+        /** Filter the parts of an hyperplane belonging to the boundary.
+         * <p>The filtering consist in splitting the specified
+         * sub-hyperplane into several parts lying in inside and outside
+         * cells of the tree. The principle is to call this method twice for
+         * each cut sub-hyperplane in the tree, once one the plus node and
+         * once on the minus node. The parts that have the same flag
+         * (inside/inside or outside/outside) do not belong to the boundary
+         * while parts that have different flags (inside/outside or
+         * outside/inside) do belong to the boundary.</p>
+         * @param node current BSP tree node
+         * @param sub sub-hyperplane to characterize
+         * @param characterization placeholder where to put the characterized 
parts
+         */
+        private void characterize(final BSPTree<S> node, final 
SubHyperplane<S> sub,
+                                  final SubHyperplane<S>[] characterization) {
+            if (node.getCut() == null) {
+                // we have reached a leaf node
+                final boolean inside = (Boolean) node.getAttribute();
+                if (inside) {
+                    if (characterization[1] == null) {
+                        characterization[1] = sub;
+                    } else {
+                        characterization[1] = characterization[1].reunite(sub);
+                    }
+                } else {
+                    if (characterization[0] == null) {
+                        characterization[0] = sub;
+                    } else {
+                        characterization[0] = characterization[0].reunite(sub);
+                    }
+                }
+            } else {
+                final Hyperplane<S> hyperplane = node.getCut().getHyperplane();
+                switch (sub.side(hyperplane)) {
+                case PLUS:
+                    characterize(node.getPlus(), sub, characterization);
+                    break;
+                case MINUS:
+                    characterize(node.getMinus(), sub, characterization);
+                    break;
+                case BOTH:
+                    final SubHyperplane.SplitSubHyperplane<S> split = 
sub.split(hyperplane);
+                    characterize(node.getPlus(),  split.getPlus(),  
characterization);
+                    characterize(node.getMinus(), split.getMinus(), 
characterization);
+                    break;
+                default:
+                    // this should not happen
+                    throw new MathInternalError();
+                }
             }
         }
+
     }
 
     /** {@inheritDoc} */


Reply via email to