Created
November 8, 2024 00:35
-
-
Save harmoniqpunk/9f5ae182f10c887df670c25cfc373fc2 to your computer and use it in GitHub Desktop.
NACA 23015 and NACA 23012 - Fusion360 Script Python (Cessna 310N)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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())) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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