|
|
@@ -0,0 +1,80 @@
|
|
|
+# -*- coding: utf-8 -*-
|
|
|
+"""
|
|
|
+Лаба 2, рисунок «Начало трассирования»: схема начала трассы от раздельного
|
|
|
+пункта (Lст/2 + запас a + участок не менее 500 м) до вершины угла поворота ВУ
|
|
|
+с тангенсом T и круговой кривой, вписанной в угол поворота.
|
|
|
+Перерисовано векторно вместо низкого разрешения скана методички.
|
|
|
+"""
|
|
|
+import numpy as np
|
|
|
+import matplotlib
|
|
|
+matplotlib.use('Agg')
|
|
|
+import matplotlib.pyplot as plt
|
|
|
+import matplotlib.font_manager as fm
|
|
|
+fm.fontManager.addfont('C:/Windows/Fonts/GOST2304A.ttf')
|
|
|
+matplotlib.rcParams['font.family'] = 'GOST 2.304 type A'
|
|
|
+matplotlib.rcParams['mathtext.default'] = 'regular'
|
|
|
+matplotlib.rcParams['mathtext.fontset'] = 'custom'
|
|
|
+matplotlib.rcParams['mathtext.rm'] = 'GOST 2.304 type A'
|
|
|
+matplotlib.rcParams['mathtext.it'] = 'GOST 2.304 type A'
|
|
|
+
|
|
|
+BLACK = '#111111'
|
|
|
+fig = plt.figure(figsize=(12.8 / 2.54, 6.4 / 2.54), dpi=300)
|
|
|
+ax = fig.add_axes([0, 0, 1, 1])
|
|
|
+ax.set_aspect('equal'); ax.axis('off')
|
|
|
+ax.set_xlim(0, 10.2); ax.set_ylim(-3.1, 2.5)
|
|
|
+
|
|
|
+# --- трасса: прямая до ВУ и следующее направление под углом 35° вниз -------------
|
|
|
+x_vu, phi, T = 7.2, np.radians(50), 1.3
|
|
|
+d = np.array([np.cos(-phi), np.sin(-phi)])
|
|
|
+x_nk = x_vu - T # начало кривой
|
|
|
+p_kk = np.array([x_vu, 0]) + T * d # конец кривой
|
|
|
+ax.plot([0.8, x_vu], [0, 0], color=BLACK, lw=1.3)
|
|
|
+p_end = np.array([x_vu, 0]) + 1.75 * d
|
|
|
+ax.plot([x_vu, p_end[0]], [0, p_end[1]], color=BLACK, lw=1.3)
|
|
|
+ax.plot(x_vu, 0, marker='+', ms=9, color=BLACK, mew=1.2)
|
|
|
+ax.text(x_vu + 0.12, 0.12, 'ВУ$_1$', fontsize=9, ha='left', va='bottom')
|
|
|
+
|
|
|
+# круговая кривая: R = T / tan(phi/2), центр на перпендикуляре из НК внутрь угла
|
|
|
+R = T / np.tan(phi / 2)
|
|
|
+o = np.array([x_nk, -R])
|
|
|
+t0, t1 = 90, np.degrees(np.arctan2(*(p_kk - o)[::-1]))
|
|
|
+arc = np.radians(np.linspace(t0, t1, 80))
|
|
|
+ax.plot(o[0] + R * np.cos(arc), o[1] + R * np.sin(arc), color=BLACK, lw=1.1,
|
|
|
+ ls=(0, (5, 3)))
|
|
|
+ax.annotate('Круговая кривая,\nвписанная в угол поворота',
|
|
|
+ xy=(o[0] + R * np.cos(np.radians(63)), o[1] + R * np.sin(np.radians(63))),
|
|
|
+ xytext=(6.7, -2.35), fontsize=8, ha='left', va='center',
|
|
|
+ arrowprops=dict(arrowstyle='->', color=BLACK, lw=0.7, shrinkA=2, shrinkB=2))
|
|
|
+
|
|
|
+# --- размерные линии: Lст/2, a, не менее 500 м (под трассой), T (над трассой) ----
|
|
|
+TICK, EXT = 0.08, 0.1
|
|
|
+def tick(x, y):
|
|
|
+ ax.plot([x - TICK, x + TICK], [y - TICK, y + TICK], color=BLACK, lw=1.1,
|
|
|
+ solid_capstyle='butt')
|
|
|
+
|
|
|
+def hdim(x1, x2, y, txt, above=False):
|
|
|
+ for x in (x1, x2):
|
|
|
+ y_end = y + EXT if above else y - EXT
|
|
|
+ ax.plot([x, x], [0, y_end], color=BLACK, lw=0.5, zorder=1)
|
|
|
+ tick(x, y)
|
|
|
+ ax.plot([x1, x2], [y, y], color=BLACK, lw=0.7)
|
|
|
+ ax.annotate('', xy=(x2, y), xytext=(x1, y),
|
|
|
+ arrowprops=dict(arrowstyle='<|-|>', color=BLACK, lw=0.7,
|
|
|
+ mutation_scale=8, shrinkA=0, shrinkB=0))
|
|
|
+ ax.text((x1 + x2) / 2, y + (0.1 if above else -0.1), txt, fontsize=8,
|
|
|
+ ha='center', va='bottom' if above else 'top')
|
|
|
+
|
|
|
+hdim(0.8, 3.0, -0.7, 'L$_ст$/2')
|
|
|
+hdim(3.0, 4.2, -0.7, 'a')
|
|
|
+hdim(4.2, x_nk, -0.7, 'не менее 500 м')
|
|
|
+hdim(x_nk, x_vu, 0.55, 'T', above=True)
|
|
|
+
|
|
|
+# --- стрелка севера ----------------------------------------------------------------
|
|
|
+cx, cy, r = 1.45, 1.65, 0.42
|
|
|
+ax.add_patch(plt.Circle((cx, cy), r, fill=False, color=BLACK, lw=0.8))
|
|
|
+ax.annotate('', xy=(cx, cy + r * 0.8), xytext=(cx, cy - r * 0.8),
|
|
|
+ arrowprops=dict(arrowstyle='-|>', color=BLACK, lw=0.9, mutation_scale=10,
|
|
|
+ shrinkA=0, shrinkB=0))
|
|
|
+
|
|
|
+fig.savefig('assets/images/laba2-nachalo-trassirovaniya.png', dpi=300, facecolor='white')
|
|
|
+print('сохранено: assets/images/laba2-nachalo-trassirovaniya.png')
|