nl.tudelft.simulation.dsol.animation.d2.BoundsUtil Maven / Gradle / Ivy
package nl.tudelft.simulation.dsol.animation.d2;
import org.djutils.draw.Oriented;
import org.djutils.draw.Transform2d;
import org.djutils.draw.Transform3d;
import org.djutils.draw.bounds.Bounds;
import org.djutils.draw.bounds.Bounds2d;
import org.djutils.draw.bounds.Bounds3d;
import org.djutils.draw.point.OrientedPoint2d;
import org.djutils.draw.point.OrientedPoint3d;
import org.djutils.draw.point.Point;
import org.djutils.draw.point.Point2d;
import org.djutils.draw.point.Point3d;
/**
* A Bounds3d utility class to help with finding intersections between bounds, to make transformations, and to see if a point
* lies within a bounds. The static methods can help in animation to see whether a shape needs to be drawn on the screen
* (3D-viewport) or not.
*
* Copyright (c) 2002-2024 Delft University of Technology, Jaffalaan 5, 2628 BX Delft, the Netherlands. All rights reserved. See
* for project information https://simulation.tudelft.nl. The DSOL
* project is distributed under a three-clause BSD-style license, which can be found at
*
* https://https://simulation.tudelft.nl/dsol/docs/latest/license.html.
*
* @author Peter Jacobs
*/
public final class BoundsUtil
{
/**
* constructs a new BoundsUtil.
*/
private BoundsUtil()
{
// unreachable code
}
/**
* Computes s new bounding box based on the projection of the original bounding box on the XY-plane, translated by the
* center point coordinates, and possibly rotated by the orientation of the center point.
* @param center Point; the point relative to which the bounds need to be calculated
* @param bounds Bounds; the bounds for which the intersection needs to be calculated. The Bounds3d are relative to the
* center that is provided
* @return Bounds2d the projected rectangle of the intersection, or null if there is no intersection
*/
public static Bounds2d projectBounds(final Point> center, final Bounds, ?, ?> bounds)
{
if (center == null)
{
return new Bounds2d(bounds.getMinX(), bounds.getMaxX(), bounds.getMinY(), bounds.getMaxY());
}
if (center instanceof Oriented)
{
Bounds2d b = new Bounds2d(bounds.getMinX(), bounds.getMaxX(), bounds.getMinY(), bounds.getMaxY());
Point2d c = new Point2d(center.getX(), center.getY());
Oriented> o = (Oriented>) center;
Transform2d transformation = new Transform2d();
transformation.translate(c);
transformation.rotation(o.getDirZ());
return transformation.transform(b);
}
return new Bounds2d(bounds.getMinX() + center.getX(), bounds.getMaxX() + center.getX(),
bounds.getMinY() + center.getY(), bounds.getMaxY() + center.getY());
}
/**
* Rotates and translates a bound relative to an oriented point. Often this point will be the given center point for the
* animation.
* @param center OrientedPoint3d; the point relative to which the bounds need to be transformed
* @param bounds Bounds3d; the bounds that need to be rotated and translated
* @return the bounds after rotation and translation
*/
public static Bounds3d transform(final OrientedPoint3d center, final Bounds3d bounds)
{
if (center == null)
{
return bounds;
}
Transform3d transform = new Transform3d();
transform.translate(center); // note: opposite order of how it should be carried out (!)
transform.rotX(center.getDirX());
transform.rotY(center.getDirY());
transform.rotZ(center.getDirZ());
return transform.transform(bounds);
}
/**
* Rotates and translates a bound relative to an oriented point. Often this point will be the given center point for the
* animation.
* @param center OrientedPoint2d; the point relative to which the bounds need to be transformed
* @param bounds Bound2ds; the bounds that need to be rotated and translated
* @return the bounds after rotation and translation
*/
public static Bounds2d transform(final OrientedPoint2d center, final Bounds2d bounds)
{
if (center == null)
{
return bounds;
}
Transform2d transform = new Transform2d();
transform.translate(center); // note: opposite order of how it should be carried out (!)
transform.rotation(center.getDirZ());
return transform.transform(bounds);
}
/**
* Check whether a point is in the bounds, after transforming the bounds relative to the center point (in animation that is
* the location). Usually the center is in the bounds, but that is not necessary. The center is in many occasions the
* Location of an animated object, and the bounds indicate the outer values of its animation without translation and
* rotation (as if center is 0,0,0) and has no direction (rotX, rotY and rotZ are 0.0).
* @param center OrientedPoint3d; the 'center' of the bounds.
* @param bounds Bounds3d; the bounds relative to 0,0,0
* @param point Point3d; the point that might be in or out of the bounds after they have been rotated and translated
* relative to the center.
* @return whether or not the point is in the bounds
*/
public static boolean contains(final OrientedPoint3d center, final Bounds3d bounds, final Point3d point)
{
if (center == null)
{
return false;
}
Transform3d transform = new Transform3d();
transform.translate(center);
transform.rotX(center.getDirX());
transform.rotY(center.getDirY());
transform.rotZ(center.getDirZ());
Bounds3d box = transform.transform(bounds);
return box.covers(point);
}
/**
* Check whether a point is in the bounds, after transforming the bounds relative to the center point (in animation that is
* the location). Usually the center is in the bounds, but that is not necessary. The center is in many occasions the
* Location of an animated object, and the bounds indicate the outer values of its animation without translation and
* rotation (as if center is 0,0) and has no direction (rotation 0.0).
* @param center OrientedPoint2d; the 'center' of the bounds.
* @param bounds Bounds2d; the bounds relative to 0,0
* @param point Point2d; the point that might be in or out of the bounds after they have been rotated and translated
* relative to the center.
* @return whether or not the point is in the bounds
*/
public static boolean contains(final OrientedPoint2d center, final Bounds2d bounds, final Point2d point)
{
if (center == null)
{
return false;
}
Transform2d transform = new Transform2d();
transform.translate(center);
transform.rotation(center.getDirZ());
Bounds2d box = transform.transform(bounds);
return box.covers(point);
}
}