1 package org.opentrafficsim.core.geometry;
2
3 import java.util.List;
4
5 import org.djutils.draw.curve.Flattener2d;
6 import org.djutils.draw.curve.OffsetCurve2d;
7 import org.djutils.draw.curve.OffsetFlattener2d;
8 import org.djutils.draw.function.ContinuousPiecewiseLinearFunction;
9 import org.djutils.draw.line.PolyLine2d;
10 import org.djutils.draw.point.DirectedPoint2d;
11 import org.djutils.draw.point.Point2d;
12 import org.djutils.exceptions.Throw;
13 import org.djutils.math.functions.MathFunction.TupleSt;
14 import org.opentrafficsim.base.geometry.OtsGeometryUtil;
15
16
17
18
19
20
21
22
23
24 public class PolyLineCurve2d implements OffsetCurve2d
25 {
26
27
28 private final PolyLine2d line;
29
30
31 private final double startDirection;
32
33
34 private final double endDirection;
35
36
37
38
39
40
41
42 public PolyLineCurve2d(final PolyLine2d line, final double startDirection, final double endDirection)
43 {
44 this.line = line;
45 this.startDirection = startDirection;
46 this.endDirection = endDirection;
47 }
48
49 @Override
50 public Double getDirection(final double fraction)
51 {
52 return fraction == 0.0 ? this.startDirection
53 : (fraction == 1.0 ? this.endDirection : this.line.getLocation(fraction).dirZ);
54 }
55
56 @Override
57 public double getDirection(final double fraction, final ContinuousPiecewiseLinearFunction of)
58 {
59 return getDirection(fraction) + of.getDerivative(fraction);
60 }
61
62 @Override
63 public DirectedPoint2d getPoint(final double fraction)
64 {
65 return this.line.getLocationFraction(fraction);
66 }
67
68 @Override
69 public DirectedPoint2d getPoint(final double fraction, final ContinuousPiecewiseLinearFunction of)
70 {
71 DirectedPoint2d offsetPoint = OtsGeometryUtil.offsetPoint(getPoint(fraction), of.get(fraction));
72 return new DirectedPoint2d(offsetPoint.x, offsetPoint.y, offsetPoint.dirZ + of.getDerivative(fraction));
73 }
74
75 @Override
76 public double getLength()
77 {
78 return this.line.getLength();
79 }
80
81 @Override
82 public PolyLine2d toPolyLine(final Flattener2d flattener)
83 {
84 return this.line;
85 }
86
87 @Override
88 public PolyLine2d toPolyLine(final OffsetFlattener2d flattener, final ContinuousPiecewiseLinearFunction offsets)
89 {
90 Throw.whenNull(offsets, "Offsets may not be null.");
91 double[] knots = new double[offsets.size()];
92 double[] knotOffset = new double[offsets.size()];
93 int i = 0;
94 for (TupleSt st : offsets)
95 {
96 knots[i] = st.s();
97 knotOffset[i] = st.t();
98 i++;
99 }
100 PolyLine2d offsetLine = OtsGeometryUtil.offsetLine(this.line, knots, knotOffset);
101 Point2d start = OtsGeometryUtil.offsetPoint(getStartPoint(), offsets.get(0.0));
102 Point2d end = OtsGeometryUtil.offsetPoint(getEndPoint(), offsets.get(1.0));
103 List<Point2d> points = offsetLine.getPointList();
104 points.set(0, start);
105 points.set(points.size() - 1, end);
106 return new PolyLine2d(points);
107 }
108
109 }