Coverage for /opt/hostedtoolcache/Python/3.11.10/x64/lib/python3.11/site-packages/hypervehicle/components/common.py: 73%
51 statements
« prev ^ index » next coverage.py v7.6.4, created at 2024-10-29 02:51 +0000
« prev ^ index » next coverage.py v7.6.4, created at 2024-10-29 02:51 +0000
1import numpy as np
2from hypervehicle.geometry import Vector3, Bezier
3from hypervehicle.components import Wing, RevolvedComponent, Fin
4from hypervehicle.geometry import Vector3, Bezier, Line, Polyline, Arc, CoonsPatch
7def leading_edge_width_function(r):
8 temp = Bezier(
9 [
10 Vector3(x=0.0, y=0.01),
11 Vector3(x=0.5, y=0.1),
12 Vector3(x=1.0, y=0.01),
13 ]
14 )
15 le_width = temp(r).y
16 return le_width
19def uniform_thickness_function(thickness: float, side: str):
20 """Returns a function handle."""
21 m = -1 if side == "top" else 1
23 def tf(x: float, y: float, z: float = 0):
24 return Vector3(x=0.0, y=0.0, z=m * thickness / 2)
26 return tf
29def circle_patch(centre: Vector3, r: float, plane: str = "xy") -> CoonsPatch:
30 """Returns a parametric surface of a circle."""
31 # TODO - planes other than xy
32 tr = Vector3(x=centre.x + r * np.cos(np.pi / 4), y=centre.y + r * np.sin(np.pi / 4))
33 tl = Vector3(x=centre.x - r * np.cos(np.pi / 4), y=centre.y + r * np.sin(np.pi / 4))
34 br = Vector3(x=centre.x + r * np.cos(np.pi / 4), y=centre.y - r * np.sin(np.pi / 4))
35 bl = Vector3(
36 x=centre.x - r * np.cos(np.pi / 4), y=centre.y + -r * np.sin(np.pi / 4)
37 )
39 n = Arc(a=tl, b=tr, c=centre)
40 e = Arc(a=br, b=tr, c=centre)
41 s = Arc(a=bl, b=br, c=centre)
42 w = Arc(a=bl, b=tl, c=centre)
44 patch = CoonsPatch(north=n, east=e, south=s, west=w)
46 return patch
49class OgiveNose(RevolvedComponent):
50 def __init__(
51 self,
52 h: float,
53 r_n: float,
54 r_o: float,
55 L_o: float,
56 stl_resolution: int = 3,
57 name: str = None,
58 **kwargs,
59 ) -> None:
60 """A Fuselage wrapper to create an Ogive nose component.
61 Parameters
62 ----------
63 h : float
64 The ogive height.
66 r_n : float
67 The ogive nose radius.
69 r_o : float
70 The ogive radius.
72 L_o : float
73 The ogive length.
74 """
76 # TODO - update docstrings, and tidy code, have done this
77 # elsewhere already
79 # TODO - think about locating nose, is the tip at (0,0,0)?
80 # Document this
82 # Ogive Dependencies
83 x_o = -np.sqrt((r_o - r_n) ** 2 - (r_o - h) ** 2)
84 y_t = r_n * (r_o - h) / (r_o - r_n)
85 x_t = x_o - np.sqrt(r_n**2 - y_t**2)
86 x_a = x_o - r_n
88 # Ogive arc
89 a_o = Vector3(-x_t, y_t)
90 b_o = Vector3(0, h)
91 c_o = Vector3(0, -r_o + h)
92 ogive_arc = Arc(a_o, b_o, c_o)
94 # Nose arc
95 a_n = Vector3(-x_a, 0)
96 b_n = a_o
97 c_n = Vector3(-x_o, 0)
98 nose_arc = Arc(a_n, b_n, c_n)
100 # Nose body
101 f0 = b_o
102 f1 = f0 - Vector3(L_o, 0)
103 fairing_line = Line(f0, f1)
105 # Nose body base
106 fb0 = f1
107 fb1 = Vector3(f1.x, 0)
108 fb_line = Line(fb0, fb1)
110 fairing = Polyline([nose_arc, ogive_arc, fairing_line, fb_line])
112 super().__init__(
113 revolve_line=fairing, stl_resolution=stl_resolution, name=name, **kwargs
114 )
116 def __repr__(self):
117 s = "Ogive nose component"
118 if self.name:
119 s += f" (tagged '{self.name}')"
120 return s