1 package org.opentrafficsim.graphs;
2
3 import static org.junit.Assert.assertEquals;
4 import static org.junit.Assert.assertFalse;
5 import static org.junit.Assert.assertTrue;
6 import static org.junit.Assert.fail;
7
8 import java.awt.Component;
9 import java.awt.Container;
10 import java.awt.event.ActionEvent;
11 import java.awt.event.MouseListener;
12 import java.util.ArrayList;
13 import java.util.HashSet;
14 import java.util.List;
15 import java.util.Set;
16
17 import javax.swing.JLabel;
18 import javax.swing.JOptionPane;
19
20 import nl.tudelft.simulation.dsol.SimRuntimeException;
21 import nl.tudelft.simulation.dsol.simulators.SimulatorInterface;
22
23 import org.djunits.unit.AccelerationUnit;
24 import org.djunits.unit.LengthUnit;
25 import org.djunits.unit.TimeUnit;
26 import org.djunits.unit.UNITS;
27 import org.djunits.value.vdouble.scalar.Acceleration;
28 import org.djunits.value.vdouble.scalar.DoubleScalar;
29 import org.djunits.value.vdouble.scalar.Duration;
30 import org.djunits.value.vdouble.scalar.Length;
31 import org.djunits.value.vdouble.scalar.Speed;
32 import org.djunits.value.vdouble.scalar.Time;
33 import org.jfree.chart.ChartPanel;
34 import org.jfree.data.DomainOrder;
35 import org.junit.Test;
36 import org.opentrafficsim.core.dsol.OTSModelInterface;
37 import org.opentrafficsim.core.dsol.OTSSimTimeDouble;
38 import org.opentrafficsim.core.geometry.OTSPoint3D;
39 import org.opentrafficsim.core.gtu.GTUType;
40 import org.opentrafficsim.core.gtu.behavioralcharacteristics.ParameterTypes;
41 import org.opentrafficsim.core.network.LongitudinalDirectionality;
42 import org.opentrafficsim.core.network.OTSNetwork;
43 import org.opentrafficsim.core.network.OTSNode;
44 import org.opentrafficsim.road.car.CarTest;
45 import org.opentrafficsim.road.gtu.lane.LaneBasedIndividualGTU;
46 import org.opentrafficsim.road.gtu.lane.tactical.following.FixedAccelerationModel;
47 import org.opentrafficsim.road.gtu.lane.tactical.following.SequentialFixedAccelerationModel;
48 import org.opentrafficsim.road.gtu.lane.tactical.lanechangemobil.Egoistic;
49 import org.opentrafficsim.road.gtu.lane.tactical.lanechangemobil.LaneChangeModel;
50 import org.opentrafficsim.road.network.factory.LaneFactory;
51 import org.opentrafficsim.road.network.lane.Lane;
52 import org.opentrafficsim.road.network.lane.LaneType;
53 import org.opentrafficsim.simulationengine.SimpleSimulator;
54
55
56
57
58
59
60
61
62
63
64
65 public class ContourPlotTest implements UNITS
66 {
67
68
69
70
71
72
73
74 private List<Lane> dummyPath(final LaneType laneType, final GTUType gtuType) throws Exception
75 {
76 OTSNode b = new OTSNode("B", new OTSPoint3D(12345, 0, 0));
77 ArrayList<Lane> result = new ArrayList<Lane>();
78 Lane[] lanes =
79 LaneFactory.makeMultiLane("AtoB", new OTSNode("A", new OTSPoint3D(1234, 0, 0)), b, null, 1, laneType,
80 new Speed(100, KM_PER_HOUR), null, LongitudinalDirectionality.DIR_PLUS);
81 result.add(lanes[0]);
82
83 lanes =
84 LaneFactory.makeMultiLane("BtoC", b, new OTSNode("C", new OTSPoint3D(99999, 0, 0)), null, 1, laneType,
85 new Speed(100, KM_PER_HOUR), null, LongitudinalDirectionality.DIR_PLUS);
86
87
88 return result;
89 }
90
91
92
93
94
95 @SuppressWarnings("static-method")
96
97 public final void accelerationContourTest() throws Exception
98 {
99 GTUType gtuType = new GTUType("Car");
100 Set<GTUType> compatibility = new HashSet<GTUType>();
101 compatibility.add(gtuType);
102 LaneType laneType = new LaneType("CarLane", compatibility);
103 List<Lane> path = dummyPath(laneType, gtuType);
104 AccelerationContourPlot acp = new AccelerationContourPlot("Acceleration", path);
105 assertTrue("newly created AccelerationContourPlot should not be null", null != acp);
106 assertEquals("SeriesKey should be \"acceleration\"", "acceleration", acp.getSeriesKey(0));
107 standardContourTests(acp, path.get(0), gtuType, Double.NaN, 0);
108 }
109
110
111
112
113
114 @SuppressWarnings("static-method")
115
116 public final void densityContourTest() throws Exception
117 {
118 GTUType gtuType = new GTUType("Car");
119 Set<GTUType> compatibility = new HashSet<GTUType>();
120 compatibility.add(gtuType);
121 LaneType laneType = new LaneType("CarLane", compatibility);
122 List<Lane> path = dummyPath(laneType, gtuType);
123 DensityContourPlot dcp = new DensityContourPlot("Density", path);
124 assertTrue("newly created DensityContourPlot should not be null", null != dcp);
125 assertEquals("SeriesKey should be \"density\"", "density", dcp.getSeriesKey(0));
126 standardContourTests(dcp, path.get(0), gtuType, 0, Double.NaN);
127 }
128
129
130
131
132
133
134
135
136
137 static void printMatrix(ContourPlot cp, int fromX, int toX, int fromY, int toY)
138 {
139 System.out.println("Contour plot data:");
140 int maxItem = cp.getItemCount(0);
141 for (int y = fromY; y <= toY; y++)
142 {
143 System.out.print(String.format("y=%3d ", y));
144 for (int x = fromX; x <= toX; x++)
145 {
146
147 int item;
148 for (item = 0; item < maxItem; item++)
149 {
150 if (cp.getXValue(0, item) == x && cp.getYValue(0, item) == y)
151 {
152 break;
153 }
154 }
155 if (item < maxItem)
156 {
157 System.out.print(String.format("%10.6f", cp.getZValue(0, item)));
158 }
159 else
160 {
161 System.out.print(" -------- ");
162 }
163 }
164 System.out.println("");
165 }
166 System.out.print("");
167 }
168
169
170
171
172
173 @SuppressWarnings("static-method")
174
175 public final void flowContourTest() throws Exception
176 {
177 GTUType gtuType = new GTUType("Car");
178 Set<GTUType> compatibility = new HashSet<GTUType>();
179 compatibility.add(gtuType);
180 LaneType laneType = new LaneType("CarLane", compatibility);
181 List<Lane> path = dummyPath(laneType, gtuType);
182 FlowContourPlot fcp = new FlowContourPlot("Density", path);
183 assertTrue("newly created DensityContourPlot should not be null", null != fcp);
184 assertEquals("SeriesKey should be \"flow\"", "flow", fcp.getSeriesKey(0));
185 standardContourTests(fcp, path.get(0), gtuType, 0, Double.NaN);
186 }
187
188
189
190
191
192 @SuppressWarnings("static-method")
193
194 public final void speedContourTest() throws Exception
195 {
196 GTUType gtuType = new GTUType("Car");
197 Set<GTUType> compatibility = new HashSet<GTUType>();
198 compatibility.add(gtuType);
199 LaneType laneType = new LaneType("CarLane", compatibility);
200 List<Lane> path = dummyPath(laneType, gtuType);
201 SpeedContourPlot scp = new SpeedContourPlot("Density", path);
202 assertTrue("newly created DensityContourPlot should not be null", null != scp);
203 assertEquals("SeriesKey should be \"speed\"", "speed", scp.getSeriesKey(0));
204 standardContourTests(scp, path.get(0), gtuType, Double.NaN, 50);
205 }
206
207
208
209
210
211
212
213
214
215
216
217
218 public static void standardContourTests(final ContourPlot cp, Lane lane, GTUType gtuType,
219 final double expectedZValue, final double expectedZValueWithTraffic) throws Exception
220 {
221 assertEquals("seriesCount should be 1", 1, cp.getSeriesCount());
222 assertEquals("domainOrder should be ASCENDING", DomainOrder.ASCENDING, cp.getDomainOrder());
223 assertEquals("indexOf always returns 0", 0, cp.indexOf(0));
224 assertEquals("indexOf always returns 0", 0, cp.indexOf("abc"));
225 assertEquals("getGroup always returns null", null, cp.getGroup());
226 int xBins = cp.xAxisBins();
227 int yBins = cp.yAxisBins();
228 int expectedXBins =
229 (int) Math.ceil((DoubleScalar.minus(ContourPlot.INITIALUPPERTIMEBOUND, ContourPlot.INITIALLOWERTIMEBOUND)
230 .getSI()) / ContourPlot.STANDARDTIMEGRANULARITIES[ContourPlot.STANDARDINITIALTIMEGRANULARITYINDEX]);
231 assertEquals("Initial xBins should be " + expectedXBins, expectedXBins, xBins);
232 int expectedYBins =
233 (int) Math.ceil(lane.getLength().getSI()
234 / ContourPlot.STANDARDDISTANCEGRANULARITIES[ContourPlot.STANDARDINITIALDISTANCEGRANULARITYINDEX]);
235 assertEquals("yBins should be " + expectedYBins, expectedYBins, yBins);
236 int bins = cp.getItemCount(0);
237 assertEquals("Total bin count is product of xBins * yBins", xBins * yBins, bins);
238
239
240 String initialLowerTimeBoundString = ContourPlot.INITIALLOWERTIMEBOUND.toString();
241 String initialUpperTimeBoundString = ContourPlot.INITIALUPPERTIMEBOUND.toString();
242
243 for (double timeGranularity : ContourPlot.STANDARDTIMEGRANULARITIES)
244 {
245 cp.actionPerformed(new ActionEvent(cp, 0, "setTimeGranularity " + timeGranularity));
246 for (double distanceGranularity : ContourPlot.STANDARDDISTANCEGRANULARITIES)
247 {
248 cp.actionPerformed(new ActionEvent(cp, 0, "setDistanceGranularity " + distanceGranularity));
249 cp.reGraph();
250 expectedXBins =
251 (int) Math.ceil((DoubleScalar.minus(ContourPlot.INITIALUPPERTIMEBOUND,
252 ContourPlot.INITIALLOWERTIMEBOUND).getSI()) / timeGranularity);
253 xBins = cp.xAxisBins();
254 assertEquals("Modified xBins should be " + expectedXBins, expectedXBins, xBins);
255 expectedYBins = (int) Math.ceil(lane.getLength().getSI() / distanceGranularity);
256 yBins = cp.yAxisBins();
257 assertEquals("Modified yBins should be " + expectedYBins, expectedYBins, yBins);
258 bins = cp.getItemCount(0);
259 assertEquals("Total bin count is product of xBins * yBins", xBins * yBins, bins);
260 for (int item = 0; item < bins; item++)
261 {
262 double x = cp.getXValue(0, item);
263 assertTrue("X should be >= " + initialLowerTimeBoundString,
264 x >= ContourPlot.INITIALLOWERTIMEBOUND.getSI());
265 assertTrue("X should be <= " + initialUpperTimeBoundString,
266 x <= ContourPlot.INITIALUPPERTIMEBOUND.getSI());
267 Number alternateX = cp.getX(0, item);
268 assertEquals("getXValue and getX should return things that have the same value", x,
269 alternateX.doubleValue(), 0.000001);
270 double y = cp.getYValue(0, item);
271 Number alternateY = cp.getY(0, item);
272 assertEquals("getYValue and getY should return things that have the same value", y,
273 alternateY.doubleValue(), 0.000001);
274 double z = cp.getZValue(0, item);
275 if (Double.isNaN(expectedZValue))
276 {
277 assertTrue("Z value should be NaN", Double.isNaN(z));
278 }
279 else
280 {
281 assertEquals("Z value should be " + expectedZValue, expectedZValue, z, 0.0001);
282 }
283 Number alternateZ = cp.getZ(0, item);
284 if (Double.isNaN(expectedZValue))
285 {
286 assertTrue("Alternate Z value should be NaN", Double.isNaN(alternateZ.doubleValue()));
287 }
288 else
289 {
290 assertEquals("Alternate Z value should be " + expectedZValue, expectedZValue,
291 alternateZ.doubleValue(), 0.0000);
292 }
293 }
294 try
295 {
296 cp.getXValue(0, -1);
297 fail("Should have thrown an Exception");
298 }
299 catch (RuntimeException e)
300 {
301
302 }
303 try
304 {
305 cp.getXValue(0, bins);
306 fail("Should have thrown an Exception");
307 }
308 catch (RuntimeException e)
309 {
310
311 }
312 try
313 {
314 cp.yAxisBin(-1);
315 fail("Should have thrown an Exception");
316 }
317 catch (RuntimeException e)
318 {
319
320 }
321 try
322 {
323 cp.yAxisBin(bins);
324 fail("Should have thrown an Exception");
325 }
326 catch (RuntimeException e)
327 {
328
329 }
330 }
331 }
332
333 try
334 {
335 cp.actionPerformed(new ActionEvent(cp, 0, "blabla"));
336 fail("Should have thrown an Exception");
337 }
338 catch (RuntimeException e)
339 {
340
341 }
342 try
343 {
344 cp.actionPerformed(new ActionEvent(cp, 0, "setDistanceGranularity -1"));
345 fail("Should have thrown an Exception");
346 }
347 catch (RuntimeException e)
348 {
349
350 }
351 try
352 {
353 cp.actionPerformed(new ActionEvent(cp, 0, "setDistanceGranularity abc"));
354 fail("Should have thrown an Exception");
355 }
356 catch (RuntimeException e)
357 {
358
359 }
360 try
361 {
362 cp.actionPerformed(new ActionEvent(cp, 0, "setDistanceGranularitIE 10"));
363 fail("Should have thrown an Exception");
364 }
365 catch (RuntimeException e)
366 {
367
368 }
369
370 final double useTimeGranularity = 30;
371 cp.actionPerformed(new ActionEvent(cp, 0, "setTimeGranularity " + useTimeGranularity));
372 final double useDistanceGranularity =
373 ContourPlot.STANDARDDISTANCEGRANULARITIES[ContourPlot.STANDARDDISTANCEGRANULARITIES.length - 1];
374 cp.actionPerformed(new ActionEvent(cp, 0, "setDistanceGranularity " + useDistanceGranularity));
375 cp.reGraph();
376 bins = cp.getItemCount(0);
377 Time initialTime = new Time(0, SECOND);
378 Length initialPosition = new Length(100, METER);
379 Speed initialSpeed = new Speed(50, KM_PER_HOUR);
380 ContourPlotModel model = new ContourPlotModel();
381 SimpleSimulator simulator =
382 new SimpleSimulator(initialTime, new Duration(0, SECOND), new Duration(1800, SECOND), model);
383
384 SequentialFixedAccelerationModel gtuFollowingModel =
385 new SequentialFixedAccelerationModel(simulator, new Acceleration(2.0, AccelerationUnit.METER_PER_SECOND_2));
386
387 gtuFollowingModel.addStep(new FixedAccelerationModel(new Acceleration(0, METER_PER_SECOND_2), new Duration(60,
388 SECOND)));
389
390 gtuFollowingModel.addStep(new FixedAccelerationModel(new Acceleration(0, METER_PER_SECOND_2), new Duration(600,
391 SECOND)));
392
393 gtuFollowingModel.addStep(new FixedAccelerationModel(new Acceleration(0, METER_PER_SECOND_2), new Duration(300,
394 SECOND)));
395 LaneChangeModel laneChangeModel = new Egoistic();
396 OTSNetwork network = new OTSNetwork("network");
397
398
399 for (int item = 0; item < bins; item++)
400 {
401 double x = cp.getXValue(0, item);
402 assertTrue("X should be >= " + ContourPlot.INITIALLOWERTIMEBOUND,
403 x >= ContourPlot.INITIALLOWERTIMEBOUND.getSI());
404 assertTrue("X should be <= " + ContourPlot.INITIALUPPERTIMEBOUND,
405 x <= ContourPlot.INITIALUPPERTIMEBOUND.getSI());
406 Number alternateX = cp.getX(0, item);
407 assertEquals("getXValue and getX should return things that have the same value", x,
408 alternateX.doubleValue(), 0.000001);
409 double y = cp.getYValue(0, item);
410 Number alternateY = cp.getY(0, item);
411 assertEquals("getYValue and getY should return things that have the same value", y,
412 alternateY.doubleValue(), 0.000001);
413 double z = cp.getZValue(0, item);
414 if (Double.isNaN(expectedZValue))
415 {
416 assertTrue("Z value should be NaN (got " + z + ")", Double.isNaN(z));
417 }
418 else
419 {
420 assertEquals("Z value should be " + expectedZValue, expectedZValue, z, 0.0001);
421 }
422 Number alternateZ = cp.getZ(0, item);
423 if (Double.isNaN(expectedZValue))
424 {
425 assertTrue("Alternate Z value should be NaN", Double.isNaN(alternateZ.doubleValue()));
426 }
427 else
428 {
429 assertEquals("Alternate Z value should be " + expectedZValue, expectedZValue, alternateZ.doubleValue(),
430 0.0000);
431 }
432 }
433
434 LaneBasedIndividualGTU car =
435 CarTest.makeReferenceCar("0", gtuType, lane, initialPosition, initialSpeed, simulator, gtuFollowingModel,
436 laneChangeModel, network);
437 car.getStrategicalPlanner().getBehavioralCharacteristics().setParameter(
438 ParameterTypes.LOOKAHEAD, new Length(10, LengthUnit.KILOMETER));
439
440
441
442 double stopTime = gtuFollowingModel.timeAfterCompletionOfStep(0).si;
443 simulator.runUpToAndIncluding(new Time(stopTime, TimeUnit.SI));
444 while (simulator.isRunning())
445 {
446 try
447 {
448 Thread.sleep(10);
449 }
450 catch (InterruptedException ie)
451 {
452 ie = null;
453 }
454 }
455
456
457
458
459 for (int item = 0; item < bins; item++)
460 {
461 double x = cp.getXValue(0, item);
462 assertTrue("X should be >= " + ContourPlot.INITIALLOWERTIMEBOUND,
463 x >= ContourPlot.INITIALLOWERTIMEBOUND.getSI());
464 assertTrue("X should be <= " + ContourPlot.INITIALUPPERTIMEBOUND,
465 x <= ContourPlot.INITIALUPPERTIMEBOUND.getSI());
466 Number alternateX = cp.getX(0, item);
467 assertEquals("getXValue and getX should return things that have the same value", x,
468 alternateX.doubleValue(), 0.000001);
469 double y = cp.getYValue(0, item);
470 Number alternateY = cp.getY(0, item);
471 assertEquals("getYValue and getY should return things that have the same value", y,
472 alternateY.doubleValue(), 0.000001);
473 double z = cp.getZValue(0, item);
474
475
476
477
478
479 boolean hit = false;
480 if (x + useTimeGranularity >= 0
481 && x < 60)
482 {
483
484 Time cellStartTime =
485 new Time(Math.max(car.getOperationalPlan().getStartTime().getSI(), x), SECOND);
486 Time cellEndTime =
487 new Time(Math.min(car.getOperationalPlan().getEndTime().getSI(), x + useTimeGranularity),
488 SECOND);
489
490
491
492
493
494 double xAtCellStartTime = initialPosition.si + initialSpeed.si * cellStartTime.si;
495 double xAtCellEndTime = initialPosition.si + initialSpeed.si * cellEndTime.si;
496 if (xAtCellStartTime < y + useDistanceGranularity && xAtCellEndTime >= y)
497 {
498 hit = true;
499 }
500 }
501
502
503
504
505 Number alternateZ = cp.getZ(0, item);
506 if (hit)
507 {
508 if (!Double.isNaN(expectedZValueWithTraffic))
509 {
510 if (Double.isNaN(z))
511 {
512 printMatrix(cp, 0, 10, 0, 10);
513 System.out.println("Oops - z is NaN, expected z value with traffic is "
514 + expectedZValueWithTraffic);
515 }
516 assertEquals("Z value should be " + expectedZValueWithTraffic, expectedZValueWithTraffic, z, 0.0001);
517 assertEquals("Z value should be " + expectedZValueWithTraffic, expectedZValueWithTraffic,
518 alternateZ.doubleValue(), 0.0001);
519 }
520 else
521 {
522 if (Double.isNaN(expectedZValue))
523 {
524 assertFalse("Z value should not be NaN", Double.isNaN(z));
525 }
526 }
527 }
528 else
529 {
530 if (Double.isNaN(expectedZValue))
531 {
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550 assertTrue("Z value should be NaN", Double.isNaN(z));
551 }
552 else
553 {
554 assertEquals("Z value should be " + expectedZValue, expectedZValue, z, 0.0001);
555 }
556 if (Double.isNaN(expectedZValue))
557 {
558 assertTrue("Alternate Z value should be NaN", Double.isNaN(alternateZ.doubleValue()));
559 }
560 else
561 {
562 assertEquals("Alternate Z value should be " + expectedZValue, expectedZValue,
563 alternateZ.doubleValue(), 0.0000);
564 }
565 }
566 }
567
568
569 stopTime = gtuFollowingModel.timeAfterCompletionOfStep(1).si;
570 simulator.runUpToAndIncluding(new Time(stopTime, TimeUnit.SI));
571 while (simulator.isRunning())
572 {
573 try
574 {
575 Thread.sleep(10);
576 }
577 catch (InterruptedException ie)
578 {
579 ie = null;
580 }
581 }
582
583
584 xBins = cp.xAxisBins();
585 bins = cp.getItemCount(0);
586 double observedHighestTime = Double.MIN_VALUE;
587 for (int bin = 0; bin < bins; bin++)
588 {
589 double xValue = cp.getXValue(0, bin);
590 if (xValue > observedHighestTime)
591 {
592 observedHighestTime = xValue;
593 }
594 }
595 double expectedHighestTime =
596 Math.floor((car.getSimulator().getSimulatorTime().get().si - 0.001) / useTimeGranularity)
597 * useTimeGranularity;
598 assertEquals("Time range should run up to " + expectedHighestTime, expectedHighestTime, observedHighestTime,
599 0.0001);
600
601
602 JLabel hintPanel = null;
603 ChartPanel chartPanel = null;
604 for (Component c0 : cp.getComponents())
605 {
606 for (Component c1 : ((Container) c0).getComponents())
607 {
608 if (c1 instanceof Container)
609 {
610 for (Component c2 : ((Container) c1).getComponents())
611 {
612
613 if (c2 instanceof Container)
614 {
615 for (Component c3 : ((Container) c2).getComponents())
616 {
617
618 if (c3 instanceof JLabel)
619 {
620 if (null == hintPanel)
621 {
622 hintPanel = (JLabel) c3;
623 }
624 else
625 {
626 fail("There should be only one JPanel in a ContourPlot");
627 }
628 }
629 if (c3 instanceof ChartPanel)
630 {
631 if (null == chartPanel)
632 {
633 chartPanel = (ChartPanel) c3;
634 }
635 else
636 {
637 fail("There should be only one ChartPanel in a ContourPlot");
638 }
639 }
640 }
641 }
642 }
643 }
644 }
645 }
646 if (null == hintPanel)
647 {
648 fail("Could not find a JLabel in ContourPlot");
649 }
650 if (null == chartPanel)
651 {
652 fail("Could not find a ChartPanel in ContourPlot");
653 }
654 assertEquals("Initially the text should be a single space", " ", hintPanel.getText());
655 PointerHandler ph = null;
656 for (MouseListener ml : chartPanel.getMouseListeners())
657 {
658 if (ml instanceof PointerHandler)
659 {
660 if (null == ph)
661 {
662 ph = (PointerHandler) ml;
663 }
664 else
665 {
666 fail("There should be only one PointerHandler on the chartPanel");
667 }
668 }
669 }
670 if (null == ph)
671 {
672 fail("Could not find the PointerHandler for the chartPanel");
673 }
674 ph.updateHint(1, 2);
675
676 assertFalse("Hint should not be a single space", " ".equals(hintPanel.getText()));
677 ph.updateHint(Double.NaN, Double.NaN);
678 assertEquals("The text should again be a single space", " ", hintPanel.getText());
679 }
680
681
682
683
684
685
686 public static void main(final String[] args) throws Exception
687 {
688 ContourPlotTest cpt = new ContourPlotTest();
689 System.out.println("Click the OK button");
690 JOptionPane.showMessageDialog(null, "ContourPlot", "Start experiment", JOptionPane.INFORMATION_MESSAGE);
691 System.out.println("Running ...");
692 cpt.densityContourTest();
693 System.out.println("Finished");
694 }
695
696 }
697
698
699
700
701
702
703
704
705
706
707 class ContourPlotModel implements OTSModelInterface
708 {
709
710
711 private static final long serialVersionUID = 20150209L;
712
713
714 @Override
715 public void constructModel(
716 SimulatorInterface<DoubleScalar.Abs<TimeUnit>, DoubleScalar.Rel<TimeUnit>, OTSSimTimeDouble> simulator)
717 throws SimRuntimeException
718 {
719
720 }
721
722
723 @Override
724 public SimulatorInterface<DoubleScalar.Abs<TimeUnit>, DoubleScalar.Rel<TimeUnit>, OTSSimTimeDouble> getSimulator()
725
726 {
727 return null;
728 }
729
730 }