# RCAIDE/Library/Plots/Geometry/plot_3d_fuselage.py
#
#
# Created: Jul 2023, M. Clarke
# ----------------------------------------------------------------------------------------------------------------------
# IMPORT
# ----------------------------------------------------------------------------------------------------------------------
from RCAIDE.Framework.Core import Data
from RCAIDE.Library.Plots.Geometry.Common.contour_surface_slice import contour_surface_slice
import numpy as np
# ----------------------------------------------------------------------------------------------------------------------
# PLOTS
# ----------------------------------------------------------------------------------------------------------------------
[docs]
def plot_3d_fuselage(plot_data, fuselage, tessellation = 24, color_map = 'teal'):
"""
Creates a 3D visualization of a fuselage surface using tessellated panels.
Parameters
----------
plot_data : list
Collection of plot vertices to be rendered
fuselage : Fuselage
RCAIDE fuselage data structure containing geometry information
tessellation : int, optional
Number of points to use in circumferential discretization (default: 24)
color_map : str, optional
Color specification for the fuselage surface (default: 'teal')
Returns
-------
plot_data : list
Updated collection of plot vertices including fuselage surface
Notes
-----
Creates a 3D surface by generating points along fuselage segments and
creating surface panels between adjacent cross-sections.
**Major Assumptions**
* Fuselage cross-sections are super-elliptical
* Surface is continuous between segments
* Tessellation is uniform around circumference
See Also
--------
generate_3d_fuselage_points : Function to generate fuselage surface points
"""
G = generate_3d_fuselage_points(fuselage,tessellation = 24 )
num_fus_segs = len(G.PTS[:,0,0])
if num_fus_segs > 0:
tesselation = len(G.PTS[0,:,0])
for i_seg in range(num_fus_segs-1):
for i_tes in range(tesselation-1):
X = np.array([[G.PTS[i_seg ,i_tes,0],G.PTS[i_seg+1,i_tes ,0]],
[G.PTS[i_seg ,i_tes+1,0],G.PTS[i_seg+1,i_tes+1,0]]])
Y = np.array([[G.PTS[i_seg ,i_tes ,1],G.PTS[i_seg+1,i_tes ,1]],
[G.PTS[i_seg ,i_tes+1,1],G.PTS[i_seg+1,i_tes+1,1]]])
Z = np.array([[G.PTS[i_seg ,i_tes ,2],G.PTS[i_seg+1,i_tes ,2]],
[G.PTS[i_seg ,i_tes+1,2],G.PTS[i_seg+1,i_tes+1,2]]])
values = np.ones_like(X)
verts = contour_surface_slice(X, Y, Z,values,color_map )
plot_data.append(verts)
return plot_data
[docs]
def generate_3d_fuselage_points(fuselage, tessellation = 24):
"""
Generates 3D coordinate points that define a fuselage surface.
Parameters
----------
fuselage : Fuselage
RCAIDE fuselage data structure containing geometry information
tessellation : int, optional
Number of points to use in circumferential discretization (default: 24)
Returns
-------
G : Data
Data structure containing generated points
- PTS : ndarray
Array of shape (num_segments, tessellation, 3) containing
x,y,z coordinates of surface points
Notes
-----
Points are generated by creating super-elliptical cross-sections at each segment
and positioning them according to segment locations.
**Major Assumptions**
* Cross-sections lie in y-z plane
* Segments are ordered from nose to tail
* Origin is at the nose of the fuselage
See Also
--------
plot_3d_fuselage : Function to visualize the generated surface
"""
num_fus_segs = len(fuselage.segments.keys())
fuselage_points = np.zeros((num_fus_segs,tessellation ,3))
if num_fus_segs > 0:
for i_seg, segment in enumerate(fuselage.segments):
a = segment.width/2
b = segment.height/2
n = segment.curvature
theta = np.linspace(0,2*np.pi,tessellation)
fus_ypts = (abs((np.cos(theta)))**(2/n))*a * ((np.cos(theta)>0)*1 - (np.cos(theta)<0)*1)
fus_zpts = (abs((np.sin(theta)))**(2/n))*b * ((np.sin(theta)>0)*1 - (np.sin(theta)<0)*1)
fuselage_points[i_seg,:,0] = segment.percent_x_location*fuselage.lengths.total + fuselage.origin[0][0]
fuselage_points[i_seg,:,1] = fus_ypts + segment.percent_y_location*fuselage.lengths.total + fuselage.origin[0][1]
fuselage_points[i_seg,:,2] = fus_zpts + segment.percent_z_location*fuselage.lengths.total + fuselage.origin[0][2]
G = Data()
G.PTS = fuselage_points
return G