67 lines
3.0 KiB
Python
67 lines
3.0 KiB
Python
"""Savegame2 30/9: reparationer af AD-vejnettet fundet ved gennemgangen.
|
|
|
|
1. Punkt 19564 (spor til 'P Forage Wagon') lå 5,6 km væk -> midt mellem naboerne.
|
|
2. Biogas Drop 1/2/4/5 var blindgyder (kun vej ind) -> sidste kant gøres tovejs som Drop 3.
|
|
3. Chicken Wait 5: 81° knæk ved 12808 (AD tillader 80°) -> privat spor 12808..12815 lagt om i en blød kurve.
|
|
4. 'Food And More' lå på en afbrudt stump oven på vejen -> markøren flyttes til vejpunkt 8416.
|
|
|
|
Brug: netfix.py <ind.xml> <ud.xml>
|
|
"""
|
|
import math, re, sys, os
|
|
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
|
from adsmooth import read, write, link, dist
|
|
|
|
src, dst = sys.argv[1], sys.argv[2]
|
|
doc = read(src); N = doc["N"]
|
|
mk = {m.group(2): int(float(m.group(1))) for m in re.finditer(r"<mm\d+>\s*<id>([\d.]+)</id>\s*<name>([^<]*)</name>", doc["s"])}
|
|
|
|
# 1
|
|
a, b = N[19563], N[19565]
|
|
assert dist(N[19564], a) > 1000, "19564 ser allerede rigtig ud"
|
|
for ax in "xyz":
|
|
N[19564][ax] = (a[ax] + b[ax]) / 2
|
|
print("19564 ->", round(N[19564]["x"], 2), round(N[19564]["z"], 2))
|
|
|
|
# 2
|
|
for name in ("Biogas Drop 1", "Biogas Drop 2", "Biogas Drop 4", "Biogas Drop 5"):
|
|
w = mk[name]; assert not N[w]["out"], name
|
|
for p in list(N[w]["inc"]):
|
|
link(N, w, p)
|
|
print(name, "tovejs mod", N[w]["out"])
|
|
|
|
# 3 kurve fra 12802 (retning fra 12801) til 12697 (retning mod 12698)
|
|
chain = [12808, 12809, 12810, 12811, 12812, 12813, 12814, 12815]
|
|
for i in chain:
|
|
assert len(N[i]["inc"]) == 1 and len(N[i]["out"]) == 1, i
|
|
P0, P3 = N[12802], N[12697]
|
|
def unit(u, v):
|
|
L = dist(u, v); return ((v["x"] - u["x"]) / L, (v["z"] - u["z"]) / L)
|
|
t0, t3 = unit(N[12801], P0), unit(P3, N[12698])
|
|
seq = [12801, 12802] + chain + [12697, 12698]
|
|
def ang(p, b, c):
|
|
v1 = (N[b]["x"] - N[p]["x"], N[b]["z"] - N[p]["z"]); v2 = (N[c]["x"] - N[b]["x"], N[c]["z"] - N[b]["z"])
|
|
return math.degrees(math.acos(max(-1, min(1, (v1[0] * v2[0] + v1[1] * v2[1]) / (math.hypot(*v1) * math.hypot(*v2))))))
|
|
def shape(k0, k3, g):
|
|
P1 = {"x": P0["x"] + t0[0] * k0, "z": P0["z"] + t0[1] * k0}
|
|
P2 = {"x": P3["x"] - t3[0] * k3, "z": P3["z"] - t3[1] * k3}
|
|
n = len(chain) + 1
|
|
for j, i in enumerate(chain, 1):
|
|
t = (j / n) ** g # g skubber punkterne mod den skarpe ende
|
|
for ax in "xz":
|
|
N[i][ax] = (1 - t) ** 3 * P0[ax] + 3 * (1 - t) ** 2 * t * P1[ax] + 3 * (1 - t) * t * t * P2[ax] + t ** 3 * P3[ax]
|
|
N[i]["y"] = P0["y"] + (P3["y"] - P0["y"]) * t
|
|
return max(ang(*seq[i:i + 3]) for i in range(len(seq) - 2))
|
|
D = dist(P0, P3)
|
|
best = min(((shape(a * D, b * D, g), a, b, g) for a in (0.2, 0.35, 0.5, 0.7, 0.9, 1.2) for b in (0.2, 0.35, 0.5, 0.7, 0.9, 1.2) for g in (0.7, 0.85, 1.0, 1.2)))
|
|
worst = shape(best[1] * D, best[2] * D, best[3])
|
|
print("Chicken Wait 5-kurve: største knæk %.1f°" % worst)
|
|
assert worst <= 45
|
|
|
|
write(doc, dst)
|
|
# 4 markør
|
|
s = open(dst, encoding="utf-8-sig").read()
|
|
s, cnt = re.subn(r"(<id>)8481\.000000(</id>\s*<name>Food And More</name>)", r"\g<1>8416.000000\g<2>", s)
|
|
assert cnt == 1
|
|
open(dst, "wb").write(b"\xef\xbb\xbf" + s.encode("utf-8"))
|
|
print("Food And More -> 8416")
|