# Grouper: the cabin (exec'd by build_grouper.py after gr_doors.py) after SECTION A-A (top right; the bottom-left one for the # overhead panels), the concept's look: a dark cabin with cyan screens, two pilots side by side (no figures). # * deck top z -1.198 (the section's floor slab) from the rear bulkhead (x 715, aft of the doors and the hatch) to where the # lining's bottom rises into the cheek (x 848); the lining (gr_hull.py) is the cabin's wall, 113 mm inside the skin; # * two seats side by side at X +-0.45 (moved in from the drawn +-0.61 so each eye looks straight out through the front # window: gr_measure CABIN), backs at x 800, cushion top z -0.692, back top 0.275, eyes (+-0.45, -1.146, 0.088); # * the console column between them (0.34 m wide) up to z 0.574 with its control box (z -0.575 .. -0.185); a low dashboard # under the front window with a screen for each seat; overhead screens (the section's three); wall control panels at # z -0.81 .. -0.23 outboard of the seats; a ladder under the hatch. # Everything is checked inside the lining (gr_finish.py: no cabin vertex within 5 mm of the skin or the glass). Z_DECK = CABIN["deck_top_z"] SEAT_X = CABIN["seat_lateral"] SEAT_W = CABIN["seat_width"] Y_SEAT_BACK = Yi(CABIN_Y["seat_back_x"]) Y_EYE = Yi(CABIN_Y["eye_x"]) Z_CUSH = CABIN["cushion_top_z"] Z_BACK_TOP = CABIN["seat_back_top_z"] EYE_Z = CABIN["eye_z"] def inner_x(z, y, clear=0.012): """the lining's lateral offset at height z: the hull's main body WITHOUT the pods (the lining follows it, gr_hull.py) at that height, less the lining (measured along the section's normal) and a clearance""" P_, arc_ = prof_at(y, False) best = None for i in range(1, len(P_.p)): (l0, z0), (l1, z1) = P_.p[i - 1], P_.p[i] if (z0 - z) * (z1 - z) <= 0 and z0 != z1: t = (z - z0) / (z1 - z0) lat = l0 + (l1 - l0) * t nz = abs(l1 - l0) / max(1e-9, math.hypot(l1 - l0, z1 - z0)) # the flank's slope: the lining's lateral depth if best is None or lat > best[0]: best = (lat, (LINER + clear) / max(0.3, math.sqrt(max(0.0, 1 - nz * nz)))) if best is None: return 0.05 return best[0] - best[1] def inner_top(x, y, clear=0.012): return hull_z_at(x, y, top=True) - LINER - clear def inner_bot(x, y, clear=0.012): return hull_z_at(x, y, top=False) + LINER + clear # ---- the deck: a slab top from the rear bulkhead to x 848, as wide as the lining at its height Y_DECK0, Y_DECK1 = Yi(716.0), Yi(843.0) rowsd = [] nd = 22 for q in range(nd + 1): y = Y_DECK0 + (Y_DECK1 - Y_DECK0) * math.sin(0.5 * math.pi * q / nd) # rows closer toward the front (the pods' noses) w = min(inner_x(Z_DECK, y, 0.02), inner_x(Z_DECK + 0.02, y, 0.02)) rowsd.append([Vector((x_, y, Z_DECK)) for x_ in [-w + 2 * w * c / 8 for c in range(9)]]) grid_rings(cab, rowsd, CABF, closed_u=False, expect=(nd // 2, 4, (0, 0, 1))) # ---- two seats side by side SEAT_EYES = {} REC = math.radians(10.0) # the backs recline 10 deg aft for sg in (1, -1): cx = sg * SEAT_X yc = Y_SEAT_BACK - 0.30 qbox(cab, (0.26, 0.34, Z_CUSH - 0.11 - Z_DECK), Vector((cx, yc + 0.03, 0.5 * (Z_CUSH - 0.11 + Z_DECK))), CABD, bevel=0.01) qbox(cab, (0.40, 0.46, 0.04), Vector((cx, yc + 0.03, Z_DECK + 0.02)), CABD, bevel=0.008) qbox(cab, (SEAT_W, 0.55, 0.10), Vector((cx, yc - 0.01, Z_CUSH - 0.05)), SEAT, bevel=0.025) hb = Z_BACK_TOP - (Z_CUSH - 0.02) up = Vector((0, math.sin(REC), math.cos(REC))) base = Vector((cx, Y_SEAT_BACK + 0.02, Z_CUSH - 0.02)) qbox(cab, (SEAT_W, 0.11, hb), base + up * (hb * 0.5) + Vector((0, 0.04, 0)), SEAT, rot=(-REC, 0, 0), bevel=0.03) qbox(cab, (0.30, 0.10, 0.20), base + up * (hb - 0.05) + Vector((0, -0.02, 0)), SEAT, rot=(-REC, 0, 0), bevel=0.03) for side in (1, -1): # armrests, a side stick on the outboard one ax = cx + side * (SEAT_W / 2 - 0.04) qbox(cab, (0.07, 0.36, 0.06), Vector((ax, yc - 0.02, Z_CUSH + 0.17)), SEAT, bevel=0.015) qbox(cab, (0.04, 0.06, 0.17), Vector((ax, yc + 0.12, Z_CUSH + 0.08)), CABD, bevel=0.01) qcyl(cab, 0.018, 0.13, Vector((cx + sg * (SEAT_W / 2 - 0.04), yc - 0.15, Z_CUSH + 0.26)), CABD, segs=8, r2=0.014) SEAT_EYES[sg] = Vector((cx, Y_EYE, EYE_Z)) # a footrest ahead of the seat, on the deck's front edge qbox(cab, (0.36, 0.05, 0.18), Vector((cx * 0.92, Y_DECK1 + 0.10, Z_DECK + 0.12)), CABD, rot=(math.radians(-35), 0, 0), bevel=0.01) # ---- the console column between the seats, its control box, two screens facing the seats CH = CABIN["console_half"] Z_CON = CABIN["console_top_z"] yc0, yc1 = Y_SEAT_BACK - 0.06, Y_SEAT_BACK - 0.46 qbox(cab, (2 * CH, abs(yc1 - yc0), Z_CON - Z_DECK), Vector((0, 0.5 * (yc0 + yc1), 0.5 * (Z_CON + Z_DECK))), CABD, bevel=0.02) zb0, zb1 = CABIN["console_box_z"] qbox(cab, (2 * CH + 0.06, abs(yc1 - yc0) + 0.06, zb1 - zb0), Vector((0, 0.5 * (yc0 + yc1) - 0.03, 0.5 * (zb0 + zb1))), CABD, bevel=0.02) for sg in (1, -1): qbox(cab, (0.012, 0.30, 0.20), Vector((sg * (CH + 0.007), 0.5 * (yc0 + yc1), Z_CON - 0.20)), SCREEN, rot=(0, 0, 0), bevel=0.003) qbox(cab, (0.014, 0.26, 0.14), Vector((sg * (CH + 0.037), 0.5 * (yc0 + yc1) - 0.03, 0.5 * (zb0 + zb1) + 0.02)), SCREEN, bevel=0.003) # ---- the dashboard under the front window: a low desk across the nose with a screen for each seat Y_DB = Yi(866.0) z_db_top = -0.12 w_db = min(inner_x(z_db_top, Y_DB - 0.15), inner_x(-0.30, Y_DB - 0.15)) - 0.02 zf_ = max(inner_bot(x_, y_, 0.02) for x_ in (-w_db, -0.5 * w_db, 0.0, 0.5 * w_db, w_db) for y_ in (Y_DB - 0.15, Y_DB, Y_DB + 0.15)) qbox(cab, (2 * w_db, 0.30, z_db_top - zf_), Vector((0, Y_DB, 0.5 * (z_db_top + zf_))), CABD, bevel=0.02) for sg in (1, -1): qbox(cab, (0.34, 0.02, 0.20), Vector((sg * SEAT_X * 0.9, Y_DB + 0.17, z_db_top + 0.05)), SCREEN, rot=(math.radians(25), 0, 0), bevel=0.004) qbox(cab, (0.30, 0.14, 0.03), Vector((0, Y_DB + 0.10, z_db_top + 0.015)), CABD, bevel=0.006) # ---- overhead screens (the section's three: two over the seats, one in the middle), hanging from the ceiling ahead of the eyes Y_OH = Y_EYE - 0.24 zo0, zo1 = CABIN["overhead_z"] for sg in (1, -1): xo0 = SEAT_X - 0.22 xo1 = min(SEAT_X + 0.24, inner_x(zo1, Y_OH, 0.03)) c = Vector((sg * 0.5 * (xo0 + xo1), Y_OH, 0.5 * (zo0 + zo1))) qbox(cab, (xo1 - xo0, 0.03, zo1 - zo0), c, CABD, rot=(math.radians(-28), 0, 0), bevel=0.008) qbox(cab, (xo1 - xo0 - 0.04, 0.006, zo1 - zo0 - 0.04), c + Vector((0, 0.018 * math.cos(math.radians(28)), -0.018 * math.sin(math.radians(28)))), SCREEN, rot=(math.radians(-28), 0, 0)) zt_ = inner_top(sg * SEAT_X, Y_OH, 0.0) qcyl(cab, 0.012, zt_ - zo1 + 0.02, Vector((sg * SEAT_X, Y_OH, 0.5 * (zt_ + zo1))), CABD, segs=8) hc = CABIN["overhead_centre_half"] zc0, zc1 = Zs(112.0), Zs(103.0) qbox(cab, (2 * hc, 0.03, zc1 - zc0), Vector((0, Y_OH - 0.05, 0.5 * (zc0 + zc1))), CABD, rot=(math.radians(-28), 0, 0), bevel=0.008) qbox(cab, (2 * hc - 0.04, 0.006, zc1 - zc0 - 0.03), Vector((0, Y_OH - 0.05 + 0.016, 0.5 * (zc0 + zc1) - 0.009)), SCREEN, rot=(math.radians(-28), 0, 0)) zt_ = inner_top(0.0, Y_OH - 0.05, 0.0) qcyl(cab, 0.012, zt_ - zc1 + 0.02, Vector((0, Y_OH - 0.05, 0.5 * (zt_ + zc1))), CABD, segs=8) # ---- wall control panels outboard of the seats zw0, zw1 = CABIN["wall_panel_z"] for sg in (1, -1): yw = Y_SEAT_BACK - 0.30 xw = min(inner_x(zw0, yw), inner_x(zw1, yw)) - 0.06 qbox(cab, (0.08, 0.40, zw1 - zw0), Vector((sg * xw, yw, 0.5 * (zw0 + zw1))), CABD, bevel=0.012) qbox(cab, (0.006, 0.30, 0.22), Vector((sg * (xw - 0.043), yw, 0.5 * (zw0 + zw1) + 0.08)), SCREEN) # ---- the ladder under the hatch (on the bore's aft side, standing off the rear bulkhead) Y_LAD = Y_CL + 0.40 z_lt = 0.98 for sx in (-0.20, 0.20): tube(cab, [Vector((sx, Y_LAD, Z_DECK)), Vector((sx, Y_LAD, z_lt))], 0.018, CABD, sides=8) yb_ = Yi(X_BULK) - 0.012 rrect_bar(cab, Vector((sx, Y_LAD + 0.015, z_lt - 0.10)), Vector((sx, yb_, z_lt - 0.10)), 0.012, 0.012, 0.004, CABD) rrect_bar(cab, Vector((sx, Y_LAD + 0.015, Z_DECK + 0.40)), Vector((sx, yb_, Z_DECK + 0.40)), 0.012, 0.012, 0.004, CABD) for q in range(7): z = Z_DECK + 0.30 + 0.30 * q tube(cab, [Vector((-0.20, Y_LAD, z)), Vector((0.20, Y_LAD, z))], 0.014, CABD, sides=8) REPORT["cabin"] = {"seats_x": SEAT_X, "eyes": {("L" if s > 0 else "R"): [round(c, 3) for c in v] for s, v in SEAT_EYES.items()}, "deck_z": round(Z_DECK, 3)}