1
2
3
4
5
6
7
8
9
10
11 package nl.tudelft.simulation.traffic.track;
12
13 import java.awt.geom.Point2D;
14 import javax.media.j3d.Bounds;
15 import javax.vecmath.Point3d;
16 import nl.tudelft.simulation.language.d2.Angle;
17 import nl.tudelft.simulation.language.d2.Circle;
18 import nl.tudelft.simulation.language.d3.BoundingBox;
19 import nl.tudelft.simulation.language.d3.DirectedPoint;
20 import nl.tudelft.simulation.logger.Logger;
21
22 /***
23 * A curved track from one link to another link. <br>
24 * (c) copyright 2003-2004 <a href="http://www.simulation.tudelft.nl">Delft
25 * University of Technology </a>, the Netherlands. <br>
26 * See for project information <a href="http://www.simulation.tudelft.nl">
27 * www.simulation.tudelft.nl </a> <br>
28 * License of use: <a href="http://www.gnu.org/copyleft/gpl.html">General Public
29 * License (GPL) </a>, no warranty <br>
30 *
31 * @version May 30, 2004 <br>
32 * @author <a
33 * href="http://www.tbm.tudelft.nl/webstaf/alexandv/index.htm">Alexander
34 * Verbraeck </a>
35 */
36 public class ArcTrack extends Track
37 {
38 /*** the length of the track */
39 private double length;
40
41 /*** the angle of the dx/dy of the track */
42 double theta = 0.0;
43
44 /*** the radius of the arc */
45 private double radius;
46
47 /*** the center point of the arc */
48 private Point2D center;
49
50 /*** the start angle of the arc */
51 private double startAngle;
52
53 /*** the end angle of the arc */
54 private double endAngle;
55
56 /*** the delta-angle of the arc */
57 private double deltaAngle;
58
59 /*** counter clockwise movement? */
60 private boolean counterClockwise;
61
62 /***
63 * @param name
64 * @param startLink
65 * @param endLink
66 * @param radius
67 * @throws Exception
68 */
69 public ArcTrack(final String name, TrackLinkInterface startLink,
70 TrackLinkInterface endLink, double radius) throws Exception
71 {
72 super(name, startLink, endLink);
73 this.theta = Math.atan2(super.getdy(), super.getdx());
74 this.radius = Math.abs(radius);
75 Point2D start = new Point2D.Double(startLink.getPosition().x, startLink
76 .getPosition().y);
77 Point2D end = new Point2D.Double(endLink.getPosition().x, endLink
78 .getPosition().y);
79 Point2D[] intersection = Circle.intersection(start, this.radius, end,
80 this.radius);
81 if (intersection.length < 2)
82 throw new Exception("ArcTrack " + name
83 + " - points too far apart for radius");
84 this.counterClockwise = (radius < 0);
85 if (this.counterClockwise)
86 this.center = intersection[1];
87 else
88 this.center = intersection[0];
89 this.startAngle = Angle.normalize2Pi(Angle.angle(this.center, start));
90 this.endAngle = Angle.normalize2Pi(Angle.angle(this.center, end));
91 if (this.counterClockwise)
92 {
93 this.deltaAngle = Angle.normalize2Pi(this.endAngle
94 - this.startAngle);
95 this.length = this.radius
96 * Angle.normalize2Pi(this.endAngle - this.startAngle);
97 } else
98 {
99 this.deltaAngle = -Angle.normalize2Pi(this.startAngle
100 - this.endAngle);
101 this.length = this.radius
102 * Angle.normalize2Pi(this.startAngle - this.endAngle);
103 }
104 Logger.finest(this, "ArcTrack", "from:" + start.getX() + ","
105 + start.getY() + " to:" + end.getX() + "," + end.getY()
106 + " - length=" + this.length + " [as,ae=" + this.startAngle
107 + "," + this.endAngle + "]" + "delta-a=" + this.deltaAngle);
108 }
109
110 /***
111 * @see nl.tudelft.simulation.traffic.track.TrackInterface#getLocationOfProgression(double)
112 */
113 public DirectedPoint getLocationOfProgression(final double progression)
114 {
115 Point3d startPoint = this.startLink.getPosition();
116 Point3d endPoint = this.endLink.getPosition();
117 double delta = progression / this.length;
118 double angle = Angle.normalize2Pi(this.startAngle + delta
119 * this.deltaAngle);
120 double x = this.center.getX() + this.radius * Math.cos(angle);
121 double y = this.center.getY() + this.radius * Math.sin(angle);
122 double z = startPoint.z + delta * (endPoint.z - startPoint.z);
123 return new DirectedPoint(x, y, z, 0.0, 0.0, 0.0);
124 }
125
126 /***
127 * @see nl.tudelft.simulation.dsol.animation.LocatableInterface#getBounds()
128 */
129 public Bounds getBounds()
130 {
131 Point3d p = this.startLink.getPosition();
132 Point3d q = this.endLink.getPosition();
133 return new BoundingBox(new Point3d(0, 0, 0), new Point3d(q.x - p.x, q.y
134 - p.y, q.z - p.z));
135 }
136
137 /***
138 * @return Returns the radius.
139 */
140 public double getRadius()
141 {
142 return this.radius;
143 }
144
145 /***
146 * @return Returns the center.
147 */
148 public Point2D getCenter()
149 {
150 return this.center;
151 }
152
153 /***
154 * @return Returns the endAngle.
155 */
156 public double getEndAngle()
157 {
158 return this.endAngle;
159 }
160
161 /***
162 * @return Returns the startAngle.
163 */
164 public double getStartAngle()
165 {
166 return this.startAngle;
167 }
168
169 /***
170 * @return Returns counter clockwise drawing direction.
171 */
172 public boolean isCounterClockwise()
173 {
174 return this.counterClockwise;
175 }
176
177 /***
178 * @see nl.tudelft.simulation.traffic.track.TrackInterface#getLength()
179 */
180 public double getLength()
181 {
182 return this.length;
183 }
184 }