def _child_cells(self): """get all the child cells within the current cell, defined by the miniribs """ cells = [] for leftrib, rightrib in\ itertools.izip(self.rib_profiles_3d[:-1], self.rib_profiles_3d[1:]): cells.append(BasicCell(leftrib, rightrib)) if not self._miniribs: return cells ballooning = [self.rib1.ballooning[x] + self.rib2.ballooning[x] for x in self.x_values] #for i in range(len(first.data)): for index, (bl, left_point, right_point) in enumerate(itertools.izip( ballooning, self._ribs[0].profile_3d.data, self._ribs[1].profile_3d.data )): l = norm(right_point - left_point) # L lnew = sum([norm(c.prof1.data[index] - c.prof2.data[index]) for c in cells]) # L-NEW for c in self._child_cells: newval = lnew / l / bl if newval < 1.: c.ballooning_phi.append(arsinc(newval)) # B/L NEW 1 / (bl * l / lnew) else: c.ballooning_phi.append(arsinc(1.)) #raise ValueError("mull") return cells
def _child_cells(self): """ get all the sub-cells within the current cell, (separated by miniribs) """ cells = [] for leftrib, rightrib in zip(self.rib_profiles_3d[:-1], self.rib_profiles_3d[1:]): cells.append(BasicCell(leftrib, rightrib, ballooning=[])) if not self.miniribs: return cells for index, xvalue in enumerate(self.x_values): left_point = self.rib1.profile_3d.data[index] right_point = self.rib2.profile_3d.data[index] bl = self.ballooning[xvalue] l = norm(right_point - left_point) # L lnew = sum([ norm(c.prof1.data[index] - c.prof2.data[index]) for c in cells ]) # L-NEW for c in cells: if bl > 0: newval = l / lnew * (bl + 1 / 2) - 1 / 2 #newval = l/lnew / bl #newval = lnew / l / bl if bl != 0 else 1 c.ballooning_phi.append( Ballooning.arcsinc( 1 / (1 + newval))) # B/L NEW 1 / (bl * l / lnew) else: c.ballooning_phi.append(0.) return cells
def polygon_size(self): size_min = float("inf") size_max = float("-inf") count = 0 sum = 0 for poly in self.all_polygons: if len(poly) in (3, 4): sides = [] for i in range(len(poly)): i_plus = i + 1 if i_plus == len(poly): i_plus = 0 side = np.array(list(poly[i])) - np.array( list(poly[i_plus])) sides.append(side) if len(poly) == 3: size_poly = 0.5 * vector.norm(np.cross(sides[0], sides[1])) elif len(poly) == 4: size_poly = 0.5 * ( vector.norm(np.cross(sides[0], sides[1])) + vector.norm(np.cross(sides[2], sides[3]))) else: size_poly = 0 sum += size_poly count += 1 size_min = min(size_min, size_poly) size_max = max(size_max, size_poly) return size_min, size_max, sum / count
def area(self): p1_1 = self.rib1.align([0, 0, 0]) p1_2 = self.rib1.align([1, 0, 0]) p2_1 = self.rib2.align([0, 0, 0]) p2_2 = self.rib2.align([1, 0, 0]) return 0.5 * (norm(np.cross(p1_2 - p1_1, p2_1 - p1_1)) + norm(np.cross(p2_2 - p2_1, p2_2 - p1_2)))
def recalc(self): if not self.rib2.profile_2d.numpoints == self.rib1.profile_2d.numpoints: raise ValueError("Unequal length of Cell-Profiles") xvalues = self.rib1.profile_2d.x_values BasicCell.recalc(self) self.prof1 = self.rib1.profile_3d self.prof2 = self.rib2.profile_3d #Map Ballooning if not self.miniribs: # In case there is no midrib, The Cell represents itself! self._cells = [self] # The cell itself is its cell, clear? self._yvalues = [0, 1] else: self._cells = [] self._yvalues = [0] + [rib.y_value for rib in self.miniribs] + [1] ballooning = [self.rib1.ballooning[x] + self.rib2.ballooning[x] for x in xvalues] miniribs = sorted(self.miniribs, key=lambda rib: rib.y_value) # sort for cell-wide (y) argument. first = self.rib1.profile_3d for minirib in miniribs: big = self.midrib_basic_cell(minirib.y_value, True).data small = self.midrib_basic_cell(minirib.y_value, False).data points = [] for i in range(len(big)): # Calculate Rib fakt = minirib.function(xvalues[i]) # factor ballooned/unb. (0-1) point = small[i] + fakt * (big[i] - small[i]) points.append(point) minirib.data = points second = minirib self._cells.append(BasicCell(first, second, [])) # leave ballooning empty first = second #Last Sub-Cell self._cells.append(BasicCell(first, self.rib2.profile_3d, [])) # Calculate ballooning for each x-value # Hamilton Principle: # http://en.wikipedia.org/wiki/Hamilton%27s_principle # http://en.wikipedia.org/wiki/Hamilton%E2%80%93Jacobi_equation # b' = b # f' = f*(l/l') [f=b/l] for i in range(len(first.data)): bl = ballooning[i] + 1 # b/l -> *l/lnew l = norm(self.rib2.profile_3d.data[i] - self.rib1.profile_3d.data[i]) # L lnew = sum([norm(c.prof1.data[i] - c.prof2.data[i]) for c in self._cells]) # L-NEW for c in self._cells: newval = lnew / l / bl if newval < 1.: c.ballooning_phi.append(arsinc(newval)) # B/L NEW 1 / (bl * l / lnew) else: c.ballooning_phi.append(arsinc(1.)) #raise ValueError("mull") for cell in self._cells: cell.recalc()
def _mindist(self, newpoint): np = array(newpoint) pts = array([[pt.x, pt.y] for pt in self.ml.Object.points]) mindist0 = norm(pts[0] - np) print(mindist0) out = 0 count = 0 for pt in pts[1:]: count += 1 mindist = norm(pt - np) if mindist < mindist0: out = count return out
def area(self): area = 0. if len(self.ribs) == 0: return 0 front = self.get_spanwise(0) back = self.get_spanwise(1) front[0][1] = 0 # Get only half a midrib, if there is... back[0][1] = 0 for i in range(len(front) - 1): area += norm(numpy.cross(front[i] - front[i + 1], back[i + 1] - front[i + 1])) area += norm(numpy.cross(back[i] - back[i + 1], back[i] - front[i])) # By this we get twice the area of half the glider :) # http://en.wikipedia.org/wiki/Triangle#Using_vectors return area
def make_smooth_dist(self, points, num=70, dist=None, upper=True): # make array [[lenght, x, y], ...] if not dist: return points length = [0] for i, point in enumerate(points[1:]): length.append(length[-1] + norm(point - points[i])) interpolation_x = Interpolation(zip(length, [p[0] for p in points])) interpolation_y = Interpolation(points) def get_point(dist): x = interpolation_x(dist) return [x, interpolation_y(x)] if dist == "const": dist = np.linspace(0, length[-1], num) elif dist == "sin": if upper: dist = [ np.sin(i) * length[-1] for i in np.linspace(0, np.pi / 2, num) ] else: dist = [ abs(1 - np.sin(i)) * length[-1] for i in np.linspace(0, np.pi / 2, num) ] else: return points return [get_point(d) for d in dist]
def midrib_basic_cell(self, y, ballooning=True, arc_argument=True): if y == 0: # left side return self.prof1 elif y == 1: # right side return self.prof2 else: # somewhere #self._checkxvals() midrib = [] for i in range(len(self.prof1.data)): # Arc -> phi(bal) -> r # oder so... diff = self.prof1[i] - self.prof2[i] if ballooning and self.ballooning_radius[i] > 0.: if arc_argument: d = 0.5 - math.sin(self.ballooning_phi[i] * (0.5 - y)) / math.sin(self.ballooning_phi[i]) h = math.cos(self.ballooning_phi[i] * (1 - 2 * y)) - self.ballooning_cos_phi[i] #h = math.sqrt(1 - (norm(diff) * (0.5 - d) / self._radius[i]) ** 2) #h -= self._cosphi[i] # cosphi2-cosphi else: d = y h = math.sqrt(1 - (norm(diff) * (0.5 - y) / self.ballooning_radius[i]) ** 2) h -= self.ballooning_cos_phi[i] # cosphi2-cosphi else: # Without ballooning d = y h = 0. midrib.append(self.prof1[i] - diff * d + self.normvectors[i] * h * self.ballooning_radius[i]) return Profile3D(midrib)
def test_flat(self): prof = self.rib.profile_2d.copy() prof = PolyLine2D(prof.data) * [self.rib.chord, self.rib.chord] print(self.rib.profile_2d, prof) #prof.scale(self.rib.chord) gib_pos = [n.rib_pos for n in self.attachment_points] gib_pos.sort() hole_pos = [(x1 + x2) / 2 for x1, x2 in zip(gib_pos[:-1], gib_pos[1:])] rigid = RigidFoil(-.15, .12) r_flat = rigid.get_flattened(self.rib) print(self.rib.rotation_matrix, norm(self.rib.rotation_matrix.dot([2, 0, 0]))) Graph.Graphics([ Graph.Line(prof), Graph.Line(self.rib.profile_2d.data * self.rib.chord), Graph.Line(r_flat) ]) Graph.Graphics([ Graph.Line([self.rib.align(p, scale=False) for p in prof.data]), Graph.Line([self.rib.align(p, scale=False) for p in r_flat]), Graph.Line(self.rib.profile_3d.data) ])
def _get_flattened(self, rib): max_segment = 0.005 # 5mm profile = rib.profile_2d profile_normvectors = PolyLine2D(profile.normvectors) start = profile(self.start) end = profile(self.end) point_range = [] last_node = None for p in profile[start:end]: sign = -1 if p[1] > 0 else +1 if last_node is not None: diff = norm(p - last_node) * rib.chord if diff > max_segment: segments = int(math.ceil(diff / max_segment)) point_range += list( np.linspace(point_range[-1], sign * p[0], segments))[1:] else: point_range.append(sign * p[0]) else: point_range.append(sign * p[0]) last_node = p indices = [profile(x) for x in point_range] return [(profile[index] - profile_normvectors[index] * self.func(x)) * rib.chord for index, x in zip(indices, point_range)]
def get_length(self, cell): rib1 = cell.rib1 rib2 = cell.rib2 left = rib1.profile_3d[rib1.profile_2d(self.left)] right = rib2.profile_3d[rib2.profile_2d(self.right)] return norm(left - right)
def ballooning_radius(self): radius = [] for i, phi in enumerate(self.ballooning_phi): if round(phi, 5) > 0: radius.append(norm(self.prof1.data[i] - self.prof2.data[i]) / (2*numpy.sin(phi))) else: radius.append(0) return radius
def span(self): span = 0. front = self.get_spanwise() last = front[0] * [0, 0, 1] # centerrib only halfed for this in front[1:]: span += norm((this - last) * [0, 1, 1]) last = this return 2 * span
def calc_panel_geo(self): for i in range(self.length): self.panel.append(numpy.array([self.airfoil[i], self.airfoil[i + 1]])) self.panel_mids.append((self.airfoil[i] + self.airfoil[i + 1]) / 2) self.half_lenghts[i] = vector.norm(self.airfoil[i] - self.airfoil[i + 1]) / 2 self.panel_tangentials.append(self.panel[-1][1] - self.panel[-1][0]) self.panel_normals.append(vector.normalize([-self.panel_tangentials[-1][1], self.panel_tangentials[-1][0]])) for i in range(self.wake_numpoints - 1): self.wake_panels.append(numpy.array([self.wake[i], self.wake[i + 1]]))
def _douplet_const(self, point_j, panel): point_i_1, point_i_2 = panel t = point_i_2 - point_i_1 n_ = vector.normalize([t[1], -t[0]]) pn, s0 = numpy.linalg.solve(numpy.transpose(numpy.array([n_, t])), -point_i_1 + point_j) l = vector.norm(t) if pn == 0: return 0 else: return 1 / 2 / numpy.pi * (-numpy.arctan2(pn, (s0 - 1) * l) + numpy.arctan2(pn, s0 * l))
def _normalize(line, target_lengths): new_line = [line[0]] last_node = line[0] segments = line.get_segments() for segment, target_length in zip(segments, target_lengths): scale = target_length / norm(segment) last_node = last_node + scale * segment new_line.append(last_node) return PolyLine2D(new_line)
def noseindex(self): p0 = self.data[0] max = 0 noseindex = 0 for i, p1 in enumerate(self.data): diff = norm(p1 - p0) if diff > max: noseindex = i max = diff return noseindex
def draw(self, graphics): cell, pointnums = super(Arrow, self).draw(graphics) assert len(pointnums) == 2 arrow = vtk.vtkArrowSource() p1, p2 = graphics.get_points(*pointnums) transform = vtk.vtkTransform() transform.Translate(p1) length = norm(p2-p1) transform.Scale(length, length, length) pass
def test_extend_case_afterend(self): #First Point further than the end for thalist in self.vectors: start = self.numpoints + random.random() * 50 leng = random.random() * 100 - 50 new = thalist.extend(start, leng) leng2 = thalist.get_length(start, new) self.assertAlmostEqual(abs(leng), leng2, 7, "Failed for start=" + str(start) + " and leng=" + str(leng) + "\nresult: i2=" + str(new) + " leng2=" + str(leng2) + " dist=" + str(vector.norm(thalist[start] - thalist[new])))
def test_extend_total(self): #Sum up the length of the list and check for thalist in self.vectors: total = 0 for i in range(len(thalist) - 2): total += vector.norm(thalist[i] - thalist[i + 1]) # First Test: i2 = thalist.extend(0, total) self.assertAlmostEqual(i2, len(thalist) - 2) # Second Test: self.assertAlmostEqual(total, thalist.get_length(0, len(thalist) - 2))
def test_extend_case_afterend(self): #First Point further than the end for thalist in self.vectors: start = self.numpoints + random.random() * 50 leng = random.random() * 100 - 50 new = thalist.extend(start, leng) leng2 = thalist.get_length(start, new) self.assertAlmostEqual( abs(leng), leng2, 7, "Failed for start=" + str(start) + " and leng=" + str(leng) + "\nresult: i2=" + str(new) + " leng2=" + str(leng2) + " dist=" + str(vector.norm(thalist[start] - thalist[new])))
def get_all(self): gib_pos = [n.rib_pos for n in self.attachment_points] gib_pos.sort() hole_pos = [(x1 + x2) / 2 for x1, x2 in zip(gib_pos[:-1], gib_pos[1:])] gibs = [self.get_gibus_arcs(y) for y in gib_pos] holes = [self.get_hole(x, 0.4) for x in hole_pos] rigid = self.get_rigid(-.15, .13) p = self.rib.profile_2d print(max([norm(p[0] - p2) for p2 in p]), self.rib.chord) return [Graph.Line(self.rib.profile_3d.data)] + gibs + holes + [rigid]
def flatten_list(list1, list2): index_left = index_right = 0 flat_left = [numpy.array([0, 0])] flat_right = [numpy.array([norm(list1[0]-list2[0]), 0])] # def which(i, j): # diff = list1[i] - list2[j] # return diff.dot(list1[i+1]-list1[i]+list2[j+1]-list2[j+1]) while True: #while which(index_left, index_right) <= 0 and index_left < len(list1) - 2: # increase left_index if index_left < len(list1) -1: flat_left.append(point2d(list1[index_left], flat_left[index_left], list2[index_right], flat_right[index_right], list1[index_left + 1])) index_left += 1 #while which(index_left, index_right) >= 0 and index_right < len(list2) - 2: # increase right_index if index_right < len(list2) -1: flat_right.append(point2d(list1[index_left], flat_left[index_left], list2[index_right], flat_right[index_right], list2[index_right + 1])) index_right += 1 if index_left == len(list1) - 1 and index_right == len(list2) - 1: break # while index_left < len(list1) - 1: # flat_left.append(point2d(list1[index_left], flat_left[index_left], # list2[index_right], flat_right[index_right], # list1[index_left + 1])) # index_left += 1 # # while index_right < len(list2) - 1: # flat_right.append(point2d(list1[index_left], flat_left[index_left], # list2[index_right], flat_right[index_right], # list2[index_right + 1])) # index_right += 1 return Vectorlist2D(flat_left), Vectorlist2D(flat_right)
def projection(self): if not self._xvekt or not self._yvekt or not self._diff: p1 = self.data[0] diff_len = nose_index = 0 diff = [p - p1 for p in self.data] for i in range(len(self.data)): thisdiff = norm(diff[i]) if thisdiff > diff_len: nose_index = i diff_len = thisdiff xvect = normalize(diff[nose_index]) yvect = numpy.array([0, 0, 0]) for i in range(len(diff)): sign = 1 - 2 * (i > nose_index) yvect = yvect + sign * (diff[i] - xvect * xvect.dot(diff[i])) self.xvect = xvect self.yvect = normalize(yvect) self._diff = diff self.noseindex = nose_index
def flatten_list(list1, list2): index_left = index_right = 0 flat_left = [numpy.array([0, 0])] flat_right = [numpy.array([norm(list1[0]-list2[0]), 0])] # def which(i, j): # diff = list1[i] - list2[j] # return diff.dot(list1[i+1]-list1[i]+list2[j+1]-list2[j+1]) while True: #while which(index_left, index_right) <= 0 and index_left < len(list1) - 2: # increase left_index if index_left < len(list1) - 1: flat_left.append(point2d(list1[index_left], flat_left[index_left], list2[index_right], flat_right[index_right], list1[index_left + 1])) index_left += 1 #while which(index_left, index_right) >= 0 and index_right < len(list2) - 2: # increase right_index if index_right < len(list2) - 1: flat_right.append(point2d(list1[index_left], flat_left[index_left], list2[index_right], flat_right[index_right], list2[index_right + 1])) index_right += 1 if index_left == len(list1) - 1 and index_right == len(list2) - 1: break # while index_left < len(list1) - 1: # flat_left.append(point2d(list1[index_left], flat_left[index_left], # list2[index_right], flat_right[index_right], # list1[index_left + 1])) # index_left += 1 # # while index_right < len(list2) - 1: # flat_right.append(point2d(list1[index_left], flat_left[index_left], # list2[index_right], flat_right[index_right], # list2[index_right + 1])) # index_right += 1 return Vectorlist2D(flat_left), Vectorlist2D(flat_right)
def normalize(self): """ Normalize the airfoil. This routine does: *Put the nose back to (0,0) *De-rotate airfoil *Reset its length to 1 """ #to normalize do: put nose to (0,0), rotate to fit (1,0), normalize to (1,0) p1 = self.data[0] dmax = 0. nose = p1 for i in self.data: temp = norm(i - p1) if temp > dmax: dmax = temp nose = i diff = p1 - nose sin = diff.dot([0, -1]) / dmax # Angle: a.b=|a|*|b|*sin(alpha) cos = numpy.sqrt(1 - sin ** 2) matrix = numpy.array([[cos, -sin], [sin, cos]]) / dmax # de-rotate and scale self.data = numpy.array([matrix.dot(i - nose) for i in self.data])
def normalize(self): """ Normalize the airfoil. This routine does: *Put the nose back to (0,0) *De-rotate airfoil *Reset its length to 1 """ #to normalize do: put nose to (0,0), rotate to fit (1,0), normalize to (1,0) p1 = self.data[0] dmax = 0. nose = p1 for i in self.data: temp = norm(i - p1) if temp > dmax: dmax = temp nose = i diff = p1 - nose sin = diff.dot([0, -1]) / dmax # Angle: a.b=|a|*|b|*sin(alpha) cos = numpy.sqrt(1 - sin**2) matrix = numpy.array([[cos, -sin], [sin, cos] ]) / dmax # de-rotate and scale self.data = numpy.array([matrix.dot(i - nose) for i in self.data])
def length_no_sag(self): return norm(self.upper_node.vec - self.lower_node.vec)
def area(self): p1_1 = self.rib1.align([0, 0, 0]) p1_2 = self.rib1.align([1, 0, 0]) p2_1 = self.rib2.align([0, 0, 0]) p2_2 = self.rib2.align([1, 0, 0]) return 0.5 * (norm(numpy.cross(p1_2 - p1_1, p2_1 - p1_1)) + norm(numpy.cross(p2_2 - p2_1, p2_2 - p1_2)))
def length_projected(self): return norm(self.lower_node.vec_proj - self.upper_node.vec_proj)
def drag_differential(self): """drag per meter""" return 1 / 2 * self.type.cw * self.type.thickness * norm(self.v_inf) ** 2
def _insert_attachment_points(self, plotpart, attachment_points): for attachment_point in attachment_points: if hasattr(attachment_point, "cell"): if attachment_point.cell != self.cell: continue cell_pos = attachment_point.cell_pos elif hasattr(attachment_point, "rib"): if attachment_point.rib not in self.cell.ribs: continue if attachment_point.rib == self.cell.rib1: cell_pos = 0 align = ("left", "right") elif attachment_point.rib == self.cell.rib2: cell_pos = 1 cut_f_l = self.panel.cut_front["left"] cut_f_r = self.panel.cut_front["right"] cut_b_l = self.panel.cut_back["left"] cut_b_r = self.panel.cut_back["right"] cut_f = cut_f_l + cell_pos * (cut_f_r - cut_f_l) cut_b = cut_b_l + cell_pos * (cut_b_r - cut_b_l) if cut_f <= attachment_point.rib_pos <= cut_b: rib_pos = attachment_point.rib_pos left, right = self.get_point(rib_pos) p1 = left + cell_pos * (right - left) d = normalize(right - left) * 0.008 # 8mm if cell_pos == 1: p2 = p1 + d else: p2 = p1 - d #p1, p2 = self.get_p1_p2(attachment_point.rib_pos, which) plotpart.layers["marks"] += self.config.marks_attachment_point( p1, p2) plotpart.layers[ "L0"] += self.config.marks_laser_attachment_point(p1, p2) if self.config.insert_attachment_point_text: text_align = "left" if cell_pos > 0.7 else "right" if text_align == "right": d1 = norm(self.get_point(cut_f_l)[0] - left) d2 = norm(self.get_point(cut_b_l)[0] - left) else: d1 = norm(self.get_point(cut_f_r)[1] - right) d2 = norm(self.get_point(cut_b_r)[1] - right) bl = self.ballooned[0] br = self.ballooned[1] text_height = 0.01 * 0.8 dmin = text_height + 0.001 if d1 < dmin and d2 + d1 > 2 * dmin: offset = dmin - d1 ik = get_x_value(self.x_values, rib_pos) left = bl[bl.extend(ik, offset)] right = br[br.extend(ik, offset)] elif d2 < dmin and d1 + d2 > 2 * dmin: offset = dmin - d2 ik = get_x_value(self.x_values, rib_pos) left = bl[bl.extend(ik, -offset)] right = br[br.extend(ik, -offset)] if self.config.layout_seperate_panels and self.panel.is_lower: # rotated later p2 = left p1 = right # text_align = text_align else: p1 = left p2 = right # text_align = text_align plotpart.layers["text"] += Text( " {} ".format(attachment_point.name), p1, p2, size=0.01, # 1cm align=text_align, valign=0, height=0.8).get_vectors()
def get_flattened_cell(self, midribs=10): left, right = openglider.vector.projection.flatten_list( self.prof1, self.prof2) left_bal = left.copy() right_bal = right.copy() ballooning = [ self.ballooning[x] for x in self.rib1.profile_2d.x_values ] for i in range(len(left)): diff = (right[i] - left[i]) * ballooning[i] / 2 left_bal.data[i] -= diff right_bal.data[i] += diff def _normalize(line, target_lengths): new_line = [line[0]] last_node = line[0] segments = line.get_segments() for segment, target_length in zip(segments, target_lengths): scale = target_length / norm(segment) last_node = last_node + scale * segment new_line.append(last_node) return PolyLine2D(new_line) # left_bal_2 = _normalize(left_bal, left.get_segment_lengthes()) right_bal_2 = _normalize(right_bal, right.get_segment_lengthes()) right_bal_3 = right_bal_2.copy() left_bal_3 = left_bal_2.copy() debug_lines = [] debug_lines2 = [] for i in range(len(left_bal)): diff = left_bal_2[i] - right_bal_2[i] dist_new = norm(diff) dist_orig = norm(left_bal[i] - right_bal[i]) diff_per_side = normalize(diff) * ((dist_new - dist_orig) / 2) right_bal_2[i] += diff_per_side left_bal_2[i] -= diff_per_side debug_lines.append(PolyLine2D([left_bal_2[i], right_bal_2[i]])) debug_lines2.append(PolyLine2D([left_bal[i], right_bal[i]])) inner = [] for x in openglider.utils.linspace(0, 1, 2 + midribs): l1 = left_bal * (1 - x) l2 = right_bal * x inner.append(l1.add(l2)) #ballooned = [left_bal, right_bal] return { "inner": inner, "ballooned": [left_bal, right_bal], "ballooned_new": [left_bal_2, right_bal_2], "ballooned_new_copy": [left_bal_3, right_bal_3], "debug": [left, right], "debug_1": debug_lines, "debug_2": debug_lines2 }
def span(self): # TODO: Maybe use mean length from (1,0), (0,0) return norm((self.rib1.pos - self.rib2.pos) * [0, 1, 1])
def span(self): return norm((self.rib1.pos - self.rib2.pos) * [0, 1, 1])
def drag_differential(self): """drag per meter""" return 1 / 2 * self.type.cw * self.type.thickness * norm(self.v_inf)**2
def setUp(self, numpoints=100): self.p1 = np.array([random.random(), random.random()]) self.d = np.array([random.random(), random.random()]) * 100 self.l = norm(self.d) self.p2 = self.p1 + self.d