Return-Path: X-Original-To: apmail-commons-notifications-archive@minotaur.apache.org Delivered-To: apmail-commons-notifications-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 3E47117AEB for ; Fri, 17 Apr 2015 19:17:26 +0000 (UTC) Received: (qmail 13051 invoked by uid 500); 17 Apr 2015 19:17:23 -0000 Delivered-To: apmail-commons-notifications-archive@commons.apache.org Received: (qmail 12994 invoked by uid 500); 17 Apr 2015 19:17:23 -0000 Mailing-List: contact notifications-help@commons.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@commons.apache.org Delivered-To: mailing list notifications@commons.apache.org Received: (qmail 12845 invoked by uid 99); 17 Apr 2015 19:17:23 -0000 Received: from eris.apache.org (HELO hades.apache.org) (140.211.11.105) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 17 Apr 2015 19:17:23 +0000 Received: from hades.apache.org (localhost [127.0.0.1]) by hades.apache.org (ASF Mail Server at hades.apache.org) with ESMTP id D9306AC0BA5 for ; Fri, 17 Apr 2015 19:17:22 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r948061 [7/22] - in /websites/production/commons/content/proper/commons-math: ./ xref/ xref/org/apache/commons/math3/ xref/org/apache/commons/math3/analysis/ xref/org/apache/commons/math3/analysis/differentiation/ xref/org/apache/commons/ma... Date: Fri, 17 Apr 2015 19:17:18 -0000 To: notifications@commons.apache.org From: luc@apache.org X-Mailer: svnmailer-1.0.9 Message-Id: <20150417191722.D9306AC0BA5@hades.apache.org> Modified: websites/production/commons/content/proper/commons-math/xref/org/apache/commons/math3/geometry/euclidean/threed/PolyhedronsSet.html ============================================================================== --- websites/production/commons/content/proper/commons-math/xref/org/apache/commons/math3/geometry/euclidean/threed/PolyhedronsSet.html (original) +++ websites/production/commons/content/proper/commons-math/xref/org/apache/commons/math3/geometry/euclidean/threed/PolyhedronsSet.html Fri Apr 17 19:17:13 2015 @@ -25,526 +25,725 @@ 17 package org.apache.commons.math3.geometry.euclidean.threed; 18 19 import java.awt.geom.AffineTransform; -20 import java.util.Collection; -21 -22 import org.apache.commons.math3.geometry.Point; -23 import org.apache.commons.math3.geometry.euclidean.oned.Euclidean1D; -24 import org.apache.commons.math3.geometry.euclidean.twod.Euclidean2D; -25 import org.apache.commons.math3.geometry.euclidean.twod.SubLine; -26 import org.apache.commons.math3.geometry.euclidean.twod.Vector2D; -27 import org.apache.commons.math3.geometry.partitioning.AbstractRegion; -28 import org.apache.commons.math3.geometry.partitioning.BSPTree; -29 import org.apache.commons.math3.geometry.partitioning.BSPTreeVisitor; -30 import org.apache.commons.math3.geometry.partitioning.BoundaryAttribute; -31 import org.apache.commons.math3.geometry.partitioning.Hyperplane; -32 import org.apache.commons.math3.geometry.partitioning.Region; -33 import org.apache.commons.math3.geometry.partitioning.RegionFactory; -34 import org.apache.commons.math3.geometry.partitioning.SubHyperplane; -35 import org.apache.commons.math3.geometry.partitioning.Transform; -36 import org.apache.commons.math3.util.FastMath; -37 -38 /** This class represents a 3D region: a set of polyhedrons. -39 * @since 3.0 -40 */ -41 public class PolyhedronsSet extends AbstractRegion<Euclidean3D, Euclidean2D> { -42 -43 /** Default value for tolerance. */ -44 private static final double DEFAULT_TOLERANCE = 1.0e-10; -45 -46 /** Build a polyhedrons set representing the whole real line. -47 * @param tolerance tolerance below which points are considered identical -48 * @since 3.3 -49 */ -50 public PolyhedronsSet(final double tolerance) { -51 super(tolerance); -52 } -53 -54 /** Build a polyhedrons set from a BSP tree. -55 * <p>The leaf nodes of the BSP tree <em>must</em> have a -56 * {@code Boolean} attribute representing the inside status of -57 * the corresponding cell (true for inside cells, false for outside -58 * cells). In order to avoid building too many small objects, it is -59 * recommended to use the predefined constants -60 * {@code Boolean.TRUE} and {@code Boolean.FALSE}</p> -61 * <p> -62 * This constructor is aimed at expert use, as building the tree may -63 * be a difficult task. It is not intended for general use and for -64 * performances reasons does not check thoroughly its input, as this would -65 * require walking the full tree each time. Failing to provide a tree with -66 * the proper attributes, <em>will</em> therefore generate problems like -67 * {@link NullPointerException} or {@link ClassCastException} only later on. -68 * This limitation is known and explains why this constructor is for expert -69 * use only. The caller does have the responsibility to provided correct arguments. -70 * </p> -71 * @param tree inside/outside BSP tree representing the region -72 * @param tolerance tolerance below which points are considered identical -73 * @since 3.3 -74 */ -75 public PolyhedronsSet(final BSPTree<Euclidean3D> tree, final double tolerance) { -76 super(tree, tolerance); -77 } -78 -79 /** Build a polyhedrons set from a Boundary REPresentation (B-rep). -80 * <p>The boundary is provided as a collection of {@link -81 * SubHyperplane sub-hyperplanes}. Each sub-hyperplane has the -82 * interior part of the region on its minus side and the exterior on -83 * its plus side.</p> -84 * <p>The boundary elements can be in any order, and can form -85 * several non-connected sets (like for example polyhedrons with holes -86 * or a set of disjoint polyhedrons considered as a whole). In -87 * fact, the elements do not even need to be connected together -88 * (their topological connections are not used here). However, if the -89 * boundary does not really separate an inside open from an outside -90 * open (open having here its topological meaning), then subsequent -91 * calls to the {@link Region#checkPoint(Point) checkPoint} method will -92 * not be meaningful anymore.</p> -93 * <p>If the boundary is empty, the region will represent the whole -94 * space.</p> -95 * @param boundary collection of boundary elements, as a -96 * collection of {@link SubHyperplane SubHyperplane} objects -97 * @param tolerance tolerance below which points are considered identical -98 * @since 3.3 -99 */ -100 public PolyhedronsSet(final Collection<SubHyperplane<Euclidean3D>> boundary, -101 final double tolerance) { -102 super(boundary, tolerance); -103 } -104 -105 /** Build a parallellepipedic box. -106 * @param xMin low bound along the x direction -107 * @param xMax high bound along the x direction -108 * @param yMin low bound along the y direction -109 * @param yMax high bound along the y direction -110 * @param zMin low bound along the z direction -111 * @param zMax high bound along the z direction -112 * @param tolerance tolerance below which points are considered identical -113 * @since 3.3 -114 */ -115 public PolyhedronsSet(final double xMin, final double xMax, -116 final double yMin, final double yMax, -117 final double zMin, final double zMax, -118 final double tolerance) { -119 super(buildBoundary(xMin, xMax, yMin, yMax, zMin, zMax, tolerance), tolerance); -120 } -121 -122 /** Build a polyhedrons set representing the whole real line. -123 * @deprecated as of 3.3, replaced with {@link #PolyhedronsSet(double)} -124 */ -125 @Deprecated -126 public PolyhedronsSet() { -127 this(DEFAULT_TOLERANCE); -128 } -129 -130 /** Build a polyhedrons set from a BSP tree. -131 * <p>The leaf nodes of the BSP tree <em>must</em> have a -132 * {@code Boolean} attribute representing the inside status of -133 * the corresponding cell (true for inside cells, false for outside -134 * cells). In order to avoid building too many small objects, it is -135 * recommended to use the predefined constants -136 * {@code Boolean.TRUE} and {@code Boolean.FALSE}</p> -137 * @param tree inside/outside BSP tree representing the region -138 * @deprecated as of 3.3, replaced with {@link #PolyhedronsSet(BSPTree, double)} -139 */ -140 @Deprecated -141 public PolyhedronsSet(final BSPTree<Euclidean3D> tree) { -142 this(tree, DEFAULT_TOLERANCE); -143 } -144 -145 /** Build a polyhedrons set from a Boundary REPresentation (B-rep). -146 * <p>The boundary is provided as a collection of {@link -147 * SubHyperplane sub-hyperplanes}. Each sub-hyperplane has the -148 * interior part of the region on its minus side and the exterior on -149 * its plus side.</p> -150 * <p>The boundary elements can be in any order, and can form -151 * several non-connected sets (like for example polyhedrons with holes -152 * or a set of disjoint polyhedrons considered as a whole). In -153 * fact, the elements do not even need to be connected together -154 * (their topological connections are not used here). However, if the -155 * boundary does not really separate an inside open from an outside -156 * open (open having here its topological meaning), then subsequent -157 * calls to the {@link Region#checkPoint(Point) checkPoint} method will -158 * not be meaningful anymore.</p> -159 * <p>If the boundary is empty, the region will represent the whole -160 * space.</p> -161 * @param boundary collection of boundary elements, as a -162 * collection of {@link SubHyperplane SubHyperplane} objects -163 * @deprecated as of 3.3, replaced with {@link #PolyhedronsSet(Collection, double)} -164 */ -165 @Deprecated -166 public PolyhedronsSet(final Collection<SubHyperplane<Euclidean3D>> boundary) { -167 this(boundary, DEFAULT_TOLERANCE); -168 } -169 -170 /** Build a parallellepipedic box. -171 * @param xMin low bound along the x direction -172 * @param xMax high bound along the x direction -173 * @param yMin low bound along the y direction -174 * @param yMax high bound along the y direction -175 * @param zMin low bound along the z direction -176 * @param zMax high bound along the z direction -177 * @deprecated as of 3.3, replaced with {@link #PolyhedronsSet(double, double, -178 * double, double, double, double, double)} -179 */ -180 @Deprecated -181 public PolyhedronsSet(final double xMin, final double xMax, -182 final double yMin, final double yMax, -183 final double zMin, final double zMax) { -184 this(xMin, xMax, yMin, yMax, zMin, zMax, DEFAULT_TOLERANCE); -185 } -186 -187 /** Build a parallellepipedic box boundary. -188 * @param xMin low bound along the x direction -189 * @param xMax high bound along the x direction -190 * @param yMin low bound along the y direction -191 * @param yMax high bound along the y direction -192 * @param zMin low bound along the z direction -193 * @param zMax high bound along the z direction -194 * @param tolerance tolerance below which points are considered identical -195 * @return boundary tree -196 * @since 3.3 -197 */ -198 private static BSPTree<Euclidean3D> buildBoundary(final double xMin, final double xMax, -199 final double yMin, final double yMax, -200 final double zMin, final double zMax, -201 final double tolerance) { -202 if ((xMin >= xMax - tolerance) || (yMin >= yMax - tolerance) || (zMin >= zMax - tolerance)) { -203 // too thin box, build an empty polygons set -204 return new BSPTree<Euclidean3D>(Boolean.FALSE); -205 } -206 final Plane pxMin = new Plane(new Vector3D(xMin, 0, 0), Vector3D.MINUS_I, tolerance); -207 final Plane pxMax = new Plane(new Vector3D(xMax, 0, 0), Vector3D.PLUS_I, tolerance); -208 final Plane pyMin = new Plane(new Vector3D(0, yMin, 0), Vector3D.MINUS_J, tolerance); -209 final Plane pyMax = new Plane(new Vector3D(0, yMax, 0), Vector3D.PLUS_J, tolerance); -210 final Plane pzMin = new Plane(new Vector3D(0, 0, zMin), Vector3D.MINUS_K, tolerance); -211 final Plane pzMax = new Plane(new Vector3D(0, 0, zMax), Vector3D.PLUS_K, tolerance); -212 @SuppressWarnings("unchecked") -213 final Region<Euclidean3D> boundary = -214 new RegionFactory<Euclidean3D>().buildConvex(pxMin, pxMax, pyMin, pyMax, pzMin, pzMax); -215 return boundary.getTree(false); -216 } -217 -218 /** {@inheritDoc} */ -219 @Override -220 public PolyhedronsSet buildNew(final BSPTree<Euclidean3D> tree) { -221 return new PolyhedronsSet(tree, getTolerance()); -222 } -223 -224 /** {@inheritDoc} */ -225 @Override -226 protected void computeGeometricalProperties() { -227 -228 // compute the contribution of all boundary facets -229 getTree(true).visit(new FacetsContributionVisitor()); -230 -231 if (getSize() < 0) { -232 // the polyhedrons set as a finite outside -233 // surrounded by an infinite inside -234 setSize(Double.POSITIVE_INFINITY); -235 setBarycenter((Point<Euclidean3D>) Vector3D.NaN); -236 } else { -237 // the polyhedrons set is finite, apply the remaining scaling factors -238 setSize(getSize() / 3.0); -239 setBarycenter((Point<Euclidean3D>) new Vector3D(1.0 / (4 * getSize()), (Vector3D) getBarycenter())); -240 } -241 -242 } -243 -244 /** Visitor computing geometrical properties. */ -245 private class FacetsContributionVisitor implements BSPTreeVisitor<Euclidean3D> { -246 -247 /** Simple constructor. */ -248 public FacetsContributionVisitor() { -249 setSize(0); -250 setBarycenter((Point<Euclidean3D>) new Vector3D(0, 0, 0)); -251 } -252 -253 /** {@inheritDoc} */ -254 public Order visitOrder(final BSPTree<Euclidean3D> node) { -255 return Order.MINUS_SUB_PLUS; -256 } -257 -258 /** {@inheritDoc} */ -259 public void visitInternalNode(final BSPTree<Euclidean3D> node) { -260 @SuppressWarnings("unchecked") -261 final BoundaryAttribute<Euclidean3D> attribute = -262 (BoundaryAttribute<Euclidean3D>) node.getAttribute(); -263 if (attribute.getPlusOutside() != null) { -264 addContribution(attribute.getPlusOutside(), false); -265 } -266 if (attribute.getPlusInside() != null) { -267 addContribution(attribute.getPlusInside(), true); +20 import java.util.ArrayList; +21 import java.util.Arrays; +22 import java.util.Collection; +23 import java.util.List; +24 +25 import org.apache.commons.math3.exception.MathIllegalArgumentException; +26 import org.apache.commons.math3.exception.NumberIsTooSmallException; +27 import org.apache.commons.math3.exception.util.LocalizedFormats; +28 import org.apache.commons.math3.geometry.Point; +29 import org.apache.commons.math3.geometry.euclidean.oned.Euclidean1D; +30 import org.apache.commons.math3.geometry.euclidean.twod.Euclidean2D; +31 import org.apache.commons.math3.geometry.euclidean.twod.PolygonsSet; +32 import org.apache.commons.math3.geometry.euclidean.twod.SubLine; +33 import org.apache.commons.math3.geometry.euclidean.twod.Vector2D; +34 import org.apache.commons.math3.geometry.partitioning.AbstractRegion; +35 import org.apache.commons.math3.geometry.partitioning.BSPTree; +36 import org.apache.commons.math3.geometry.partitioning.BSPTreeVisitor; +37 import org.apache.commons.math3.geometry.partitioning.BoundaryAttribute; +38 import org.apache.commons.math3.geometry.partitioning.Hyperplane; +39 import org.apache.commons.math3.geometry.partitioning.Region; +40 import org.apache.commons.math3.geometry.partitioning.RegionFactory; +41 import org.apache.commons.math3.geometry.partitioning.SubHyperplane; +42 import org.apache.commons.math3.geometry.partitioning.Transform; +43 import org.apache.commons.math3.util.FastMath; +44 +45 /** This class represents a 3D region: a set of polyhedrons. +46 * @since 3.0 +47 */ +48 public class PolyhedronsSet extends AbstractRegion<Euclidean3D, Euclidean2D> { +49 +50 /** Default value for tolerance. */ +51 private static final double DEFAULT_TOLERANCE = 1.0e-10; +52 +53 /** Build a polyhedrons set representing the whole real line. +54 * @param tolerance tolerance below which points are considered identical +55 * @since 3.3 +56 */ +57 public PolyhedronsSet(final double tolerance) { +58 super(tolerance); +59 } +60 +61 /** Build a polyhedrons set from a BSP tree. +62 * <p>The leaf nodes of the BSP tree <em>must</em> have a +63 * {@code Boolean} attribute representing the inside status of +64 * the corresponding cell (true for inside cells, false for outside +65 * cells). In order to avoid building too many small objects, it is +66 * recommended to use the predefined constants +67 * {@code Boolean.TRUE} and {@code Boolean.FALSE}</p> +68 * <p> +69 * This constructor is aimed at expert use, as building the tree may +70 * be a difficult task. It is not intended for general use and for +71 * performances reasons does not check thoroughly its input, as this would +72 * require walking the full tree each time. Failing to provide a tree with +73 * the proper attributes, <em>will</em> therefore generate problems like +74 * {@link NullPointerException} or {@link ClassCastException} only later on. +75 * This limitation is known and explains why this constructor is for expert +76 * use only. The caller does have the responsibility to provided correct arguments. +77 * </p> +78 * @param tree inside/outside BSP tree representing the region +79 * @param tolerance tolerance below which points are considered identical +80 * @since 3.3 +81 */ +82 public PolyhedronsSet(final BSPTree<Euclidean3D> tree, final double tolerance) { +83 super(tree, tolerance); +84 } +85 +86 /** Build a polyhedrons set from a Boundary REPresentation (B-rep) specified by sub-hyperplanes. +87 * <p>The boundary is provided as a collection of {@link +88 * SubHyperplane sub-hyperplanes}. Each sub-hyperplane has the +89 * interior part of the region on its minus side and the exterior on +90 * its plus side.</p> +91 * <p>The boundary elements can be in any order, and can form +92 * several non-connected sets (like for example polyhedrons with holes +93 * or a set of disjoint polyhedrons considered as a whole). In +94 * fact, the elements do not even need to be connected together +95 * (their topological connections are not used here). However, if the +96 * boundary does not really separate an inside open from an outside +97 * open (open having here its topological meaning), then subsequent +98 * calls to the {@link Region#checkPoint(Point) checkPoint} method will +99 * not be meaningful anymore.</p> +100 * <p>If the boundary is empty, the region will represent the whole +101 * space.</p> +102 * @param boundary collection of boundary elements, as a +103 * collection of {@link SubHyperplane SubHyperplane} objects +104 * @param tolerance tolerance below which points are considered identical +105 * @since 3.3 +106 */ +107 public PolyhedronsSet(final Collection<SubHyperplane<Euclidean3D>> boundary, +108 final double tolerance) { +109 super(boundary, tolerance); +110 } +111 +112 /** Build a polyhedrons set from a Boundary REPresentation (B-rep) specified by connected vertices. +113 * <p> +114 * The boundary is provided as a list of vertices and a list of facets. +115 * Each facet is specified as an integer array containing the arrays vertices +116 * indices in the vertices list. Each facet normal is oriented by right hand +117 * rule to the facet vertices list. +118 * </p> +119 * <p> +120 * Some basic sanity checks are performed but not everything is thoroughly +121 * assessed, so it remains under caller responsibility to ensure the vertices +122 * and facets are consistent and properly define a polyhedrons set. +123 * </p> +124 * @param vertices list of polyhedrons set vertices +125 * @param facets list of facets, as vertices indices in the vertices list +126 * @param tolerance tolerance below which points are considered identical +127 * @exception MathIllegalArgumentException if some basic sanity checks fail +128 * @since 3.5 +129 */ +130 public PolyhedronsSet(final List<Vector3D> vertices, final List<int[]> facets, +131 final double tolerance) { +132 super(buildBoundary(vertices, facets, tolerance), tolerance); +133 } +134 +135 /** Build a parallellepipedic box. +136 * @param xMin low bound along the x direction +137 * @param xMax high bound along the x direction +138 * @param yMin low bound along the y direction +139 * @param yMax high bound along the y direction +140 * @param zMin low bound along the z direction +141 * @param zMax high bound along the z direction +142 * @param tolerance tolerance below which points are considered identical +143 * @since 3.3 +144 */ +145 public PolyhedronsSet(final double xMin, final double xMax, +146 final double yMin, final double yMax, +147 final double zMin, final double zMax, +148 final double tolerance) { +149 super(buildBoundary(xMin, xMax, yMin, yMax, zMin, zMax, tolerance), tolerance); +150 } +151 +152 /** Build a polyhedrons set representing the whole real line. +153 * @deprecated as of 3.3, replaced with {@link #PolyhedronsSet(double)} +154 */ +155 @Deprecated +156 public PolyhedronsSet() { +157 this(DEFAULT_TOLERANCE); +158 } +159 +160 /** Build a polyhedrons set from a BSP tree. +161 * <p>The leaf nodes of the BSP tree <em>must</em> have a +162 * {@code Boolean} attribute representing the inside status of +163 * the corresponding cell (true for inside cells, false for outside +164 * cells). In order to avoid building too many small objects, it is +165 * recommended to use the predefined constants +166 * {@code Boolean.TRUE} and {@code Boolean.FALSE}</p> +167 * @param tree inside/outside BSP tree representing the region +168 * @deprecated as of 3.3, replaced with {@link #PolyhedronsSet(BSPTree, double)} +169 */ +170 @Deprecated +171 public PolyhedronsSet(final BSPTree<Euclidean3D> tree) { +172 this(tree, DEFAULT_TOLERANCE); +173 } +174 +175 /** Build a polyhedrons set from a Boundary REPresentation (B-rep). +176 * <p>The boundary is provided as a collection of {@link +177 * SubHyperplane sub-hyperplanes}. Each sub-hyperplane has the +178 * interior part of the region on its minus side and the exterior on +179 * its plus side.</p> +180 * <p>The boundary elements can be in any order, and can form +181 * several non-connected sets (like for example polyhedrons with holes +182 * or a set of disjoint polyhedrons considered as a whole). In +183 * fact, the elements do not even need to be connected together +184 * (their topological connections are not used here). However, if the +185 * boundary does not really separate an inside open from an outside +186 * open (open having here its topological meaning), then subsequent +187 * calls to the {@link Region#checkPoint(Point) checkPoint} method will +188 * not be meaningful anymore.</p> +189 * <p>If the boundary is empty, the region will represent the whole +190 * space.</p> +191 * @param boundary collection of boundary elements, as a +192 * collection of {@link SubHyperplane SubHyperplane} objects +193 * @deprecated as of 3.3, replaced with {@link #PolyhedronsSet(Collection, double)} +194 */ +195 @Deprecated +196 public PolyhedronsSet(final Collection<SubHyperplane<Euclidean3D>> boundary) { +197 this(boundary, DEFAULT_TOLERANCE); +198 } +199 +200 /** Build a parallellepipedic box. +201 * @param xMin low bound along the x direction +202 * @param xMax high bound along the x direction +203 * @param yMin low bound along the y direction +204 * @param yMax high bound along the y direction +205 * @param zMin low bound along the z direction +206 * @param zMax high bound along the z direction +207 * @deprecated as of 3.3, replaced with {@link #PolyhedronsSet(double, double, +208 * double, double, double, double, double)} +209 */ +210 @Deprecated +211 public PolyhedronsSet(final double xMin, final double xMax, +212 final double yMin, final double yMax, +213 final double zMin, final double zMax) { +214 this(xMin, xMax, yMin, yMax, zMin, zMax, DEFAULT_TOLERANCE); +215 } +216 +217 /** Build a parallellepipedic box boundary. +218 * @param xMin low bound along the x direction +219 * @param xMax high bound along the x direction +220 * @param yMin low bound along the y direction +221 * @param yMax high bound along the y direction +222 * @param zMin low bound along the z direction +223 * @param zMax high bound along the z direction +224 * @param tolerance tolerance below which points are considered identical +225 * @return boundary tree +226 * @since 3.3 +227 */ +228 private static BSPTree<Euclidean3D> buildBoundary(final double xMin, final double xMax, +229 final double yMin, final double yMax, +230 final double zMin, final double zMax, +231 final double tolerance) { +232 if ((xMin >= xMax - tolerance) || (yMin >= yMax - tolerance) || (zMin >= zMax - tolerance)) { +233 // too thin box, build an empty polygons set +234 return new BSPTree<Euclidean3D>(Boolean.FALSE); +235 } +236 final Plane pxMin = new Plane(new Vector3D(xMin, 0, 0), Vector3D.MINUS_I, tolerance); +237 final Plane pxMax = new Plane(new Vector3D(xMax, 0, 0), Vector3D.PLUS_I, tolerance); +238 final Plane pyMin = new Plane(new Vector3D(0, yMin, 0), Vector3D.MINUS_J, tolerance); +239 final Plane pyMax = new Plane(new Vector3D(0, yMax, 0), Vector3D.PLUS_J, tolerance); +240 final Plane pzMin = new Plane(new Vector3D(0, 0, zMin), Vector3D.MINUS_K, tolerance); +241 final Plane pzMax = new Plane(new Vector3D(0, 0, zMax), Vector3D.PLUS_K, tolerance); +242 @SuppressWarnings("unchecked") +243 final Region<Euclidean3D> boundary = +244 new RegionFactory<Euclidean3D>().buildConvex(pxMin, pxMax, pyMin, pyMax, pzMin, pzMax); +245 return boundary.getTree(false); +246 } +247 +248 /** Build boundary from vertices and facets. +249 * @param vertices list of polyhedrons set vertices +250 * @param facets list of facets, as vertices indices in the vertices list +251 * @param tolerance tolerance below which points are considered identical +252 * @return boundary as a list of sub-hyperplanes +253 * @exception MathIllegalArgumentException if some basic sanity checks fail +254 * @since 3.5 +255 */ +256 private static List<SubHyperplane<Euclidean3D>> buildBoundary(final List<Vector3D> vertices, +257 final List<int[]> facets, +258 final double tolerance) { +259 +260 // check vertices distances +261 for (int i = 0; i < vertices.size() - 1; ++i) { +262 final Vector3D vi = vertices.get(i); +263 for (int j = i + 1; j < vertices.size(); ++j) { +264 if (Vector3D.distance(vi, vertices.get(j)) <= tolerance) { +265 throw new MathIllegalArgumentException(LocalizedFormats.CLOSE_VERTICES, +266 vi.getX(), vi.getY(), vi.getZ()); +267 } 268 } 269 } 270 -271 /** {@inheritDoc} */ -272 public void visitLeafNode(final BSPTree<Euclidean3D> node) { -273 } -274 -275 /** Add he contribution of a boundary facet. -276 * @param facet boundary facet -277 * @param reversed if true, the facet has the inside on its plus side -278 */ -279 private void addContribution(final SubHyperplane<Euclidean3D> facet, final boolean reversed) { +271 // find how vertices are referenced by facets +272 final int[][] references = findReferences(vertices, facets); +273 +274 // find how vertices are linked together by edges along the facets they belong to +275 final int[][] successors = successors(vertices, facets, references); +276 +277 // check edges orientations +278 for (int vA = 0; vA < vertices.size(); ++vA) { +279 for (final int vB : successors[vA]) { 280 -281 final Region<Euclidean2D> polygon = ((SubPlane) facet).getRemainingRegion(); -282 final double area = polygon.getSize(); -283 -284 if (Double.isInfinite(area)) { -285 setSize(Double.POSITIVE_INFINITY); -286 setBarycenter((Point<Euclidean3D>) Vector3D.NaN); -287 } else { -288 -289 final Plane plane = (Plane) facet.getHyperplane(); -290 final Vector3D facetB = plane.toSpace(polygon.getBarycenter()); -291 double scaled = area * facetB.dotProduct(plane.getNormal()); -292 if (reversed) { -293 scaled = -scaled; -294 } -295 -296 setSize(getSize() + scaled); -297 setBarycenter((Point<Euclidean3D>) new Vector3D(1.0, (Vector3D) getBarycenter(), scaled, facetB)); +281 if (vB >= 0) { +282 // when facets are properly oriented, if vB is the successor of vA on facet f1, +283 // then there must be an adjacent facet f2 where vA is the successor of vB +284 boolean found = false; +285 for (final int v : successors[vB]) { +286 found = found || (v == vA); +287 } +288 if (!found) { +289 final Vector3D start = vertices.get(vA); +290 final Vector3D end = vertices.get(vB); +291 throw new MathIllegalArgumentException(LocalizedFormats.EDGE_CONNECTED_TO_ONE_FACET, [... 678 lines stripped ...]