View Javadoc

    1   /*
    2    * @(#) Renderable2D.java Nov 10, 2003
    3    *
    4    * Copyright (c) 2003 Delft University of Technology Jaffalaan 5, 2628 BX Delft,
    5    * the Netherlands All rights reserved.
    6    *
    7    * This software is proprietary information of Delft University of Technology
    8    * The code is published under the General Public License
    9    */
    10
    11  package nl.tudelft.simulation.dsol.animation.D2;
    12
    13  import java.awt.Dimension;
    14  import java.awt.Graphics2D;
    15  import java.awt.geom.Point2D;
    16  import java.awt.geom.Rectangle2D;
    17  import java.awt.image.ImageObserver;
    18  import java.rmi.RemoteException;
    19  import nl.tudelft.simulation.dsol.animation.LocatableInterface;
    20  import nl.tudelft.simulation.dsol.context.ContextUtil;
    21  import nl.tudelft.simulation.dsol.simulators.SimulatorInterface;
    22  import nl.tudelft.simulation.language.d2.Shape;
    23  import nl.tudelft.simulation.language.d3.BoundsUtil;
    24  import nl.tudelft.simulation.language.d3.DirectedPoint;
    25  import nl.tudelft.simulation.logger.Logger;
    26
    27  /***
    28   * The Renderable2D provides an easy accessible renderable object.
    29   * <p>
    30   * (c) copyright 2003 <a href="http://www.simulation.tudelft.nl">Delft
    31   * University of Technology </a>, the Netherlands. <br>
    32   * See for project information <a
    33   * href="http://www.simulation.tudelft.nl">www.simulation.tudelft.nl </a> <br>
    34   * License of use: <a href="http://www.gnu.org/copyleft/gpl.html">General Public
    35   * License (GPL) </a>, no warranty <br>
    36   *
    37   * @version 2.0 10.11.2003 <br>
    38   * @author <a href="http://www.tbm.tudelft.nl/webstaf/peterja/index.htm">Peter
    39   *         Jacobs </a>
    40   */
    41  public abstract class Renderable2D implements Renderable2DInterface
    42  {
    43  	/*** whether to rotate the renderable */
    44  	protected boolean rotate = true;
    45
    46  	/*** whether to flip the renderable after rotating 180 degrees */
    47  	protected boolean flip = false;
    48
    49  	/*** whether to scale the renderable when zooming in or out */
    50  	protected boolean scale = true;
    51
    52  	/*** whether to translate the renderable when panning */
    53  	protected boolean translate = true;
    54
    55  	/*** simulator */
    56  	protected SimulatorInterface simulator = null;
    57
    58  	/*** the source of the renderable */
    59  	protected LocatableInterface source = null;
    60
    61  	/***
    62  	 * constructs a new Renderable2D
    63  	 *
    64  	 * @param source the source
    65  	 * @param simulator the simulator
    66  	 */
    67  	public Renderable2D(final LocatableInterface source,
    68  			final SimulatorInterface simulator)
    69  	{
    70  		this.source = source;
    71  		this.simulator = simulator;
    72  		ContextUtil.bindToContext(simulator, "/animation/2D", this);
    73  	}
    74
    75  	/***
    76  	 * @return Returns the flip.
    77  	 */
    78  	public boolean isFlip()
    79  	{
    80  		return this.flip;
    81  	}
    82
    83  	/***
    84  	 * @param flip The flip to set.
    85  	 */
    86  	public void setFlip(final boolean flip)
    87  	{
    88  		this.flip = flip;
    89  	}
    90
    91  	/***
    92  	 * @return Returns the rotate.
    93  	 */
    94  	public boolean isRotate()
    95  	{
    96  		return this.rotate;
    97  	}
    98
    99  	/***
    100 	 * @param rotate The rotate to set.
    101 	 */
    102 	public void setRotate(final boolean rotate)
    103 	{
    104 		this.rotate = rotate;
    105 	}
    106
    107 	/***
    108 	 * @return Returns the scale.
    109 	 */
    110 	public boolean isScale()
    111 	{
    112 		return this.scale;
    113 	}
    114
    115 	/***
    116 	 * @param scale The scale to set.
    117 	 */
    118 	public void setScale(final boolean scale)
    119 	{
    120 		this.scale = scale;
    121 	}
    122
    123 	/***
    124 	 * @see nl.tudelft.simulation.dsol.animation.D2.Renderable2DInterface#getSource()
    125 	 */
    126 	public LocatableInterface getSource()
    127 	{
    128 		return this.source;
    129 	}
    130
    131 	/***
    132 	 * @return Returns the translate.
    133 	 */
    134 	public boolean isTranslate()
    135 	{
    136 		return this.translate;
    137 	}
    138
    139 	/***
    140 	 * @param translate The translate to set.
    141 	 */
    142 	public void setTranslate(final boolean translate)
    143 	{
    144 		this.translate = translate;
    145 	}
    146
    147 	/***
    148 	 * @see nl.tudelft.simulation.dsol.animation.D2.Renderable2DInterface
    149 	 *      #paint(Graphics2D, Rectangle2D, Dimension,ImageObserver)
    150 	 */
    151 	public synchronized void paint(final Graphics2D graphics,
    152 			final Rectangle2D extent, final Dimension screen,
    153 			final ImageObserver observer)
    154 	{
    155 		try
    156 		{
    157 			DirectedPoint location = this.source.getLocation();
    158 			Rectangle2D rectangle = BoundsUtil.getIntersect(this.source
    159 					.getLocation(), this.source.getBounds(), location.z);
    160 			if (!Shape.overlaps(extent, rectangle) && this.translate)
    161 			{
    162 				return;
    163 			}
    164 			Point2D screenCoordinates = Renderable2DInterface.Util
    165 					.getScreenCoordinates(this.source.getLocation().to2D(),
    166 							extent, screen);
    167 			//Let's transform
    168 			if (this.translate)
    169 			{
    170 				graphics.translate(screenCoordinates.getX(), screenCoordinates
    171 						.getY());
    172 			}
    173 			double scale = Renderable2DInterface.Util.getScale(extent, screen);
    174 			if (this.scale)
    175 			{
    176 				graphics.scale(1.0 / scale, 1.0 / scale);
    177 			}
    178 			double angle = -location.getRotZ();
    179 			if (this.flip && angle > Math.PI)
    180 			{
    181 				angle = angle - Math.PI;
    182 			}
    183 			if (this.rotate && angle != 0.0)
    184 			{
    185 				graphics.rotate(angle);
    186 			}
    187 			//Now we paint
    188 			this.paint(graphics, observer);
    189 			//Let's untransform
    190 			if (this.rotate && angle != 0.0)
    191 			{
    192 				graphics.rotate(-angle);
    193 			}
    194 			if (this.scale)
    195 			{
    196 				graphics.scale(scale, scale);
    197 			}
    198 			if (this.translate)
    199 			{
    200 				graphics.translate(-screenCoordinates.getX(),
    201 						-screenCoordinates.getY());
    202 			}
    203 		} catch (Exception exception)
    204 		{
    205 			Logger.warning(this, "paint", exception);
    206 		}
    207 	}
    208
    209 	/***
    210 	 * @see nl.tudelft.simulation.dsol.animation.D2.Renderable2DInterface
    211 	 *      #contains(java.awt.geom.Point2D, java.awt.geom.Rectangle2D,
    212 	 *      java.awt.Dimension)
    213 	 */
    214 	public boolean contains(final Point2D pointWorldCoordinates,
    215 			final Rectangle2D extent, final Dimension screen)
    216 	{
    217 		try
    218 		{
    219 			Rectangle2D intersect = BoundsUtil.getIntersect(this.source
    220 					.getLocation(), this.source.getBounds(), this.source
    221 					.getLocation().z);
    222 			if (intersect == null)
    223 			{
    224 				throw new NullPointerException(
    225 						"empty intersect!: location.z is not in bounds. This is probably due to a modeling error. See the javadoc off LocatableInterface.");
    226 			}
    227 			return intersect.contains(pointWorldCoordinates);
    228 		} catch (RemoteException exception)
    229 		{
    230 			Logger.warning(this, "contains", exception);
    231 			return false;
    232 		}
    233 	}
    234
    235 	/***
    236 	 * destroys an RenderableObject by unsubscribing it from the context.
    237 	 */
    238 	public void destroy()
    239 	{
    240 		try
    241 		{
    242 			nl.tudelft.simulation.naming.context.ContextUtil
    243 					.unbindFromContext(this);
    244 		} catch (Throwable throwable)
    245 		{
    246 			Logger.warning(this, "finalize", throwable);
    247 		}
    248 	}
    249
    250 	/***
    251 	 * @see java.lang.Object#toString()
    252 	 */
    253 	public String toString()
    254 	{
    255 		if (this != this.source)
    256 		{
    257 			return super.toString() + "-OF-" + this.source.toString();
    258 		}
    259 		return super.toString() + "-OF-" + super.toString();
    260 	}
    261
    262 	/***
    263 	 * draws an animation on a worldcoordinates around [x,y=0,0]
    264 	 *
    265 	 * @param graphics the graphics object
    266 	 * @param observer the observer
    267 	 * @throws RemoteException on network exception
    268 	 */
    269 	public abstract void paint(final Graphics2D graphics,
    270 			final ImageObserver observer) throws RemoteException;
    271 }