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