/* * $Id$ * This file is a part of the Arakhne Foundation Classes, http://www.arakhne.org/afc * * Copyright (c) 2000-2012 Stephane GALLAND. * Copyright (c) 2005-10, Multiagent Team, Laboratoire Systemes et Transports, * Universite de Technologie de Belfort-Montbeliard. * Copyright (c) 2013-2016 The original authors, and other authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.arakhne.afc.math.geometry.d3.afp; import org.eclipse.xtext.xbase.lib.Pure; import org.arakhne.afc.math.geometry.d3.Point3D; import org.arakhne.afc.math.geometry.d3.Vector3D; import org.arakhne.afc.vmutil.asserts.AssertMessages; /** * Base class for Prisms. Only rectangular prism * are considered here. * * @param <ST> is the type of the general implementation. * @param <IT> is the type of the implementation of this shape. * @param <IE> is the type of the path elements. * @param <P> is the type of the points. * @param <V> is the type of the vectors. * @param <B> is the type of the bounding boxes. * @author $Author: tpiotrow$ * @author $Author: sgalland$ * @version $FullVersion$ * @mavengroupid $GroupId$ * @mavenartifactid $ArtifactId$ */ public interface Prism3afp< ST extends Shape3afp<?, ?, IE, P, V, B>, IT extends Prism3afp<?, ?, IE, P, V, B>, IE extends PathElement3afp, P extends Point3D<? super P, ? super V>, V extends Vector3D<? super V, ? super P>, B extends RectangularPrism3afp<?, ?, IE, P, V, B>> extends Shape3afp<ST, IT, IE, P, V, B> { @Override default void toBoundingBox(B box) { assert box != null : AssertMessages.notNullParameter(); box.setFromCorners(getMinX(), getMinY(), getMinZ(), getMaxX(), getMaxY(), getMaxZ()); } @Override default void clear() { setFromCorners(0, 0, 0, 0, 0, 0); } /** Change the frame of the prism. * * @param x x coordinate of the lower front corner of the prism. * @param y y coordinate of the lower front corner of the prism. * @param z z coordinate of the lower front corner of the prism. * @param width width of the prism. * @param height height of the prism. * @param depth depth of the prism. */ @SuppressWarnings("checkstyle:magicnumber") default void set(double x, double y, double z, double width, double height, double depth) { assert width >= 0. : AssertMessages.positiveOrZeroParameter(3); assert height >= 0. : AssertMessages.positiveOrZeroParameter(4); assert depth >= 0. : AssertMessages.positiveOrZeroParameter(5); setFromCorners(x, y, z, x + width, y + height, z + depth); } /** Change the frame of the prism. * * @param min is the min corner of the rectangular prism. * @param max is the max corner of the rectangular prism. */ default void set(Point3D<?, ?> min, Point3D<?, ?> max) { assert min != null : AssertMessages.notNullParameter(0); assert max != null : AssertMessages.notNullParameter(1); setFromCorners(min.getX(), min.getY(), min.getZ(), max.getX(), max.getY(), max.getZ()); } @Override default void set(IT shape) { assert shape != null : AssertMessages.notNullParameter(); setFromCorners(shape.getMinX(), shape.getMinY(), shape.getMinZ(), shape.getMaxX(), shape.getMaxY(), shape.getMaxZ()); } /** Change the width of the prism, not the min corner. * * @param width the width of the prism. */ default void setWidth(double width) { assert width >= 0. : AssertMessages.positiveOrZeroParameter(); setMaxX(getMinX() + width); } /** Change the height of the prism, not the min corner. * * @param height the heigth of the prism. */ default void setHeight(double height) { assert height >= 0. : AssertMessages.positiveOrZeroParameter(); setMaxY(getMinY() + height); } /** Change the depth of the prism, not the min corner. * * @param depth the depth of the prism */ default void setDepth(double depth) { assert depth >= 0. : AssertMessages.positiveOrZeroParameter(); setMaxZ(getMinZ() + depth); } /** Change the frame of the rectangular prism conserving previous min and max if needed. * * @param x1 is the coordinate of the first corner. * @param y1 is the coordinate of the first corner. * @param z1 is the coordinate of the first corner. * @param x2 is the coordinate of the second corner. * @param y2 is the coordinate of the second corner. * @param z2 is the coordinate of the second corner. */ // This function has no default implementation for allowing implementation to be atomic. void setFromCorners(double x1, double y1, double z1, double x2, double y2, double z2); /** Change the frame of the rectangular prism conserving previous min and max if needed. * * @param p1 the first corner. * @param p2 the second corner. */ // This function has no default implementation for allowing implementation to be atomic. default void setFromCorners(Point3D<?, ?> p1, Point3D<?, ?> p2) { assert p1 != null : AssertMessages.notNullParameter(0); assert p2 != null : AssertMessages.notNullParameter(1); setFromCorners(p1.getX(), p1.getY(), p1.getZ(), p2.getX(), p2.getY(), p2.getZ()); } /** * Sets the framing rectangular prism of this <code>Shape</code> * based on the specified center point coordinates and corner point * coordinates. The framing rectangular prism is used by the subclasses of * <code>RectangularShape</code> to define their geometry. * * @param centerX the X coordinate of the specified center point * @param centerY the Y coordinate of the specified center point * @param centerZ the Z coordinate of the specified center point * @param cornerX the X coordinate of the specified corner point * @param cornerY the Y coordinate of the specified corner point * @param cornerZ the Z coordinate of the specified corner point */ default void setFromCenter(double centerX, double centerY, double centerZ, double cornerX, double cornerY, double cornerZ) { final double demiWidth = Math.abs(centerX - cornerX); final double demiHeight = Math.abs(centerY - cornerY); final double demiDepth = Math.abs(centerZ - cornerZ); setFromCorners(centerX - demiWidth, centerY - demiHeight, centerZ - demiDepth, centerX + demiWidth, centerY + demiHeight, centerZ - demiDepth); } /** * Sets the framing rectangular prism of this <code>Shape</code> * based on the specified center point coordinates and corner point * coordinates. The framing rectangular prism is used by the subclasses of * <code>RectangularShape</code> to define their geometry. * * @param center the specified center point * @param corner the specified corner point */ default void setFromCenter(Point3D<?, ?> center, Point3D<?, ?> corner) { assert center != null : AssertMessages.notNullParameter(0); assert corner != null : AssertMessages.notNullParameter(1); setFromCenter(center.getX(), center.getY(), center.getZ(), corner.getX(), corner.getY(), corner.getZ()); } /** Replies the min X. * * @return the min x. */ @Pure double getMinX(); /** Set the min X conserving previous min if needed. * * @param x the min x. */ void setMinX(double x); /** Replies the center x. * * @return the center x. */ @Pure default double getCenterX() { return (getMinX() + getMaxX()) / 2; } /** Replies the max x. * * @return the max x. */ @Pure double getMaxX(); /** Set the max X conserving previous max if needed. * * @param x the max x. */ void setMaxX(double x); /** Replies the min y. * * @return the min y. */ @Pure double getMinY(); /** Set the min Y conserving previous min if needed. * * @param y the min y. */ void setMinY(double y); /** Replies the center y. * * @return the center y. */ @Pure default double getCenterY() { return (getMinY() + getMaxY()) / 2; } /** Replies the max y. * * @return the max y. */ @Pure double getMaxY(); /** Set the max Y conserving previous max if needed. * * @param y the max y. */ void setMaxY(double y); /** Replies the min z. * * @return the min z. */ @Pure double getMinZ(); /** Set the min Z conserving previous min if needed. * * @param z the min z. */ void setMinZ(double z); /** Replies the center z. * * @return the center z. */ @Pure default double getCenterZ() { return (getMinZ() + getMaxZ()) / 2; } /** Replies the max z. * * @return the max z. */ @Pure double getMaxZ(); /** Set the max Z conserving previous max if needed. * * @param z the max z. */ void setMaxZ(double z); /** Replies the center. * * @return the center. */ default P getCenter() { return getGeomFactory().newPoint(getCenterX(), getCenterY(), getCenterZ()); } /** Set the center. * * @param cx the center x. * @param cy the center y. * @param cz the center z. */ default void setCenter(double cx, double cy, double cz) { setCenterX(cx); setCenterY(cy); setCenterZ(cz); } /** Set the center. * * @param center the center point. */ default void setCenter(Point3D<?, ?> center) { assert center != null : AssertMessages.notNullParameter(); setCenter(center.getX(), center.getY(), center.getZ()); } /** Set the center's x. * * @param cx the center x. */ default void setCenterX(double cx) { final double demiWidth = getWidth() / 2.; setMinX(cx - demiWidth); setMaxX(cx + demiWidth); } /** Set the center's y. * * @param cy the center y. */ default void setCenterY(double cy) { final double demiHeight = getHeight() / 2.; setMinY(cy - demiHeight); setMaxY(cy + demiHeight); } /** Set the center's z. * * @param cz the center z. */ default void setCenterZ(double cz) { final double demiDepth = getDepth() / 2.; setMinZ(cz - demiDepth); setMaxZ(cz + demiDepth); } /** Replies the width. * * @return the width. */ @Pure default double getWidth() { return getMaxX() - getMinX(); } /** Replies the height. * * @return the height. */ @Pure default double getHeight() { return getMaxY() - getMinY(); } /** Replies the depth. * * @return the depth. */ @Pure default double getDepth() { return getMaxZ() - getMinZ(); } @Override default void translate(double dx, double dy, double dz) { setFromCorners(getMinX() + dx, getMinY() + dy, getMinZ() + dz, getMaxX() + dx, getMaxY() + dy, getMaxZ() + dz); } @Pure @Override default boolean isEmpty() { return getMinX() == getMaxX() && getMinY() == getMaxY() && getMinZ() == getMaxZ(); } /** Inflate this rectangular prism with the given amounts. * * <p>All borders may be inflated. If the value associated to a border * is positive, the border is moved outside the current prism. * If the value is negative, the border is moved inside the prism. * * @param minXBorder the value to substract to the minimum x. * @param minYBorder the value to substract to the minimum y. * @param minZBorder the value to substract to the minimum z. * @param maxXBorder the value to add to the maximum x. * @param maxYBorder the value to add to the maximum y. * @param maxZBorder the value to add to the maximum z. */ default void inflate(double minXBorder, double minYBorder, double minZBorder, double maxXBorder, double maxYBorder, double maxZBorder) { setFromCorners( getMinX() - minXBorder, getMinY() - minYBorder, getMinZ() - minZBorder, getMaxX() + maxXBorder, getMaxY() + maxYBorder, getMaxZ() + maxZBorder); } }