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

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 

5 

6 

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 

17 

18 

19def uniform_thickness_function(thickness: float, side: str): 

20 """Returns a function handle.""" 

21 m = -1 if side == "top" else 1 

22 

23 def tf(x: float, y: float, z: float = 0): 

24 return Vector3(x=0.0, y=0.0, z=m * thickness / 2) 

25 

26 return tf 

27 

28 

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 ) 

38 

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) 

43 

44 patch = CoonsPatch(north=n, east=e, south=s, west=w) 

45 

46 return patch 

47 

48 

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. 

65 

66 r_n : float 

67 The ogive nose radius. 

68 

69 r_o : float 

70 The ogive radius. 

71 

72 L_o : float 

73 The ogive length. 

74 """ 

75 

76 # TODO - update docstrings, and tidy code, have done this 

77 # elsewhere already 

78 

79 # TODO - think about locating nose, is the tip at (0,0,0)? 

80 # Document this 

81 

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 

87 

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) 

93 

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) 

99 

100 # Nose body 

101 f0 = b_o 

102 f1 = f0 - Vector3(L_o, 0) 

103 fairing_line = Line(f0, f1) 

104 

105 # Nose body base 

106 fb0 = f1 

107 fb1 = Vector3(f1.x, 0) 

108 fb_line = Line(fb0, fb1) 

109 

110 fairing = Polyline([nose_arc, ogive_arc, fairing_line, fb_line]) 

111 

112 super().__init__( 

113 revolve_line=fairing, stl_resolution=stl_resolution, name=name, **kwargs 

114 ) 

115 

116 def __repr__(self): 

117 s = "Ogive nose component" 

118 if self.name: 

119 s += f" (tagged '{self.name}')" 

120 return s