1 package org.opentrafficsim.base.geometry;
2
3 import java.util.List;
4
5 import org.djunits.value.vdouble.scalar.Direction;
6 import org.djutils.draw.line.PolyLine2d;
7 import org.djutils.draw.line.Ray2d;
8 import org.djutils.draw.point.DirectedPoint2d;
9 import org.djutils.draw.point.Point2d;
10 import org.djutils.exceptions.Throw;
11 import org.opentrafficsim.base.geometry.FractionalProjectionHelper.FractionalFallback;
12
13
14
15
16
17
18
19 public class DirectionalPolyLine extends OtsLine2d
20 {
21
22 private final Direction startDirection;
23
24
25 private final Direction endDirection;
26
27
28
29
30
31
32
33 public DirectionalPolyLine(final PolyLine2d line, final Direction startDirection, final Direction endDirection)
34 {
35 super(line);
36 Throw.whenNull(startDirection, "startDirection");
37 Throw.whenNull(endDirection, "endDirection");
38 this.startDirection = startDirection;
39 this.endDirection = endDirection;
40 }
41
42
43
44
45
46
47 public DirectionalPolyLine directionalOffsetLine(final double offset)
48 {
49 PolyLine2d offsetLine = offsetLine(offset);
50 DirectedPoint2d start = new DirectedPoint2d(getFirst().x, getFirst().y, this.startDirection.si);
51 DirectedPoint2d end = new DirectedPoint2d(getLast().x, getLast().y, this.endDirection.si);
52 List<Point2d> points = offsetLine.getPointList();
53 points.set(0, OtsGeometryUtil.offsetPoint(start, offset));
54 points.set(points.size() - 1, OtsGeometryUtil.offsetPoint(end, offset));
55 return new DirectionalPolyLine(new PolyLine2d(0.0, points), this.startDirection, this.endDirection);
56 }
57
58
59
60
61
62
63
64 public DirectionalPolyLine directionalOffsetLine(final double startOffset, final double endOffset)
65 {
66 PolyLine2d start = directionalOffsetLine(startOffset);
67 PolyLine2d end = directionalOffsetLine(endOffset);
68 return new DirectionalPolyLine(start.transitionLine(end, (f) -> f), this.startDirection, this.endDirection);
69 }
70
71 @Override
72 public DirectionalPolyLine extractFractional(final double start, final double end)
73 {
74 return new DirectionalPolyLine(super.extractFractional(start, end), Direction.ofSI(getLocationFraction(start).dirZ),
75 Direction.ofSI(getLocationFraction(end).dirZ));
76 }
77
78 @Override
79 public Ray2d getLocationFraction(final double fraction)
80 {
81 Ray2d ray = new Ray2d(super.getLocationFraction(fraction));
82 if (fraction == 0.0)
83 {
84 ray = new Ray2d(ray, this.startDirection.si);
85 }
86 else if (fraction == 1.0)
87 {
88 ray = new Ray2d(ray, this.endDirection.si);
89 }
90 return ray;
91 }
92
93
94
95
96
97
98
99
100 public double projectFractional(final double x, final double y, final FractionalFallback fallback)
101 {
102 return projectFractionalAt(this.startDirection, this.endDirection, x, y, fallback);
103 }
104
105
106
107
108
109 public Direction getStartDirection()
110 {
111 return this.startDirection;
112 }
113
114
115
116
117
118 public Direction getEndDirection()
119 {
120 return this.endDirection;
121 }
122 }