1 package org.opentrafficsim.road.network;
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
39
40
41
42 public CrossSectionGeometry
43
44 {
45 Throw.whenNull(centerLine, "centerLine");
46 Throw.whenNull(absoluteContour, "absoluteContour");
47 Throw.whenNull(offset, "offset");
48 Throw.whenNull(width, "width");
49 }
50
51
52
53
54
55
56
57
58
59 public static CrossSectionGeometry of(final OffsetCurve2d designLine, final OffsetFlattener2d flattener,
60 final ContinuousPiecewiseLinearFunction offset, final ContinuousPiecewiseLinearFunction width)
61 {
62 PolyLine2d line = designLine.toPolyLine(flattener, offset);
63 Map<Double, Double> leftMap = new LinkedHashMap<>();
64 Map<Double, Double> rightMap = new LinkedHashMap<>();
65 for (TupleSt st : offset)
66 {
67 leftMap.put(st.s(), st.t() + .5 * width.get(st.s()));
68 rightMap.put(st.s(), st.t() - .5 * width.get(st.s()));
69 }
70 for (TupleSt st : width)
71 {
72 leftMap.put(st.s(), offset.get(st.s()) + .5 * width.get(st.s()));
73 rightMap.put(st.s(), offset.get(st.s()) - .5 * width.get(st.s()));
74 }
75 PolyLine2d left = designLine.toPolyLine(flattener, new ContinuousPiecewiseLinearFunction(leftMap));
76 PolyLine2d right = designLine.toPolyLine(flattener, new ContinuousPiecewiseLinearFunction(rightMap));
77 Polygon2d cont = LaneGeometryUtil.getContour(left, right);
78 return new CrossSectionGeometry(new OtsLine2d(line), cont, offset, width);
79 }
80
81
82
83
84
85 public DirectedPoint2d getLocation()
86 {
87 return centerLine().getLocationFractionExtended(0.5);
88 }
89
90
91
92
93
94 public Polygon2d getRelativeContour()
95 {
96 return new Polygon2d(0.0, OtsShape.toRelativeTransform(getLocation()).transform(absoluteContour().iterator()));
97 }
98
99 }