Renderable2dInterface.java
package nl.tudelft.simulation.dsol.animation.d2;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.geom.Point2D;
import java.awt.image.ImageObserver;
import java.util.concurrent.atomic.AtomicInteger;
import javax.naming.NamingException;
import org.djutils.draw.bounds.Bounds2d;
import org.djutils.draw.point.Point2d;
import nl.tudelft.simulation.dsol.animation.Locatable;
import nl.tudelft.simulation.naming.context.Contextualized;
/**
* The Renderable2d interface defines the basic interface for 2d animation. This is a hard-to-use interface. It is implemented
* by the easy-to-use Renderable2d class.
* <p>
* Copyright (c) 2002-2025 Delft University of Technology, Jaffalaan 5, 2628 BX Delft, the Netherlands. All rights reserved. See
* for project information <a href="https://simulation.tudelft.nl/dsol/manual/" target="_blank">DSOL Manual</a>. The DSOL
* project is distributed under a three-clause BSD-style license, which can be found at
* <a href="https://simulation.tudelft.nl/dsol/docs/latest/license.html" target="_blank">DSOL License</a>.
* </p>
* @author <a href="https://www.linkedin.com/in/peterhmjacobs">Peter Jacobs </a>
* @param <L> the Locatable class of the source that indicates the location of the Renderable on the screen
*/
public interface Renderable2dInterface<L extends Locatable>
{
/** the object number counter for a unique id. */
AtomicInteger ANIMATION_OBJECT_COUNTER = new AtomicInteger(0);
/** whether to scale the X/Y-value with the value of RenderableScale.OnjectScaleFactor. Flag is 0010 0000 */
byte SCALE_OBJECT_FLAG = 0x20;
/** whether to scale the Y-value in case of a compressed Y-axis. Flag is 0001 0000 */
byte SCALE_Y_FLAG = 0x10;
/** whether to rotate the renderable. Flag is 0000 1000 */
byte ROTATE_FLAG = 0x08;
/** whether to flip the renderable after rotating 180 degrees. Flag is 0000 0100 */
byte FLIP_FLAG = 0x04;
/** whether to scale the renderable when zooming in or out. Flag is 0000 0010 */
byte SCALE_FLAG = 0x02;
/** whether to translate the renderable when panning. Flag is 0000 0001 */
byte TRANSLATE_FLAG = 0x01;
/**
* the overarching method that is called when painting, usually redirecting to paint(...) but possibly retrieving the
* drawing from a cache.
* @param graphics the graphics object
* @param extent the extent of the panel
* @param screenSize the screen of the panel
* @param renderableScale the scale to use (usually RenderableScaleDefault where X/Y ratio is 1)
* @param observer the observer of the renderableInterface
*/
void paintComponent(Graphics2D graphics, Bounds2d extent, Dimension screenSize, RenderableScale renderableScale,
ImageObserver observer);
/**
* gets the source of this renderable.
* @return Locatable the source
*/
L getSource();
/**
* This method determines whether the shape drawn on the screen (rotated, zoomed, translated) contain the point that is
* provided in world coordinates. The default implementation is to project the bounds of the object on the XY-plane, and
* return the intersection with the given point (x,y) in world coordinates. Note that the bounds of the object are given in
* world coordinates, and are relative to point (0,0,0).
* @param pointWorldCoordinates the point in world coordinates.
* @param extent the extent of the viewport that is visible on the screen, in world coordinates
* @return whether the point is in the shape
*/
boolean contains(Point2d pointWorldCoordinates, Bounds2d extent);
/**
* This method determines whether the shape drawn on the screen (rotated, zoomed, translated) contain the provided point
* that is provided in screen coordinates (e.g., the position of a mouse click on the screen).
* @param pointScreenCoordinates the point in screen coordinates, e.g. from a mouse event; note that the point is given in
* AWT/Swing coordinates, so as a `Point2D` and not a `Point2d`
* @param extent the extent of the viewport that is visible on the screen, in world coordinates
* @param screenSize the dimensions of the screen, in screen coordinates
* @param scale the current zoom factor of the screen, as well as the y-scale ratio
* @param worldMargin the margin to apply 'around' the object, in screen coordinates at a zoom level of 1, which is the same
* as world coordinates. This allows for a smaller or larger 'click box', since it is allowed for margin to be
* negative. This margin grows and shrinks in absolute sense withe the zoom factor.
* @param pixelMargin the number of pixels around the drawn object for contains to be 'true'. This guarantees that a mouse
* click can be pointed to a very small object.
* @return whether the point is in the shape or in a margin around the shape
*/
boolean contains(Point2D pointScreenCoordinates, Bounds2d extent, Dimension screenSize, RenderableScale scale,
double worldMargin, double pixelMargin);
/**
* destroys this editable. How to do this must be implemented by the modeler.
* @param contextProvider the object that can provide the context to bind and unbind the animation objects
* @throws NamingException when there is a problem retrieving the animation object from the Context
*/
void destroy(Contextualized contextProvider) throws NamingException;
/**
* return the id of the renderable component.
* @return the id of the renderable component
*/
int getId();
/**
* Return whether to flip the renderable, if the direction is 'left' or not.
* @return whether to flip the renderable, if the direction is 'left' or not
*/
boolean isFlip();
/**
* Set whether to flip the renderable, if the direction is 'left' or not.
* @param flip whether to flip the renderable, if the direction is 'left' or not
*/
void setFlip(boolean flip);
/**
* Return whether to rotate the renderable or not.
* @return whether to rotate the renderable or not
*/
boolean isRotate();
/**
* Set whether to rotate the renderable or not.
* @param rotate whether to rotate the renderable or not
*/
void setRotate(boolean rotate);
/**
* Return whether to scale the renderable or not.
* @return whether to scale the renderable or not
*/
boolean isScale();
/**
* Set whether to scale the renderable or not.
* @param scale whether to scale the renderable or not
*/
void setScale(boolean scale);
/**
* Return whether to scale the renderable in the Y-direction when there is a compressed Y-axis or not.
* @return whether to scale the renderable in the Y-direction when there is a compressed Y-axis or not
*/
boolean isScaleY();
/**
* Set whether to scale the renderable in the Y-direction when there is a compressed Y-axis or not.
* @param scaleY whether to scale the renderable in the Y-direction when there is a compressed Y-axis or not
*/
void setScaleY(boolean scaleY);
/**
* Return whether to scale the renderable in the X/Y-direction with the value of RenderableScale.objectScaleFactor or not.
* @return whether to scale the renderable in the X/Y-direction with the value of RenderableScale.objectScaleFactor or not
*/
boolean isScaleObject();
/**
* Set whether to scale the renderable in the X/Y-direction with the value of RenderableScale.objectScaleFactor or not.
* @param scaleY whether to scale the renderable in the X/Y-direction with the value of RenderableScale.objectScaleFactor or
* not
*/
void setScaleObject(boolean scaleY);
/**
* Return whether to translate the renderable to its position or not (false means absolute position).
* @return whether to translate the renderable to its position or not (false means absolute position)
*/
boolean isTranslate();
/**
* Set whether to translate the renderable to its position or not (false means absolute position).
* @param translate whether to translate the renderable to its position or not (false means absolute position)
*/
void setTranslate(boolean translate);
}