LongitudinalDirectionality.java
package org.opentrafficsim.core.network;
import java.util.Arrays;
import java.util.LinkedHashSet;
import org.opentrafficsim.core.gtu.GTUDirectionality;
import nl.tudelft.simulation.immutablecollections.Immutable;
import nl.tudelft.simulation.immutablecollections.ImmutableHashSet;
import nl.tudelft.simulation.immutablecollections.ImmutableSet;
/**
* Permitted longitudinal driving directions.
* <p>
* Copyright (c) 2013-2018 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
* BSD-style license. See <a href="http://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
* <p>
* $LastChangedDate: 2018-09-19 13:55:45 +0200 (Wed, 19 Sep 2018) $, @version $Revision: 4006 $, by $Author: averbraeck $,
* initial version Oct 15, 2014 <br>
* @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
* @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
* @author <a href="http://www.citg.tudelft.nl">Guus Tamminga</a>
*/
public enum LongitudinalDirectionality
{
/** Direction the same as the direction of the graph, increasing fractional position when driving in this direction. */
DIR_PLUS(new GTUDirectionality[] { GTUDirectionality.DIR_PLUS }),
/** Direction opposite to the direction of the graph, decreasing fractional position when driving in this direction. */
DIR_MINUS(new GTUDirectionality[] { GTUDirectionality.DIR_MINUS }),
/** Bidirectional. */
DIR_BOTH(new GTUDirectionality[] { GTUDirectionality.DIR_PLUS, GTUDirectionality.DIR_MINUS }),
/** No traffic possible. */
DIR_NONE(new GTUDirectionality[] {});
/** Array of permitted driving directions. */
private final ImmutableSet<GTUDirectionality> directions;
/**
* Construct a new LongitudinalDirectionality.
* @param directions GTUDirectionality[]; array containing the permitted driving directions
*/
LongitudinalDirectionality(final GTUDirectionality[] directions)
{
this.directions = new ImmutableHashSet<>(new LinkedHashSet<>(Arrays.asList(directions)), Immutable.WRAP);
}
/**
* Retrieve the permitted driving directions.
* @return ImmutableSet<GTUDirectionality>; immutable set containing the permitted driving directions
*/
public final ImmutableSet<GTUDirectionality> getDirectionalities()
{
return this.directions;
}
/**
* This method looks if this directionality "contains" the provided other directionality. The logic table looks as follows:
* <table border="1" summary="">
* <tr>
* <td><b>THIS ↓ OTHER →</b></td>
* <td><b>DIR_BOTH </b></td>
* <td><b>DIR_PLUS </b></td>
* <td><b>DIR_MINUS</b></td>
* <td><b>DIR_NONE </b></td>
* </tr>
* <tr>
* <td><b>DIR_BOTH</b></td>
* <td>true</td>
* <td>true</td>
* <td>true</td>
* <td>true</td>
* </tr>
* <tr>
* <td><b>DIR_PLUS</b></td>
* <td>false</td>
* <td>true</td>
* <td>false</td>
* <td>true</td>
* </tr>
* <tr>
* <td><b>DIR_MINUS</b></td>
* <td>false</td>
* <td>false</td>
* <td>true</td>
* <td>true</td>
* </tr>
* <tr>
* <td><b>DIR_NONE</b></td>
* <td>false</td>
* <td>false</td>
* <td>false</td>
* <td>true</td>
* </tr>
* </table>
* @param directionality the directionality to compare with
* @return whether this directionality "contains" the provided other directionality
*/
public final boolean contains(final LongitudinalDirectionality directionality)
{
return (this.equals(directionality) || this.equals(DIR_BOTH) || directionality.equals(DIR_NONE)) ? true : false;
}
/**
* Easy access method to test if the directionality is FORWARD or BOTH.
* @return whether the directionality is FORWARD or BOTH
*/
public final boolean isForwardOrBoth()
{
return this.equals(DIR_PLUS) || this.equals(DIR_BOTH);
}
/**
* Easy access method to test if the directionality is BACKWARD or BOTH.
* @return whether the directionality is BACKWARD or BOTH
*/
public final boolean isBackwardOrBoth()
{
return this.equals(DIR_MINUS) || this.equals(DIR_BOTH);
}
/**
* Easy access method to test if the directionality is FORWARD.
* @return whether the directionality is FORWARD
*/
public final boolean isForward()
{
return this.equals(DIR_PLUS);
}
/**
* Easy access method to test if the directionality is BACKWARD.
* @return whether the directionality is BACKWARD
*/
public final boolean isBackward()
{
return this.equals(DIR_MINUS);
}
/**
* Easy access method to test if the directionality is BACKWARD or BOTH.
* @return whether the directionality is BACKWARD or BOTH
*/
public final boolean isBoth()
{
return this.equals(DIR_BOTH);
}
/**
* Compute the intersection of this LongitudinalDirectionality with another LongitudinalDirectionality.
* @param other LongitudinalDirectionality; the other LongitudinalDirectionality
* @return LongitudinalDirectionality; the intersection of <code>this</code> and <code>other</code>
*/
public final LongitudinalDirectionality intersect(final LongitudinalDirectionality other)
{
switch (other)
{
case DIR_BOTH:
return this;
case DIR_MINUS:
if (this.equals(other))
{
return this;
}
if (this.equals(DIR_BOTH))
{
return other;
}
return DIR_NONE;
case DIR_NONE:
return other;
case DIR_PLUS:
if (this.equals(other))
{
return this;
}
if (this.equals(DIR_BOTH))
{
return other;
}
return DIR_NONE;
default:
System.err.println("intersect with null (returns DIR_NONE)");
return DIR_NONE;
}
}
/**
* Check if a direction is permitted by this LongitudinalDirectionality.
* @param direction GTUDirectionality; the direction of motion in which a GTU moves, or wants to move
* @return boolean; true if the direction is permitted by this LongitudinalDirectionality; false if it is not permitted
*/
public final boolean permits(final GTUDirectionality direction)
{
switch (direction)
{
case DIR_MINUS:
return isBackwardOrBoth();
case DIR_PLUS:
return isForwardOrBoth();
default:
System.out.println("Bad direction: " + direction);
return false;
}
}
/**
* Return the inverse if this LongitudinalDirectionality.
* @return LongitudinalDirectionality; the directional inverse of this LongitudinalDirectionality
*/
public LongitudinalDirectionality invert()
{
switch (this)
{
case DIR_BOTH:
return this;
case DIR_MINUS:
return DIR_PLUS;
case DIR_NONE:
return this;
case DIR_PLUS:
return DIR_MINUS;
default:
return this; // cannot happen
}
}
}