def fit_glider_3d(cls, glider, numpoints=3): """ Create a parametric model from glider """ shape = glider.shape_simple front, back = shape.front, shape.back arc = [rib.pos[1:] for rib in glider.ribs] aoa = [[front[i][0], rib.aoa_relative] for i, rib in enumerate(glider.ribs)] zrot = [[front[i][0], rib.zrot] for i, rib in enumerate(glider.ribs)] def symmetric_fit(polyline, numpoints=numpoints): mirrored = PolyLine2D(polyline[1:]).mirror([0, 0], [0, 1]) symmetric = mirrored[::-1].join(polyline[int(glider.has_center_cell):]) return SymmetricBezier.fit(symmetric, numpoints=numpoints) front_bezier = symmetric_fit(front) back_bezier = symmetric_fit(back) arc_bezier = symmetric_fit(arc) aoa_bezier = symmetric_fit(aoa) zrot_bezier = symmetric_fit(zrot) cell_num = len(glider.cells) * 2 - glider.has_center_cell front[0][0] = 0 # for midribs start = (2 - glider.has_center_cell) / cell_num const_arr = [0.] + np.linspace(start, 1, len(front) - 1).tolist() rib_pos = [p[0] for p in front] cell_centers = [(p1+p2)/2 for p1, p2 in zip(rib_pos[:-1], rib_pos[1:])] rib_pos_int = Interpolation(zip([0] + rib_pos[1:], const_arr)) rib_distribution = [[i, rib_pos_int(i)] for i in np.linspace(0, rib_pos[-1], 30)] rib_distribution = Bezier.fit(rib_distribution, numpoints=numpoints+3) profiles = [rib.profile_2d for rib in glider.ribs] profile_dist = Bezier.fit([[i, i] for i, rib in enumerate(front)], numpoints=numpoints) balloonings = [cell.ballooning for cell in glider.cells] ballooning_dist = Bezier.fit([[i, i] for i, rib in enumerate(front[1:])], numpoints=numpoints) zrot = Bezier([[0, 0], [front.last()[0], 0]]) # TODO: lineset, dist-curce->xvalues parametric_shape = ParametricShape(front_bezier, back_bezier, rib_distribution, cell_num) parametric_arc = ArcCurve(arc_bezier) return cls(shape=parametric_shape, arc=parametric_arc, aoa=aoa_bezier, zrot=zrot_bezier, profiles=profiles, profile_merge_curve=profile_dist, balloonings=balloonings, ballooning_merge_curve=ballooning_dist, glide=glider.glide, speed=10, lineset=LineSet2D([]))
class AirfoilMergeTool(BaseMergeTool): def __init__(self, obj): super(AirfoilMergeTool, self).__init__(obj) self.scal = numpy.array([1, 0.2]) self.x_grid = [i[0] for i in self.front if i[0] >= 0] self.set_end_points() self.bezier_curve = self.parametric_glider.profile_merge_curve self.bezier_curve = Bezier( [self.scal * i for i in self.bezier_curve.controlpoints]) self.bezier_cpc.control_pos = vector3D(self.bezier_curve.controlpoints) self.fix_end_points() def set_end_points(self): self.parametric_glider.profile_merge_curve.controlpoints[0][0] = 0 self.parametric_glider.profile_merge_curve.controlpoints[-1][ 0] = self.parametric_glider.shape.span def update_spline(self): self.bezier_curve.controlpoints = [ point[:2] for point in self.bezier_cpc.control_pos ] self.expl_curve.update(self.bezier_curve.get_sequence(40)) y_grid = range( int( max([ c[1] / self.scal[1] for c in self.bezier_curve.get_sequence(10) ])) + 2) y_grid = [i * self.scal[1] for i in y_grid] self.update_grid(self.x_grid, y_grid) def fix_end_points(self): def y_constraint(pos): return [pos[0], (pos[1] > 0) * pos[1], pos[2]] def c1(pos): pos = y_constraint(pos) return [0, pos[1], pos[2]] def c2(pos): pos = y_constraint(pos) return [self.parametric_glider.shape.span, pos[1], pos[2]] for i, cp in enumerate(self.bezier_cpc.control_points): if i == 0: cp.constraint = c1 elif i == len(self.bezier_cpc.control_points) - 1: cp.constraint = c2 else: cp.constraint = y_constraint self.update_spline() def accept(self): self.parametric_glider.profile_merge_curve.controlpoints = [ cp / self.scal for cp in self.bezier_curve.controlpoints ] super(AirfoilMergeTool, self).accept()
def __init__(self, obj): super(AirfoilMergeTool, self).__init__(obj) self.scal = numpy.array([1, 0.2]) self.x_grid = [i[0] for i in self.front if i[0] >= 0] self.set_end_points() self.bezier_curve = self.parametric_glider.profile_merge_curve self.bezier_curve = Bezier( [self.scal * i for i in self.bezier_curve.controlpoints]) self.bezier_cpc.control_pos = vector3D(self.bezier_curve.controlpoints) self.fix_end_points()
def __init__(self, yvalue, front_cut, back_cut=1, func=None, name="minirib"): #Profile3D.__init__(self, [], name) if not func: # Function is a bezier-function depending on front/back if front_cut > 0: points = [[front_cut, 1], [front_cut * 2. / 3 + back_cut * 1. / 3, 0]] # else: points = [[front_cut, 0]] if back_cut < 1: points = points + [[front_cut * 1. / 3 + back_cut * 2. / 3, 0], [back_cut, 1]] else: points = points + [[back_cut, 0]] func = Bezier(points).interpolation() self.__function__ = func self.y_value = yvalue self.front_cut = front_cut self.back_cut = back_cut
def test_fit(self): num = len(self.bezier.controlpoints) to_fit = self.bezier.get_sequence() bezier2 = Bezier.fit(to_fit, numpoints=num) for p1, p2 in zip(self.bezier.controlpoints, bezier2.controlpoints): self.assertAlmostEqual(p1[0], p2[0], 0) self.assertAlmostEqual(p1[1], p2[1], 0)
def get_flattened(self, rib, numpoints=30): curve = [[self.end, 0.75], [self.end - 0.05, 1], [self.front, 0], [self.end - 0.05, -1], [self.end, -0.75]] profile = rib.profile_2d cp = [profile.align(point) * rib.chord for point in curve] return Bezier(cp).interpolation(numpoints)
class AirfoilMergeTool(BaseMergeTool): def __init__(self, obj): super(AirfoilMergeTool, self).__init__(obj) self.scal = numpy.array([1, 0.2]) self.x_grid = [i[0] for i in self.front if i[0] >= 0] self.set_end_points() self.bezier_curve = self.ParametricGlider.profile_merge_curve self.bezier_curve = Bezier([self.scal * i for i in self.bezier_curve.controlpoints]) self.bezier_cpc.control_pos = vector3D(self.bezier_curve.controlpoints) self.fix_end_points() def set_end_points(self): self.ParametricGlider.profile_merge_curve.controlpoints[0][0] = 0 self.ParametricGlider.profile_merge_curve.controlpoints[-1][0] = self.ParametricGlider.shape.span def update_spline(self): self.bezier_curve.controlpoints = [point[:2] for point in self.bezier_cpc.control_pos] self.expl_curve.update(self.bezier_curve.get_sequence(40)) y_grid = range(int(max([c[1] / self.scal[1] for c in self.bezier_curve.get_sequence(10)])) + 2) y_grid = [i * self.scal[1] for i in y_grid] self.update_grid(self.x_grid, y_grid) def fix_end_points(self): def y_constraint(pos): return [pos[0], (pos[1] > 0) * pos[1], pos[2]] def c1(pos): pos = y_constraint(pos) return [0, pos[1], pos[2]] def c2(pos): pos = y_constraint(pos) return [self.ParametricGlider.shape.span, pos[1], pos[2]] for i, cp in enumerate(self.bezier_cpc.control_points): if i == 0: cp.constraint = c1 elif i == len(self.bezier_cpc.control_points) - 1: cp.constraint = c2 else: cp.constraint = y_constraint self.update_spline() def accept(self): self.ParametricGlider.profile_merge_curve.controlpoints = [cp / self.scal for cp in self.bezier_curve.controlpoints] super(AirfoilMergeTool, self).accept()
def __init__(self, obj): super(AirfoilMergeTool, self).__init__(obj) self.scal = numpy.array([1, 0.2]) self.x_grid = [i[0] for i in self.front if i[0] >= 0] self.set_end_points() self.bezier_curve = self.ParametricGlider.profile_merge_curve self.bezier_curve = Bezier([self.scal * i for i in self.bezier_curve.controlpoints]) self.bezier_cpc.control_pos = vector3D(self.bezier_curve.controlpoints) self.fix_end_points()
class TestBezier(unittest.TestCase): def setUp(self): controlpoints = [[i, random.random()] for i in range(15)] self.bezier = Bezier(controlpoints) def test_get_value(self): val = random.random() self.assertAlmostEqual(self.bezier(val)[0], self.bezier(val)[0]) self.assertAlmostEqual(self.bezier(val)[1], self.bezier(val)[1]) def test_fit(self): num = len(self.bezier.controlpoints) to_fit = self.bezier.get_sequence() bezier2 = Bezier.fit(to_fit, numpoints=num) for p1, p2 in zip(self.bezier.controlpoints, bezier2.controlpoints): self.assertAlmostEqual(p1[0], p2[0], 0) self.assertAlmostEqual(p1[1], p2[1], 0) def test_length(self): self.bezier.controlpoints = [[0, 0], [2, 0]] self.assertAlmostEqual(self.bezier.get_length(10), 2.) def test_get_sequence(self): sequence = self.bezier.get_sequence(100)
def __init__(self, obj): super(BaseMergeTool, self).__init__(obj) self.bezier_curve = Bezier([[0, 0], [1, 1]]) self.bezier_cpc = ControlPointContainer( self.bezier_curve.controlpoints, self.view) self.shape = coin.SoSeparator() self.grid = coin.SoSeparator() self.coords = coin.SoSeparator() self.expl_curve = Line([]) _shape = self.parametric_glider.shape.get_half_shape() self.ribs = _shape.ribs self.front = _shape.front self.back = _shape.back self.bezier_cpc.on_drag.append(self.update_spline) self.setup_widget() self.setup_pivy()
def fit_region(self, start, stop, num_points, control_points): smoothened = [ self[self(x)] for x in np.linspace(start, stop, num=num_points) ] return Bezier.fit(smoothened, numpoints=num_points)
def setUp(self): controlpoints = [[i, random.random()] for i in range(15)] self.bezier = Bezier(controlpoints)
def __init__(self, control_points, num=50): self.bezier_curve = Bezier(controlpoints=control_points) self.num = num points = self.bezier_curve.get_sequence(num) super(Spline, self).__init__(points)
def get_geometry_explicit(sheet): # All Lists front = [] back = [] cell_distribution = [] aoa = [] arc = [] profile_merge = [] ballooning_merge = [] zrot = [] y = z = span_last = alpha = 0. for i in range(1, sheet.nrows()): line = [sheet.get_cell([i, j]).value for j in range(sheet.ncols())] if not line[0]: break # skip empty line if not all(isinstance(c, numbers.Number) for c in line[:10]): raise ValueError("Invalid row ({}): {}".format(i, line)) # Index, Choord, Span(x_2d), Front(y_2d=x_3d), d_alpha(next), aoa, chord = line[1] span = line[2] x = line[3] y += np.cos(alpha) * (span - span_last) z -= np.sin(alpha) * (span - span_last) alpha += line[4] * np.pi / 180 # angle after the rib aoa.append([span, line[5] * np.pi / 180]) arc.append([y, z]) front.append([span, -x]) back.append([span, -x - chord]) cell_distribution.append([span, i - 1]) profile_merge.append([span, line[8]]) ballooning_merge.append([span, line[9]]) zrot.append([span, line[7] * np.pi / 180]) span_last = span def symmetric_fit(data, bspline=False): not_from_center = int(data[0][0] == 0) mirrored = [[-p[0], p[1]] for p in data[not_from_center:]][::-1] + data if bspline: return SymmetricBSpline.fit(mirrored) else: return SymmetricBezier.fit(mirrored) has_center_cell = not front[0][0] == 0 cell_no = (len(front) - 1) * 2 + has_center_cell start = (2 - has_center_cell) / cell_no const_arr = [0.] + np.linspace(start, 1, len(front) - (not has_center_cell)).tolist() rib_pos = [0.] + [p[0] for p in front[not has_center_cell:]] rib_pos_int = Interpolation(zip(rib_pos, const_arr)) rib_distribution = [[i, rib_pos_int(i)] for i in np.linspace(0, rib_pos[-1], 30)] rib_distribution = Bezier.fit(rib_distribution) parametric_shape = ParametricShape(symmetric_fit(front), symmetric_fit(back), rib_distribution, cell_no) arc_curve = ArcCurve(symmetric_fit(arc)) return { "shape": parametric_shape, "arc": arc_curve, "aoa": symmetric_fit(aoa), "zrot": symmetric_fit(zrot), "profile_merge_curve": symmetric_fit(profile_merge, bspline=True), "ballooning_merge_curve": symmetric_fit(ballooning_merge, bspline=True) }