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