Skip to content

Instantly share code, notes, and snippets.

@gongfan99
Last active October 5, 2025 23:57
Show Gist options
  • Select an option

  • Save gongfan99/8ed7603b451e87682cb4dd7ea940d6b5 to your computer and use it in GitHub Desktop.

Select an option

Save gongfan99/8ed7603b451e87682cb4dd7ea940d6b5 to your computer and use it in GitHub Desktop.
Demonstrate the Gordon surface with build123d - an airliner fuselage
"""
Simple example demonstrating Gordon curve interpolation with build123d.
"""
# %%
from build123d import *
from ocp_vscode import show_all, show, Camera, set_defaults
set_defaults(reset_camera=Camera.KEEP, helper_scale=5)
# %%
# step#1 create the top guide line and bottom guide line (they are from nose to tail)
top_guide_points = [
(0, 0, 1.47),
(0, 1, 2.21),
(0, 2.2, 2.94),
(0, 3, 3.68),
(0, 4, 4.56),
(0, 5, 5.15),
(0, 7, 5.70),
(0, 10, 6.05),
(0, 15, 6.25),
(0, 30, 6.25),
(0, 50, 6.21),
(0, 60, 6.10),
(0, 74.5, 4.96),
]
bottom_guide_points = [
(0, 0, -0.37),
(0, 1, -0.92),
(0, 2.2, -1.32),
(0, 3, -1.54),
(0, 4, -1.77),
(0, 5, -1.91),
(0, 7, -2.02),
(0, 10, -2.10),
(0, 15, -2.13),
(0, 30, -2.10),
(0, 48, -2.10),
(0, 50, -2.06),
(0, 52, -1.91),
(0, 60, -0.55),
(0, 68, 1.47),
(0, 74.5, 3.49),
]
guide1 = Spline(top_guide_points) # top guide
guide2 = Spline(bottom_guide_points) # bottom guide
# step#2 create all the profiles. They are the sections of the fuselage.
# For simplicity, we use circles but you can also use Spline to be more accurate
def circle_by_2_point(p1: Vector, p2: Vector):
center = (p1 + p2) / 2
loc1 = Location(center, (90 + Vector(0, 0, 1).get_signed_angle(p2 - p1), 0, 0))
c1 = CenterArc(center=(0,0,0), radius=abs(p1-p2)/2, start_angle=0, arc_size=360)
return c1.locate(loc1)
profile_section_points = [0, 5, 10, 30, 50, top_guide_points[-1][1]]
profiles: list[Edge] = []
for section_point in profile_section_points:
point1 = guide1.intersect(Plane((0, section_point, 0), z_dir=(0, -1, 0)))
point2 = guide2.intersect(Plane((0, section_point, 0), z_dir=(0, -1, 0)))
if point1 is not None and point2 is not None:
vertex1 = point1.vertex()
vertex2 = point2.vertex()
if vertex1 is not None and vertex2 is not None:
profiles.append(circle_by_2_point(vertex1.center(), vertex2.center()))
# step#3 create the rest of the guides.
# We only add two more guides but you can add more by adding guide_points
guide_points = [0]
guides = [guide1, guide2]
for u in guide_points:
guide3 = Spline([p@u for p in profiles])
guide4 = guide3.mirror(Plane.YZ)
guides.extend([guide3, guide4])
# step#4 create gordon surface
face10 = Face.make_gordon_surface(
profiles, guides
)
# step#5 add small patches at the nose and tail
# then make shell and solid
edge20 = (face10.edges() > Axis.Y)[0]
face20 = Face.make_surface_patch([(edge20, face10, ContinuityLevel.C2)])
edge30 = (face10.edges() < Axis.Y)[0]
face30 = Face.make_surface_patch([(edge30, face10, ContinuityLevel.C0)])
shell10 = Shell((face10, face20, face30))
solid10 = Solid(shell10)
show(solid10, *profiles, *guides)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment