1 package org.opentrafficsim.road.network.lane;
2
3 import java.util.LinkedHashMap;
4 import java.util.Map;
5
6 import org.djutils.draw.line.PolyLine2d;
7 import org.djutils.draw.line.Polygon2d;
8 import org.djutils.exceptions.Throw;
9 import org.opentrafficsim.base.geometry.OtsLine2d;
10 import org.opentrafficsim.core.geometry.ContinuousLine;
11 import org.opentrafficsim.core.geometry.ContinuousLine.ContinuousDoubleFunction;
12 import org.opentrafficsim.core.geometry.Flattener;
13 import org.opentrafficsim.core.geometry.FractionalLengthData;
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 @SuppressWarnings("javadoc")
29 public record CrossSectionGeometry(OtsLine2d centerLine, Polygon2d contour, ContinuousDoubleFunction offset,
30 ContinuousDoubleFunction width)
31 {
32
33
34
35
36
37 public CrossSectionGeometry
38
39 {
40 Throw.whenNull(centerLine, "Center line may not be null.");
41 Throw.whenNull(contour, "Contour may not be null.");
42 Throw.whenNull(offset, "Offset may not be null.");
43 Throw.whenNull(width, "Width may not be null.");
44 }
45
46
47
48
49
50
51
52
53
54 public static CrossSectionGeometry of(final ContinuousLine designLine, final Flattener flattener,
55 final ContinuousDoubleFunction offset, final ContinuousDoubleFunction width)
56 {
57 PolyLine2d line = designLine.flattenOffset(offset, flattener);
58 Map<Double, Double> leftMap = new LinkedHashMap<>();
59 Map<Double, Double> rightMap = new LinkedHashMap<>();
60 for (double f : offset.getKnots())
61 {
62 leftMap.put(f, offset.apply(f) + .5 * width.apply(f));
63 rightMap.put(f, offset.apply(f) - .5 * width.apply(f));
64 }
65 for (double f : width.getKnots())
66 {
67 leftMap.put(f, offset.apply(f) + .5 * width.apply(f));
68 rightMap.put(f, offset.apply(f) - .5 * width.apply(f));
69 }
70 PolyLine2d left = designLine.flattenOffset(new FractionalLengthData(leftMap), flattener);
71 PolyLine2d right = designLine.flattenOffset(new FractionalLengthData(rightMap), flattener);
72 Polygon2d cont = LaneGeometryUtil.getContour(left, right);
73 return new CrossSectionGeometry(new OtsLine2d(line), cont, offset, width);
74 }
75
76 }