EmbeddedTreeLineSubset3D.java

  1. /*
  2.  * Licensed to the Apache Software Foundation (ASF) under one or more
  3.  * contributor license agreements.  See the NOTICE file distributed with
  4.  * this work for additional information regarding copyright ownership.
  5.  * The ASF licenses this file to You under the Apache License, Version 2.0
  6.  * (the "License"); you may not use this file except in compliance with
  7.  * the License.  You may obtain a copy of the License at
  8.  *
  9.  *      http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */
  17. package org.apache.commons.geometry.euclidean.threed.line;

  18. import java.util.ArrayList;
  19. import java.util.List;

  20. import org.apache.commons.geometry.core.Transform;
  21. import org.apache.commons.geometry.euclidean.oned.Interval;
  22. import org.apache.commons.geometry.euclidean.oned.RegionBSPTree1D;
  23. import org.apache.commons.geometry.euclidean.oned.Vector1D;
  24. import org.apache.commons.geometry.euclidean.threed.Bounds3D;
  25. import org.apache.commons.geometry.euclidean.threed.Vector3D;
  26. import org.apache.commons.geometry.euclidean.threed.line.Line3D.SubspaceTransform;

  27. /** Class representing an arbitrary subset of a line in 3D Euclidean space using a
  28.  * {@link RegionBSPTree1D}. This class can represent convex, non-convex, finite,
  29.  * infinite, and empty regions.
  30.  *
  31.  * <p>This class is mutable and <em>not</em> thread safe.</p>
  32.  */
  33. public final class EmbeddedTreeLineSubset3D extends LineSubset3D {
  34.     /** The 1D region representing the area on the line. */
  35.     private final RegionBSPTree1D region;

  36.     /** Construct a new, empty subset for the given line.
  37.      * @param line line defining the subset
  38.      */
  39.     public EmbeddedTreeLineSubset3D(final Line3D line) {
  40.         this(line, false);
  41.     }

  42.     /** Construct a new subset for the given line. If {@code full}
  43.      * is true, then the subset will cover the entire line; otherwise,
  44.      * it will be empty.
  45.      * @param line line defining the subset
  46.      * @param full if true, the subset will cover the entire space;
  47.      *      otherwise it will be empty
  48.      */
  49.     public EmbeddedTreeLineSubset3D(final Line3D line, final boolean full) {
  50.         this(line, new RegionBSPTree1D(full));
  51.     }

  52.     /** Construct a new instance from its defining line and subspace region.
  53.      * @param line line defining the subset
  54.      * @param region subspace region for the subset
  55.      */
  56.     public EmbeddedTreeLineSubset3D(final Line3D line, final RegionBSPTree1D region) {
  57.         super(line);

  58.         this.region = region;
  59.     }

  60.     /** {@inheritDoc} */
  61.     @Override
  62.     public double getSize() {
  63.         return region.getSize();
  64.     }

  65.     /** {@inheritDoc} */
  66.     @Override
  67.     public RegionBSPTree1D getSubspaceRegion() {
  68.         return region;
  69.     }

  70.     /** {@inheritDoc} */
  71.     @Override
  72.     public Vector3D getCentroid() {
  73.         final Vector1D subcenter = region.getCentroid();
  74.         return subcenter != null ?
  75.                 getLine().toSpace(subcenter) :
  76.                 null;
  77.     }

  78.     /** {@inheritDoc} */
  79.     @Override
  80.     public Bounds3D getBounds() {
  81.         final double min = region.getMin();
  82.         final double max = region.getMax();

  83.         if (Double.isFinite(min) && Double.isFinite(max)) {
  84.             final Line3D line = getLine();

  85.             return Bounds3D.builder()
  86.                     .add(line.toSpace(min))
  87.                     .add(line.toSpace(max))
  88.                     .build();
  89.         }

  90.         return null;
  91.     }

  92.     /** Transform this instance.
  93.      * @param transform the transform to apply
  94.      * @return a new, transformed instance
  95.      */
  96.     public EmbeddedTreeLineSubset3D transform(final Transform<Vector3D> transform) {
  97.         final SubspaceTransform st = getLine().subspaceTransform(transform);

  98.         final RegionBSPTree1D tRegion = RegionBSPTree1D.empty();
  99.         tRegion.copy(region);
  100.         tRegion.transform(st.getTransform());

  101.         return new EmbeddedTreeLineSubset3D(st.getLine(), tRegion);
  102.     }

  103.     /** Return a list of {@link LineConvexSubset3D} instances representing the same region
  104.      * as this instance.
  105.      * @return a list of {@link LineConvexSubset3D} instances representing the same region
  106.      *      as this instance.
  107.      */
  108.     public List<LineConvexSubset3D> toConvex() {
  109.         final List<Interval> intervals = region.toIntervals();

  110.         final Line3D line = getLine();
  111.         final List<LineConvexSubset3D> convex = new ArrayList<>(intervals.size());

  112.         for (final Interval interval : intervals) {
  113.             convex.add(Lines3D.subsetFromInterval(line, interval));
  114.         }

  115.         return convex;
  116.     }

  117.     /** {@inheritDoc} */
  118.     @Override
  119.     public String toString() {
  120.         final Line3D line = getLine();

  121.         final StringBuilder sb = new StringBuilder();
  122.         sb.append(this.getClass().getSimpleName())
  123.             .append('[')
  124.             .append("lineOrigin= ")
  125.             .append(line.getOrigin())
  126.             .append(", lineDirection= ")
  127.             .append(line.getDirection())
  128.             .append(", region= ")
  129.             .append(region)
  130.             .append(']');

  131.         return sb.toString();
  132.     }
  133. }