/*- * Copyright 2020 Beuth Hochschule für Technik Berlin, Hochschule für Technik Stuttgart * * This file is part of CityDoctor2. * * CityDoctor2 is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * CityDoctor2 is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with CityDoctor2. If not, see . */ package de.hft.stuttgart.citydoctor2.datastructure; import java.util.List; import de.hft.stuttgart.citydoctor2.math.Vector3d; import de.hft.stuttgart.citydoctor2.utils.BoundingBoxCalculator; /** * An axis aligned bounding box represented by its two corners * * @author Matthias Betz * */ public class BoundingBox { private Vector3d[] bbox; /** * Creates an axis aligned bounding box containing all points of all polygons * * @param polygons containing the points from which the box will be created * @return the bounding box around all points */ public static BoundingBox of(List polygons) { return BoundingBoxCalculator.calculateBoundingBox(polygons); } public static BoundingBox ofPoints(List points) { return BoundingBoxCalculator.calculateBoundingBoxFromPoints(points); } /** * Creates an axis aligned bounding box of the whole model. * * @param model the model containing the features with geometries used for the * bounding box * @return the bounding box around all features */ public static BoundingBox of(CityDoctorModel model) { return BoundingBoxCalculator.calculateBoundingBox(model); } /** * Creates a new bounding box with two vectors as corner points. * * @param box the array of length 2 containing both corners * @return the new bounding box */ public static BoundingBox of(Vector3d[] box) { return new BoundingBox(box); } private BoundingBox(Vector3d[] bbox) { if (bbox == null || bbox.length != 2) { throw new IllegalArgumentException("BoundingBox must be an array of the length 2"); } this.bbox = bbox; } /** * Calculates the volume of the box * * @return the volume of the box */ public double getVolume() { double length = getDepth(); double width = getWidth(); double height = getHeight(); return height * width * length; } /** * Calculates the center of the bounding box * * @return the center of the bounding box */ public Vector3d getCenter() { return bbox[0].plus(bbox[1].minus(bbox[0]).mult(0.5)); } /** * Getter for the corner array * * @return the array containing the corner points */ public Vector3d[] getBox() { return bbox; } /** * Calculates the width of the bounding box * * @return the width of the bounding box */ public double getWidth() { return bbox[1].getY() - bbox[0].getY(); } /** * Calculates the height of the bounding box * * @return the height of the bounding box */ public double getHeight() { return bbox[1].getZ() - bbox[0].getZ(); } /** * Calculates the depth of the bounding box * * @return the depth of the bounding box */ public double getDepth() { return bbox[1].getX() - bbox[0].getX(); } /** * Returns the length of the longest side of the bounding box, ignoring the * height. Only X and Y axis are considered * * @return the length of the longest side in X or Y direction */ public double getLongestSide() { double width = getWidth(); double depth = getDepth(); if (width > depth) { return width; } else { return depth; } } /** * Calculates the direction vector from the lower corner to the upper corner * * @return the direction vector from the lower corner to the upper corner */ public Vector3d getDiagonal() { return bbox[1].minus(bbox[0]); } /** * Calculates the distance between the corner points * * @return the distance between the corner points */ public double getDiagonalLength() { return bbox[1].getDistance(bbox[0]); } }