curvedarch / code /vault_shared.py
jpata's picture
up
21d8cb3
Raw
History Blame Contribute Delete
3.27 kB
import math
import numpy as np
# ----------------------------------------
# 1. Shared Configuration
# ----------------------------------------
CONFIG = {
'xy_span': [[0.0, 10.0], [0.0, 10.0]], # Square span for fan vault as per paper
'thickness': 0.2,
'max_rise': 1.5,
'discretisation_level': 40, # For envelope meshes (higher for smoother curves)
'form_discretisation': 10, # Default (legacy)
'form_discretisation_x': 12, # Number of ribs/segments in X direction
'form_discretisation_y': 8, # Number of ribs/segments in Y direction
'solver': 'IPOPT', # Preferred solver
'support_type': 'corners', # 'corners' or 'perimeter'
'vault_type': 'fan' # 'cross' or 'fan'
}
# ----------------------------------------
# 2. Shared Geometric Logic
# ----------------------------------------
def crossvault_middle_hc(x, y, x_span, y_span, hc, tol=1e-6):
"""
Calculate the z-coordinate of the middle surface of a cross vault
using a circular arc quadrant logic.
"""
x0, x1 = x_span
y0, y1 = y_span
rx = (x1 - x0) / 2
ry = (y1 - y0) / 2
z = np.zeros(len(x))
for i in range(len(x)):
xi, yi = x[i], y[i]
xi = max(x0, min(x1, xi))
yi = max(y0, min(y1, yi))
# Quadrant logic for crossvault
if yi <= y0 + (y1 - y0) / (x1 - x0) * (xi - x0) + tol and yi >= y1 - (y1 - y0) / (x1 - x0) * (xi - x0) - tol:
dx = abs(xi - (x0 + rx))
z[i] = hc * math.sqrt(max(0, 1 - (dx/rx)**2))
elif yi >= y0 + (y1 - y0) / (x1 - x0) * (xi - x0) - tol and yi >= y1 - (y1 - y0) / (x1 - x0) * (xi - x0) - tol:
dy = abs(yi - (y0 + ry))
z[i] = hc * math.sqrt(max(0, 1 - (dy/ry)**2))
elif yi >= y0 + (y1 - y0) / (x1 - x0) * (xi - x0) - tol and yi <= y1 - (y1 - y0) / (x1 - x0) * (xi - x0) + tol:
dx = abs(xi - (x0 + rx))
z[i] = hc * math.sqrt(max(0, 1 - (dx/rx)**2))
elif yi <= y0 + (y1 - y0) / (x1 - x0) * (xi - x0) + tol and yi <= y1 - (y1 - y0) / (x1 - x0) * (xi - x0) + tol:
dy = abs(yi - (y0 + ry))
z[i] = hc * math.sqrt(max(0, 1 - (dy/ry)**2))
return z
def fanvault_middle_hc(x, y, x_span, y_span, hc):
"""
Calculate the z-coordinate of the middle surface of a fan vault.
The surface is a union of four surfaces of revolution (one at each corner).
"""
x0, x1 = x_span
y0, y1 = y_span
xm = (x0 + x1) / 2
ym = (y0 + y1) / 2
# Distance from corner to center
rmax = math.sqrt((xm - x0)**2 + (ym - y0)**2)
# Circular profile radius
R = (rmax**2 + hc**2) / (2 * hc)
z = np.zeros(len(x))
for i in range(len(x)):
xi, yi = x[i], y[i]
# Find nearest corner
if xi <= xm:
xc = x0
else:
xc = x1
if yi <= ym:
yc = y0
else:
yc = y1
r = math.sqrt((xi - xc)**2 + (yi - yc)**2)
# Profile: reaching hc at rmax
# We ensure it doesn't exceed hc by clipping r
r_eff = min(r, rmax)
# z(r) = sqrt(R^2 - (rmax - r)^2) - (R - hc)
z[i] = math.sqrt(max(0, R**2 - (rmax - r_eff)**2)) - (R - hc)
return z