<<<<<<< HEAD
package roadnetwork;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Stroke;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import shapes.Line2DExt;
import shapes.Polygon2D;
import trafficdefinition.TrafficDefinitionElement;
/**
* Class that represents an edge (street) of the road network.
*/
public class Edge extends RoadNetworkElement implements Serializable {
private static final long serialVersionUID = 1L;
/**
* List containing any traffic definition elements that depent on this edge.
* If this list is not empty, then the edge will not be deleted.
*/
private List<TrafficDefinitionElement> dependentTrafficElements = null;
/**
* The lines that represent the dividers between the edge's lanes.
*/
private List<Line2DExt> dividers = new ArrayList<Line2DExt>();
/**
* The id of the junction that this edge starts from.
*/
private String from = "";
/**
* The edge's lanes.
*/
private List<Lane> lanes;
/**
* The edge's length in meters.
*/
private float length = 0;
/**
* The edge's priority
*/
private int priority = 0;
/**
* The edge's speed limit in m/s
*/
private float speedLimit = 0;
/**
* The id of the junction that this edge ends to.
*/
private String to = "";
/**
* Default constructor
*
*/
public Edge() {
lanes = new ArrayList<Lane>();
}
/**
* Adds the given {@link TrafficDefinitionElement} to the list of the
* elements that depent on this edge.
*
* @param t
*/
public void AddDependentTrafficElement(TrafficDefinitionElement t) {
if (dependentTrafficElements == null) {
dependentTrafficElements = new ArrayList<TrafficDefinitionElement>();
}
if (!dependentTrafficElements.contains(t)) {
dependentTrafficElements.add(t);
}
}
/**
* Adds a new lane to the edge.
*
* @param l
*/
public void AddLane(Lane l) {
lanes.add(l);
}
/**
* Method that creates the shape of the edge. This method creates the
* polygon that defines the edge's shape and the dividers that are drawn
* between the lanes.
*
*/
public void CalculateShape() {
// Each lane is 3.2 meters wide.A lane is defined by a series of points
// that pass through the lane's center. All lanes have the same number
// of points. The dividers are calculated as the lines passing between
// two consecutive lane points
// Calculate the width of half the edge.
double halfwidth = 1.6 * lanes.size();
// Get the total points that the edge has
int parts = Integer.MAX_VALUE;
//TODO what happens if each lane has a different number of parts
//int parts = lanes.get(0).GetTotalPoints();
for(Lane l:lanes){
parts = Math.min(parts, l.GetTotalPoints());
}
// Lists holding the left and right side points that will define the
// polygon of the edge.
List<Point2D.Double> leftPoints = new ArrayList<Point2D.Double>();
List<Point2D.Double> rightPoints = new ArrayList<Point2D.Double>();
// Lists holding the previous and next points for all lanes
List<Point2D.Double> previousLanePoints = new ArrayList<Point2D.Double>();
List<Point2D.Double> nextLanePoints = new ArrayList<Point2D.Double>();
Point2D.Double previousCenter;
Point2D.Double nextCenter;
Point2D.Double newLeftPoint;
Point2D.Double newRightPoint;
//Loop through the number of points that the edge passes through
for (int i = 0; i < parts; i++) {
previousLanePoints.clear();
nextLanePoints.clear();
// last part
if (i == parts - 1) {
for (Lane l : lanes) {
previousLanePoints.add(l.GetPoint(i));
nextLanePoints.add(l.GetPoint(i - 1));
}
}
// all others
else {
for (Lane l : lanes) {
previousLanePoints.add(l.GetPoint(i));
nextLanePoints.add(l.GetPoint(i + 1));
}
}
// Calculate dividers
Point2D.Double lineStart = new Point2D.Double();
Point2D.Double lineEnd = new Point2D.Double();
//We have as many dividers as lanes minus one
for (int dp = 0; dp < lanes.size() - 1; dp++) {
lineStart.x = (previousLanePoints.get(dp).x + previousLanePoints.get(dp + 1).x) / 2;
lineStart.y = (previousLanePoints.get(dp).y + previousLanePoints.get(dp + 1).y) / 2;
lineEnd.x = (nextLanePoints.get(dp).x + nextLanePoints.get(dp + 1).x) / 2;
lineEnd.y = (nextLanePoints.get(dp).y + nextLanePoints.get(dp + 1).y) / 2;
dividers.add(new Line2DExt(lineStart, lineEnd));
}
// Find the center of the previous and next points
previousCenter = PointsCenter(previousLanePoints);
nextCenter = PointsCenter(nextLanePoints);
// if they are horizontal
if (previousCenter.y == nextCenter.y) {
newLeftPoint = new Point2D.Double(previousCenter.x, previousCenter.y - halfwidth);
newRightPoint = new Point2D.Double(previousCenter.x, previousCenter.y + halfwidth);
}
// if they are vertical
else if (previousCenter.x == nextCenter.x) {
newLeftPoint = new Point2D.Double(previousCenter.x - halfwidth, previousCenter.y);
newRightPoint = new Point2D.Double(previousCenter.x + halfwidth, previousCenter.y);
}
// if they are diagonal
else {
// use circles
double m = -(nextCenter.x - previousCenter.x) / (nextCenter.y - previousCenter.y);
newLeftPoint = new Point2D.Double((halfwidth / Math.sqrt(m * m + 1)) + previousCenter.x, previousCenter.y + m * halfwidth / Math.sqrt(m * m + 1));
newRightPoint = new Point2D.Double((-halfwidth / Math.sqrt(m * m + 1)) + previousCenter.x, previousCenter.y - m * halfwidth / Math.sqrt(m * m + 1));
}
leftPoints.add(newLeftPoint);
rightPoints.add(newRightPoint);
}
double[] f = new double[(parts) * 2 * 2];
int v = 0;
for (Point2D.Double k : rightPoints) {
f[v++] = k.x;
f[v++] = k.y;
}
for (int k = leftPoints.size() - 1; k >= 0; k--) {
f[v++] = leftPoints.get(k).x;
f[v++] = leftPoints.get(k).y;
}
shape = new Polygon2D.Double(f);
}
/**
* Calculates the distance from another edge.
* @param e
* @return the distance in meters between the two edges
*/
public int DistanceFrom(Edge e) {
return (int) Math.round(lanes.get(0).GetPoint(0).distance(e.lanes.get(0).GetPoint(0)));
}
/**
* Calculates the distance from the specified point
* @param point
* @return
*/
public double DistanceFrom(Point2D.Double point) {
return lanes.get(0).GetPoint(0).distance(point);
}
@Override
public void Draw(Graphics2D g, double zoomFactor, boolean isDeleted, boolean isSelected) {
super.Draw(g, zoomFactor, isDeleted, isSelected);
// Save the previous color to restore it later
Color prev = g.getColor();
// Draw the lane divider lines in yellow
g.setColor(Color.YELLOW);
// Draw the dividers only if we are zoomed in enough
if (zoomFactor > 2.f) {
Stroke previous = g.getStroke();
float[] dashes = { 1.f, 2.f };
g.setStroke(new BasicStroke(0.1f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10.f, dashes, 0.f));
for (Line2D.Double l : dividers) {
g.draw(l);
}
g.setStroke(previous);
}
g.setColor(prev);
}
/**
* @return the from
* @uml.property name="from"
*/
public String getFrom() {
return from;
}
/**
* @return the lanes
* @uml.property name="lanes"
*/
public List<Lane> getLanes() {
return lanes;
}
/**
* @return the length
* @uml.property name="length"
*/
public float getLength() {
return length;
}
/**
* @return the priority
* @uml.property name="priority"
*/
public int getPriority() {
return priority;
}
/**
* @return the speedLimit
* @uml.property name="speedLimit"
*/
public float getSpeedLimit() {
return speedLimit;
}
/**
* @return the to
* @uml.property name="to"
*/
public String getTo() {
return to;
}
@Override
public String getToolTip() {
return "<html>" + "<b>Edge</b> " + id + "<br>" + "<b>Priority:</b> " + priority + "<br>" + "<b>Speed limit:</b> " + speedLimit + "<br>" + "</html>";
}
/**
* Checks whether this edge has traffic definition elements that depend on it.
*
* @return true if the edge has dependent traffic elements, false otherwise
*/
public boolean HasDependentTrafficElements() {
if (dependentTrafficElements == null) {
return false;
} else {
return true;
}
}
/**
* Returns the list of traffic elements that depend on this edge
* @return
* @uml.property name="dependentTrafficElements"
*/
public List<TrafficDefinitionElement> getDependentTrafficElements(){
return dependentTrafficElements;
}
/**
* Removes the specified traffic element from this edge's list of dependent traffic elements
* @param t the traffic element to remove
*/
public void RemoveDependentTrafficElement(TrafficDefinitionElement t) {
if ((dependentTrafficElements != null) && (dependentTrafficElements.contains(t))) {
dependentTrafficElements.remove(t);
if (dependentTrafficElements.isEmpty()) {
dependentTrafficElements = null;
}
}
}
/**
* @param from the from to set
* @uml.property name="from"
*/
public void setFrom(String from) {
this.from = from;
}
/**
* @param length the length to set
* @uml.property name="length"
*/
public void setLength(float length) {
this.length = length;
}
/**
* @param priority the priority to set
* @uml.property name="priority"
*/
public void setPriority(int priority) {
this.priority = priority;
}
/**
* @param speedLimit the speedLimit to set
* @uml.property name="speedLimit"
*/
public void setSpeedLimit(float speed) {
this.speedLimit = speed;
}
/**
* @param to the to to set
* @uml.property name="to"
*/
public void setTo(String to) {
this.to = to;
}
@Override
public String toString() {
return "Edge " + id;
}
/**
* Calculates the center of the specified points by averaging them
* @param points
* @return
*/
private Point2D.Double PointsCenter(List<Point2D.Double> points) {
Point2D.Double center = new Point2D.Double(0, 0);
for (Point2D.Double p : points) {
center.x += p.x;
center.y += p.y;
}
center.x /= points.size();
center.y /= points.size();
return center;
}
}
=======
package roadnetwork;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Stroke;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import shapes.Line2DExt;
import shapes.Polygon2D;
import trafficdefinition.TrafficDefinitionElement;
/**
* Class that represents an edge (street) of the road network.
*/
public class Edge extends RoadNetworkElement implements Serializable {
private static final long serialVersionUID = 1L;
/**
* List containing any traffic definition elements that depent on this edge.
* If this list is not empty, then the edge will not be deleted.
*/
private List<TrafficDefinitionElement> dependentTrafficElements = null;
/**
* The lines that represent the dividers between the edge's lanes.
*/
private List<Line2DExt> dividers = new ArrayList<Line2DExt>();
/**
* The id of the junction that this edge starts from.
*/
private String from = "";
/**
* The edge's lanes.
*/
private List<Lane> lanes;
/**
* The edge's length in meters.
*/
private float length = 0;
/**
* The edge's priority
*/
private int priority = 0;
/**
* The edge's speed limit in m/s
*/
private float speedLimit = 0;
/**
* The id of the junction that this edge ends to.
*/
private String to = "";
/**
* Default constructor
*
*/
public Edge() {
lanes = new ArrayList<Lane>();
}
/**
* Adds the given {@link TrafficDefinitionElement} to the list of the
* elements that depent on this edge.
*
* @param t
*/
public void AddDependentTrafficElement(TrafficDefinitionElement t) {
if (dependentTrafficElements == null) {
dependentTrafficElements = new ArrayList<TrafficDefinitionElement>();
}
if (!dependentTrafficElements.contains(t)) {
dependentTrafficElements.add(t);
}
}
/**
* Adds a new lane to the edge.
*
* @param l
*/
public void AddLane(Lane l) {
lanes.add(l);
}
/**
* Method that creates the shape of the edge. This method creates the
* polygon that defines the edge's shape and the dividers that are drawn
* between the lanes.
*
*/
public void CalculateShape() {
// Each lane is 3.2 meters wide.A lane is defined by a series of points
// that pass through the lane's center. All lanes have the same number
// of points. The dividers are calculated as the lines passing between
// two consecutive lane points
// Calculate the width of half the edge.
double halfwidth = 1.6 * lanes.size();
// Get the total points that the edge has
int parts = Integer.MAX_VALUE;
//TODO what happens if each lane has a different number of parts
//int parts = lanes.get(0).GetTotalPoints();
for(Lane l:lanes){
parts = Math.min(parts, l.GetTotalPoints());
}
// Lists holding the left and right side points that will define the
// polygon of the edge.
List<Point2D.Double> leftPoints = new ArrayList<Point2D.Double>();
List<Point2D.Double> rightPoints = new ArrayList<Point2D.Double>();
// Lists holding the previous and next points for all lanes
List<Point2D.Double> previousLanePoints = new ArrayList<Point2D.Double>();
List<Point2D.Double> nextLanePoints = new ArrayList<Point2D.Double>();
Point2D.Double previousCenter;
Point2D.Double nextCenter;
Point2D.Double newLeftPoint;
Point2D.Double newRightPoint;
//Loop through the number of points that the edge passes through
for (int i = 0; i < parts; i++) {
previousLanePoints.clear();
nextLanePoints.clear();
// last part
if (i == parts - 1) {
for (Lane l : lanes) {
previousLanePoints.add(l.GetPoint(i));
nextLanePoints.add(l.GetPoint(i - 1));
}
}
// all others
else {
for (Lane l : lanes) {
previousLanePoints.add(l.GetPoint(i));
nextLanePoints.add(l.GetPoint(i + 1));
}
}
// Calculate dividers
Point2D.Double lineStart = new Point2D.Double();
Point2D.Double lineEnd = new Point2D.Double();
//We have as many dividers as lanes minus one
for (int dp = 0; dp < lanes.size() - 1; dp++) {
lineStart.x = (previousLanePoints.get(dp).x + previousLanePoints.get(dp + 1).x) / 2;
lineStart.y = (previousLanePoints.get(dp).y + previousLanePoints.get(dp + 1).y) / 2;
lineEnd.x = (nextLanePoints.get(dp).x + nextLanePoints.get(dp + 1).x) / 2;
lineEnd.y = (nextLanePoints.get(dp).y + nextLanePoints.get(dp + 1).y) / 2;
dividers.add(new Line2DExt(lineStart, lineEnd));
}
// Find the center of the previous and next points
previousCenter = PointsCenter(previousLanePoints);
nextCenter = PointsCenter(nextLanePoints);
// if they are horizontal
if (previousCenter.y == nextCenter.y) {
newLeftPoint = new Point2D.Double(previousCenter.x, previousCenter.y - halfwidth);
newRightPoint = new Point2D.Double(previousCenter.x, previousCenter.y + halfwidth);
}
// if they are vertical
else if (previousCenter.x == nextCenter.x) {
newLeftPoint = new Point2D.Double(previousCenter.x - halfwidth, previousCenter.y);
newRightPoint = new Point2D.Double(previousCenter.x + halfwidth, previousCenter.y);
}
// if they are diagonal
else {
// use circles
double m = -(nextCenter.x - previousCenter.x) / (nextCenter.y - previousCenter.y);
newLeftPoint = new Point2D.Double((halfwidth / Math.sqrt(m * m + 1)) + previousCenter.x, previousCenter.y + m * halfwidth / Math.sqrt(m * m + 1));
newRightPoint = new Point2D.Double((-halfwidth / Math.sqrt(m * m + 1)) + previousCenter.x, previousCenter.y - m * halfwidth / Math.sqrt(m * m + 1));
}
leftPoints.add(newLeftPoint);
rightPoints.add(newRightPoint);
}
double[] f = new double[(parts) * 2 * 2];
int v = 0;
for (Point2D.Double k : rightPoints) {
f[v++] = k.x;
f[v++] = k.y;
}
for (int k = leftPoints.size() - 1; k >= 0; k--) {
f[v++] = leftPoints.get(k).x;
f[v++] = leftPoints.get(k).y;
}
shape = new Polygon2D.Double(f);
}
/**
* Calculates the distance from another edge.
* @param e
* @return the distance in meters between the two edges
*/
public int DistanceFrom(Edge e) {
return (int) Math.round(lanes.get(0).GetPoint(0).distance(e.lanes.get(0).GetPoint(0)));
}
/**
* Calculates the distance from the specified point
* @param point
* @return
*/
public double DistanceFrom(Point2D.Double point) {
return lanes.get(0).GetPoint(0).distance(point);
}
@Override
public void Draw(Graphics2D g, double zoomFactor, boolean isDeleted, boolean isSelected) {
super.Draw(g, zoomFactor, isDeleted, isSelected);
// Save the previous color to restore it later
Color prev = g.getColor();
// Draw the lane divider lines in yellow
g.setColor(Color.YELLOW);
// Draw the dividers only if we are zoomed in enough
if (zoomFactor > 2.f) {
Stroke previous = g.getStroke();
float[] dashes = { 1.f, 2.f };
g.setStroke(new BasicStroke(0.1f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10.f, dashes, 0.f));
for (Line2D.Double l : dividers) {
g.draw(l);
}
g.setStroke(previous);
}
g.setColor(prev);
}
/**
* @return the from
* @uml.property name="from"
*/
public String getFrom() {
return from;
}
/**
* @return the lanes
* @uml.property name="lanes"
*/
public List<Lane> getLanes() {
return lanes;
}
/**
* @return the length
* @uml.property name="length"
*/
public float getLength() {
return length;
}
/**
* @return the priority
* @uml.property name="priority"
*/
public int getPriority() {
return priority;
}
/**
* @return the speedLimit
* @uml.property name="speedLimit"
*/
public float getSpeedLimit() {
return speedLimit;
}
/**
* @return the to
* @uml.property name="to"
*/
public String getTo() {
return to;
}
@Override
public String getToolTip() {
return "<html>" + "<b>Edge</b> " + id + "<br>" + "<b>Priority:</b> " + priority + "<br>" + "<b>Speed limit:</b> " + speedLimit + "<br>" + "</html>";
}
/**
* Checks whether this edge has traffic definition elements that depend on it.
*
* @return true if the edge has dependent traffic elements, false otherwise
*/
public boolean HasDependentTrafficElements() {
if (dependentTrafficElements == null) {
return false;
} else {
return true;
}
}
/**
* Returns the list of traffic elements that depend on this edge
* @return
* @uml.property name="dependentTrafficElements"
*/
public List<TrafficDefinitionElement> getDependentTrafficElements(){
return dependentTrafficElements;
}
/**
* Removes the specified traffic element from this edge's list of dependent traffic elements
* @param t the traffic element to remove
*/
public void RemoveDependentTrafficElement(TrafficDefinitionElement t) {
if ((dependentTrafficElements != null) && (dependentTrafficElements.contains(t))) {
dependentTrafficElements.remove(t);
if (dependentTrafficElements.isEmpty()) {
dependentTrafficElements = null;
}
}
}
/**
* @param from the from to set
* @uml.property name="from"
*/
public void setFrom(String from) {
this.from = from;
}
/**
* @param length the length to set
* @uml.property name="length"
*/
public void setLength(float length) {
this.length = length;
}
/**
* @param priority the priority to set
* @uml.property name="priority"
*/
public void setPriority(int priority) {
this.priority = priority;
}
/**
* @param speedLimit the speedLimit to set
* @uml.property name="speedLimit"
*/
public void setSpeedLimit(float speed) {
this.speedLimit = speed;
}
/**
* @param to the to to set
* @uml.property name="to"
*/
public void setTo(String to) {
this.to = to;
}
@Override
public String toString() {
return "Edge " + id;
}
/**
* Calculates the center of the specified points by averaging them
* @param points
* @return
*/
private Point2D.Double PointsCenter(List<Point2D.Double> points) {
Point2D.Double center = new Point2D.Double(0, 0);
for (Point2D.Double p : points) {
center.x += p.x;
center.y += p.y;
}
center.x /= points.size();
center.y /= points.size();
return center;
}
}
>>>>>>> origin/abdalla