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