Skip to content

Instantly share code, notes, and snippets.

@edp8489
Created March 14, 2026 23:26
Show Gist options
  • Select an option

  • Save edp8489/d125f4b709f2b8e253e19bce2082613f to your computer and use it in GitHub Desktop.

Select an option

Save edp8489/d125f4b709f2b8e253e19bce2082613f to your computer and use it in GitHub Desktop.
sectionproperties: angled hat section
from sectionproperties.pre.geometry import Geometry
from sectionproperties.pre.pre import Material, DEFAULT_MATERIAL
from sectionproperties.pre.library.primitive_sections import rectangular_section
from math import radians, sin, cos
def angled_hat(
dim_1: float,
dim_2: float,
dim_3: float,
dim_4: float,
dim_5: float,
dim_6: float,
dim_7: float = None,
material: Material = DEFAULT_MATERIAL,
) -> Geometry:
"""
Creates a hat section with angled walls and
dim_1: total height (Y)
dim_2: brim width
dim_3: cap width
dim_4: web thickness
dim_5: cap thickness
dim_6: web angle in degrees, 0 is vertical, 90 is horizontal
dim_7: skin thickness (to close section for torsion constant calculation)
"""
overall_height = dim_1
brim_width = dim_2
cap_width = dim_3
web_thickness = dim_4
cap_thickness = dim_5
web_angle_deg = dim_6
web_angle_rad = radians(web_angle_deg)
# TODO Better validation and throw error instead
if web_angle_deg < 0 or web_angle_deg >= 90:
print(f"ERROR: Web angle ({web_angle_deg}) out of bounds. Value must be in range [0,90) degrees.")
return
# define exterior points from left to right, stopping at midplane
pt_a0_l_bot = (0, 0)
pt_a0_l_top = (0, web_thickness)
pt_a0_r_bot = (brim_width + web_thickness, 0)
pt_a0_r_top = (brim_width, web_thickness)
h2 = overall_height - cap_thickness
h_sl = (overall_height - cap_thickness / 2 - web_thickness / 2) / cos(web_angle_rad)
l_sl = h_sl * sin(web_angle_rad)
l2 = brim_width + l_sl
pt_a1_r_bot = (l2 + web_thickness, h2)
pt_a1_r_top = (l2, overall_height)
midplane_width = l2 + (cap_width / 2)
pt_a2_mid_bot = (midplane_width, h2)
pt_a2_mid_top = (midplane_width, overall_height)
points = [
pt_a0_l_bot,
pt_a0_r_bot,
pt_a1_r_bot,
pt_a2_mid_bot,
pt_a2_mid_top,
pt_a1_r_top,
pt_a0_r_top,
pt_a0_l_top,
]
facets = [(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7), (7, 0)]
# Create half the shape then mirror about the midplane
shape_L = Geometry.from_points(
points=points,
facets=facets,
control_points=[(brim_width / 2, web_thickness / 2)],
material=material
)
shape_R = shape_L.mirror_section(axis="y", mirror_point=(midplane_width, 0))
angled_hat = shape_L + shape_R
# TODO refactor into separate `angled_hat_with_skin()` constructor
if dim_7 is not None:
t_skin = dim_7
bounding_box = angled_hat.calculate_extents()
overall_width = bounding_box[1] - bounding_box[0]
skin = rectangular_section(d=t_skin, b=overall_width).align_to(
other=angled_hat, on="bottom"
)
angled_hat += skin
else:
print(
"WARN: dim_7 (skin thickness) not provided. Shape is open and warping properties cannot be calculated."
)
return angled_hat
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment