/*-
* 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 extends Vector3d> 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]);
}
}