Skip to content

Instantly share code, notes, and snippets.

@harmoniqpunk
Created November 8, 2024 00:35
Show Gist options
  • Save harmoniqpunk/9f5ae182f10c887df670c25cfc373fc2 to your computer and use it in GitHub Desktop.
Save harmoniqpunk/9f5ae182f10c887df670c25cfc373fc2 to your computer and use it in GitHub Desktop.
NACA 23015 and NACA 23012 - Fusion360 Script Python (Cessna 310N)
import adsk.core, adsk.fusion, adsk.cam, traceback, math
def run(context):
ui = None
try:
app = adsk.core.Application.get()
ui = app.userInterface
design = app.activeProduct
# Get the active sketch
sketch_airfoil = adsk.fusion.Sketch.cast(app.activeEditObject)
if not sketch_airfoil:
ui.messageBox('Please select a sketch first')
return
# NACA 23012 airfoil parameters
max_camber = 0.03 # 3% of chord length
max_camber_position = 0.3 # 30% of chord length
max_thickness = 0.12 # 12% of chord length
# Number of points to generate for the airfoil
num_points = 100
chord_length = 119.6 # Set the chord length to 990.6 mm
# Function to calculate the thickness distribution
def thickness_distribution(x):
return (5 * max_thickness) * (
0.2969 * math.sqrt(x) -
0.1260 * x -
0.3516 * x**2 +
0.2843 * x**3 -
0.1015 * x**4
)
# Function to calculate camber line
def camber_line(x):
if x < max_camber_position:
return (max_camber / (max_camber_position**2)) * (2 * max_camber_position * x - x**2)
else:
return (max_camber / ((1 - max_camber_position)**2)) * ((1 - 2 * max_camber_position) + 2 * max_camber_position * x - x**2)
# Function to calculate the slope of the camber line
def camber_line_slope(x):
if x < max_camber_position:
return (2 * max_camber / (max_camber_position**2)) * (max_camber_position - x)
else:
return (2 * max_camber / ((1 - max_camber_position)**2)) * (max_camber_position - x)
# Generate upper and lower surface points
upper_surface_coords = []
lower_surface_coords = []
for i in range(num_points + 1):
x = (i / num_points) * chord_length # Scale x-coordinate to match chord length in mm
y_camber = camber_line(x / chord_length) * chord_length # Scale camber line to mm
dyc_dx = camber_line_slope(x / chord_length)
theta = math.atan(dyc_dx)
y_thickness = thickness_distribution(x / chord_length) * chord_length
# Upper surface points
x_upper = x - y_thickness * math.sin(theta)
y_upper = y_camber + y_thickness * math.cos(theta)
upper_surface_coords.append((x_upper, y_upper))
for i in range(num_points, -1, -1):
x = (i / num_points) * chord_length # Scale x-coordinate to match chord length in mm
y_camber = camber_line(x / chord_length) * chord_length # Scale camber line to mm
dyc_dx = camber_line_slope(x / chord_length)
theta = math.atan(dyc_dx)
y_thickness = thickness_distribution(x / chord_length) * chord_length
# Lower surface points
x_lower = x + y_thickness * math.sin(theta)
y_lower = y_camber - y_thickness * math.cos(theta)
lower_surface_coords.append((x_lower, y_lower))
# Convert coordinates to Point3D objects and adjust for sketch
upper_points = []
for coord in upper_surface_coords:
point = adsk.core.Point3D.create(coord[0] - chord_length / 2, -coord[1], 0)
upper_points.append(point)
lower_points = []
for coord in lower_surface_coords:
point = adsk.core.Point3D.create(coord[0] - chord_length / 2, -coord[1], 0)
lower_points.append(point)
# Create ObjectCollections for the points
upper_point_collection = adsk.core.ObjectCollection.create()
for point in upper_points:
upper_point_collection.add(point)
lower_point_collection = adsk.core.ObjectCollection.create()
for point in lower_points:
lower_point_collection.add(point)
# Create splines for upper and lower surfaces
upper_spline = sketch_airfoil.sketchCurves.sketchFittedSplines.add(upper_point_collection)
lower_spline = sketch_airfoil.sketchCurves.sketchFittedSplines.add(lower_point_collection)
# Connect the endpoints to close the airfoil profile
sketch_airfoil.sketchCurves.sketchLines.addByTwoPoints(upper_points[0], lower_points[-1])
sketch_airfoil.sketchCurves.sketchLines.addByTwoPoints(upper_points[-1], lower_points[0])
ui.messageBox('NACA 23012 airfoil created successfully with smooth splines!')
except:
if ui:
ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
import adsk.core, adsk.fusion, adsk.cam, traceback, math
def run(context):
ui = None
try:
app = adsk.core.Application.get()
ui = app.userInterface
design = app.activeProduct
# Get the active sketch
sketch_airfoil = adsk.fusion.Sketch.cast(app.activeEditObject)
if not sketch_airfoil:
ui.messageBox('Please select a sketch first')
return
# NACA 23015 airfoil parameters
max_camber = 0.03 # 3% of chord length
max_camber_position = 0.3 # 30% of chord length
max_thickness = 0.15 # 15% of chord length
# Number of points to generate for the airfoil
num_points = 100
chord_length = 171 # Set the chord length to 2082.8 mm
# Function to calculate the thickness distribution
def thickness_distribution(x):
return (5 * max_thickness) * (
0.2969 * math.sqrt(x) -
0.1260 * x -
0.3516 * x**2 +
0.2843 * x**3 -
0.1015 * x**4
)
# Function to calculate camber line
def camber_line(x):
if x < max_camber_position:
return (max_camber / (max_camber_position**2)) * (2 * max_camber_position * x - x**2)
else:
return (max_camber / ((1 - max_camber_position)**2)) * ((1 - 2 * max_camber_position) + 2 * max_camber_position * x - x**2)
# Function to calculate the slope of the camber line
def camber_line_slope(x):
if x < max_camber_position:
return (2 * max_camber / (max_camber_position**2)) * (max_camber_position - x)
else:
return (2 * max_camber / ((1 - max_camber_position)**2)) * (max_camber_position - x)
# Generate upper and lower surface points
upper_surface_coords = []
lower_surface_coords = []
for i in range(num_points + 1):
x = (i / num_points) * chord_length # Scale x-coordinate to match chord length in mm
y_camber = camber_line(x / chord_length) * chord_length # Scale camber line to mm
dyc_dx = camber_line_slope(x / chord_length)
theta = math.atan(dyc_dx)
y_thickness = thickness_distribution(x / chord_length) * chord_length
# Upper surface points
x_upper = x - y_thickness * math.sin(theta)
y_upper = y_camber + y_thickness * math.cos(theta)
upper_surface_coords.append((x_upper, y_upper))
for i in range(num_points, -1, -1):
x = (i / num_points) * chord_length # Scale x-coordinate to match chord length in mm
y_camber = camber_line(x / chord_length) * chord_length # Scale camber line to mm
dyc_dx = camber_line_slope(x / chord_length)
theta = math.atan(dyc_dx)
y_thickness = thickness_distribution(x / chord_length) * chord_length
# Lower surface points
x_lower = x + y_thickness * math.sin(theta)
y_lower = y_camber - y_thickness * math.cos(theta)
lower_surface_coords.append((x_lower, y_lower))
# Convert coordinates to Point3D objects and adjust for sketch
upper_points = []
for coord in upper_surface_coords:
point = adsk.core.Point3D.create(coord[0] - chord_length / 2, -coord[1], 0)
upper_points.append(point)
lower_points = []
for coord in lower_surface_coords:
point = adsk.core.Point3D.create(coord[0] - chord_length / 2, -coord[1], 0)
lower_points.append(point)
# Create ObjectCollections for the points
upper_point_collection = adsk.core.ObjectCollection.create()
for point in upper_points:
upper_point_collection.add(point)
lower_point_collection = adsk.core.ObjectCollection.create()
for point in lower_points:
lower_point_collection.add(point)
# Create splines for upper and lower surfaces
upper_spline = sketch_airfoil.sketchCurves.sketchFittedSplines.add(upper_point_collection)
lower_spline = sketch_airfoil.sketchCurves.sketchFittedSplines.add(lower_point_collection)
# Connect the endpoints to close the airfoil profile
sketch_airfoil.sketchCurves.sketchLines.addByTwoPoints(upper_points[0], lower_points[-1])
sketch_airfoil.sketchCurves.sketchLines.addByTwoPoints(upper_points[-1], lower_points[0])
ui.messageBox('NACA 23015 airfoil created successfully with smooth splines!')
except:
if ui:
ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment