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 }