1
2
3
4
5
6
7
8
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
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
188 this.paint(graphics, observer);
189
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 }