street: continental zebra markings at the three signalised crossings
0.5 m white bars with 0.5 m gaps across a 3 m band per crossing, laid 1 cm above the road surface. Makes the mid-block crossing (OSM way 385648319, s=130.1 m) a designated crossing in game. Metadata audit passes (1 sidecar, 0 problems).
This commit is contained in:
1 parent
eb614fe035
commit
cef87b3d31
2 files changed
+44
-2
No files matched your search
Binary file not shown.
@@ -18,6 +18,10 @@ Geometry follows the measured profile rather than a guess:
|
||||
kerb (see `Geo/verification/2026-11-06-cross-sections.md`);
|
||||
* kerbs are flushed to 0.02 m within ±2.5 m of each signalised crossing, with a
|
||||
1.5 m blend, so the crossings are actually usable on foot;
|
||||
* each signalised crossing gets continental zebra markings — 0.5 m white bars
|
||||
with 0.5 m gaps across a 3 m band, laid 1 cm above the road surface — so the
|
||||
mid-block crossing (OSM way 385648319, s ≈ 130 m) reads as a designated
|
||||
crossing in game;
|
||||
* sidewalk widths 4.0 m south and 5.3 m north, from the DEM-derived setback
|
||||
arithmetic;
|
||||
* the DEM supplies every elevation, so the 3.4 m fall and the ~2 % crown come
|
||||
@@ -247,6 +251,44 @@ def main():
|
||||
kerb_faces(SOUTH_GUTTER, "Kerb_South")
|
||||
kerb_faces(NORTH_GUTTER, "Kerb_North")
|
||||
|
||||
# Continental zebra markings: one band per signalised crossing. Bars run
|
||||
# along the road (traffic direction), side by side across the carriageway;
|
||||
# a pedestrian crosses perpendicular to them. Lifted 1 cm above the road
|
||||
# surface (which is itself 2 cm above the DEM) to avoid z-fighting.
|
||||
paint = bpy.data.materials.new("Road_Paint_White")
|
||||
paint.diffuse_color = (0.85, 0.85, 0.85, 1.0)
|
||||
|
||||
def crossing_band(s_c):
|
||||
zone = 3.0 # band length along the road, m
|
||||
w, g = 0.5, 0.5 # stripe width / gap, m
|
||||
span = (SOUTH_GUTTER + 0.2, NORTH_GUTTER - 0.2)
|
||||
verts, faces = [], []
|
||||
n = int(zone // (w + g))
|
||||
for k in range(n):
|
||||
s0 = s_c - zone / 2 + k * (w + g)
|
||||
corners = []
|
||||
for s_edge in (s0, s0 + w):
|
||||
base, normal, _ = at(s_edge)
|
||||
for off in span:
|
||||
x = base[0] + off * normal[0]
|
||||
y = base[1] + off * normal[1]
|
||||
corners.append((len(verts), (x, y, (dem_z(x, y) or 0.0) + 0.03)))
|
||||
# corners order: (s0,off_s), (s0,off_n), (s1,off_s), (s1,off_n)
|
||||
idx = [c[0] for c in corners]
|
||||
verts.extend(c[1] for c in corners)
|
||||
faces.append((idx[0], idx[1], idx[3], idx[2]))
|
||||
mesh = bpy.data.meshes.new("Crossing_Markings")
|
||||
mesh.from_pydata(verts, [], faces)
|
||||
mesh.update()
|
||||
mesh.materials.append(paint)
|
||||
obj = bpy.data.objects.new("Crossing_Markings", mesh)
|
||||
bpy.context.scene.collection.objects.link(obj)
|
||||
return obj
|
||||
|
||||
for s_c in CROSSINGS:
|
||||
band = crossing_band(s_c)
|
||||
print(f"crossing band at s={s_c:.1f}: {len(band.data.polygons)} stripes")
|
||||
|
||||
for obj in (road, sw_s, sw_n):
|
||||
print(f"{obj.name:16} verts {len(obj.data.vertices):5} faces {len(obj.data.polygons):5}")
|
||||
|
||||
|
||||
Reference in new issue
Block a user