1 package org.opentrafficsim.road.network.lane;
2
3 import java.util.LinkedHashMap;
4 import java.util.Map;
5
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.line.Polygon2d;
11 import org.djutils.draw.point.DirectedPoint2d;
12 import org.djutils.exceptions.Throw;
13 import org.djutils.math.functions.MathFunction.TupleSt;
14 import org.opentrafficsim.base.geometry.OtsLine2d;
15 import org.opentrafficsim.base.geometry.OtsShape;
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 public record CrossSectionGeometry(OtsLine2d centerLine, Polygon2d absoluteContour, ContinuousPiecewiseLinearFunction offset,
31 ContinuousPiecewiseLinearFunction width)
32 {
33
34
35
36
37
38 public CrossSectionGeometry
39
40 {
41 Throw.whenNull(centerLine, "centerLine");
42 Throw.whenNull(absoluteContour, "absoluteContour");
43 Throw.whenNull(offset, "offset");
44 Throw.whenNull(width, "width");
45 }
46
47
48
49
50
51
52
53
54
55 public static CrossSectionGeometry of(final OffsetCurve2d designLine, final OffsetFlattener2d flattener,
56 final ContinuousPiecewiseLinearFunction offset, final ContinuousPiecewiseLinearFunction width)
57 {
58 PolyLine2d line = designLine.toPolyLine(flattener, offset);
59 Map<Double, Double> leftMap = new LinkedHashMap<>();
60 Map<Double, Double> rightMap = new LinkedHashMap<>();
61 for (TupleSt st : offset)
62 {
63 leftMap.put(st.s(), st.t() + .5 * width.get(st.s()));
64 rightMap.put(st.s(), st.t() - .5 * width.get(st.s()));
65 }
66 for (TupleSt st : width)
67 {
68 leftMap.put(st.s(), offset.get(st.s()) + .5 * width.get(st.s()));
69 rightMap.put(st.s(), offset.get(st.s()) - .5 * width.get(st.s()));
70 }
71 PolyLine2d left = designLine.toPolyLine(flattener, new ContinuousPiecewiseLinearFunction(leftMap));
72 PolyLine2d right = designLine.toPolyLine(flattener, new ContinuousPiecewiseLinearFunction(rightMap));
73 Polygon2d cont = LaneGeometryUtil.getContour(left, right);
74 return new CrossSectionGeometry(new OtsLine2d(line), cont, offset, width);
75 }
76
77
78
79
80
81 public DirectedPoint2d getLocation()
82 {
83 return centerLine().getLocationFractionExtended(0.5);
84 }
85
86
87
88
89
90 public Polygon2d getRelativeContour()
91 {
92 return new Polygon2d(OtsShape.toRelativeTransform(getLocation()).transform(absoluteContour().iterator()));
93 }
94
95 }