def parameter_frame(self, s, mode=Vector([0., 0., 1.])): basis = [] t = self.parameter_point(s) orig = t if (type(mode) == Vector): vec = mode.unit() elif mode == 'Xnat': vec = (1., 0., 0.) elif mode == 'Ynat': vec = (0., 1., 0.) elif mode == 'Znat': vec = (0., 0., 1.) tph = self.parameter_point(s + 0.001) xp = Vector( [float(tph[0] - t[0]), float(tph[1] - t[1]), float(tph[2] - t[2])]) T = xp.unit() basis.append(T) B = cross(vec, T) basis.append(B) N = cross(T, B) basis.append(N) matrix = [None, None, None] for i in range(3): matrix[i] = [float(basis[i][j]) for j in range(3)] return Frame((orig, matrix))
def symmetrize(self, smooth=False, plane_normal=Vector([0., 1., 0.])): # we will always take the first point of the control polyline as origin of the symmetry plane new_pol3d = [self.control_polyline[0]] plane = Plane([self.control_polyline[0], plane_normal.unit()]) for p in self.control_polyline[1:]: cp = closest_point_on_plane(p, plane) print 'closest of ' + str(p) + ' is ' + str(cp) vec = Vector([cp[i] - p[i] for i in range(3)]) new_pol3d.append(Point([cp[i] + vec[i] for i in range(3)])) return Spline3D(new_pol3d)
def center_arc(pt1, pt2, bulge): if bulge > 0.: inc_angle = 4. * np.arctan(bulge) elif bulge < 0.: inc_angle = -4. * np.arctan(bulge) chord = Vector([pt2[i] - pt1[i] for i in range(3)]) mid = Point([0.5 * (pt1[i] + pt2[i]) for i in range(3)]) vec = (chord.norm * 0.5 * bulge * cross(chord, Vector( (0., 0., 1.))).unit()) summit = Point([mid[i] + vec[i] for i in range(3)]) radius = chord.norm / (2. * np.sin(inc_angle / 2.)) vec = radius * Vector([mid[i] - summit[i] for i in range(3)]).unit() center = Point([summit[i] + vec[i] for i in range(3)]) return center
def cross(u, v): pv = [] pv.append(u[1] * v[2] - u[2] * v[1]) pv.append(u[2] * v[0] - u[0] * v[2]) pv.append(u[0] * v[1] - u[1] * v[0]) vp = Vector(pv) return vp
def extrude_polyline2d(polyline, frame, height): pol3d = polyline.to_frame(frame) lines = [] yb_point = Point([frame[0][i] for i in range(3)]) yb_vec = Vector([frame[1][0][i] for i in range(3)]).unit() print '*************' print yb_vec orig = gp_Pnt(frame[0][0], frame[0][1], frame[0][2]) vec = gp_Dir(yb_vec[0], yb_vec[1], yb_vec[2]) plane = gp_Pln(orig, vec) for i, p in enumerate(pol3d[:-1]): print p print 'zob' gp0 = gp_Pnt(p[0], p[1], p[2]) gp1 = gp_Pnt(pol3d[i + 1][0], pol3d[i + 1][1], pol3d[i + 1][2]) lines.append(BRepBuilderAPI_MakeEdge(gp0, gp1).Edge()) wire = BRepBuilderAPI_MakeWire(lines[0]) for l in lines[1:]: wire.Add(l) face = BRepBuilderAPI_MakeFace(wire.Wire()) print 'normal' print[vec.X(), vec.Y(), vec.Z()] extrude = BRepPrimAPI_MakePrism( face.Shape(), gp_Vec(height * vec.X(), height * vec.Y(), height * vec.Z())).Shape() return extrude
def intersect_2_segments(seg1, seg2): from youbastard.geometry.Line import Line v1 = Vector([seg1[1][i] - seg1[0][i] for i in range(3)]) v2 = Vector([seg2[1][i] - seg2[0][i] for i in range(3)]) l1 = Line([seg1[0], v1]) seg1_parameters = sorted( [get_parameter(seg1[0], l1), get_parameter(seg1[1], l1)]) l2 = Line([seg2[0], v2]) seg2_parameters = sorted( [get_parameter(seg2[0], l2), get_parameter(seg2[1], l2)]) intersection = intersect_2_lines(l1, l2) out = False if intersection and ( seg1_parameters[0] < get_parameter(intersection, l1) < seg1_parameters[1]) and \ ( seg2_parameters[0] < get_parameter(intersection, l2) < seg2_parameters[1]): out = True return out
def __init__(self, pt1, pt2, thickness, vertical_vector): super(Wall, self).__init__([pt1, pt2]) vert = vertical_vector.unit() wall_direction = Vector([pt2[i] - pt1[i] for i in range(3)]).unit() normal_direction = cross(wall_direction, vertical_vector).unit() self.matrix = [[normal_direction[i] for i in range(3)], [vert[i] for i in range(3)], [wall_direction[i] for i in range(3)]] self.thickness = thickness frame = Frame([pt1, self.matrix])
def face_polyline(polyline, frame): pol3d = polyline.to_frame(frame) lines = [] yb_point = Point([frame[0][i] for i in range(3)]) yb_vec = Vector([frame[3][i] for i in range(3)]).unit() orig = gp_Pnt(frame[0][0], frame[0][1], frame[0][2]) vec = gp_Dir(yb_vec[0], yb_vec[1], yb_vec[2]) plane = gp_Pln(orig, vec) for i, p in enumerate(pol3d[:-1]): gp0 = gp_Pnt(p[0], p[1], p[2]) gp1 = gp_Pnt(pol3d[i + 1][0], pol3d[i + 1][1], pol3d[i + 1][2]) lines.append(BRepBuilderAPI_MakeEdge(gp0, gp1).Edge()) wire = BRepBuilderAPI_MakeWire(lines[0]) for l in lines[1:]: wire.Add(l) face = BRepBuilderAPI_MakeFace(wire.Wire()) return face.Shape()
def parameter_frame(self, s, mode='frenet'): basis = [] t = interpolate.splev(s, self.tck, der=0) orig = Point([float(t[i]) for i in range(3)]) if mode == 'frenet': t = interpolate.splev(s, self.tck, der=1) xp = Vector([float(t[0]), float(t[1]), float(t[2])]) t = interpolate.splev(s, tck, der=2) xpp = Vector([float(t[0]), float(t[1]), float(t[2])]) T = xp.unit() basis.append(T.unit()) B = cross(xp, xpp) basis.append(B.unit()) N = cross(B, T) basis.append(N.unit()) else: if (type(mode) == Vector): vec = mode.unit() elif mode == 'Xnat': vec = (1., 0., 0.) elif mode == 'Ynat': vec = (0., 1., 0.) elif mode == 'Znat': vec = (0., 0., 1.) t = interpolate.splev(s, self.tck, der=1) xp = Vector([float(t[0]), float(t[1]), float(t[2])]) T = xp.unit() basis.append(T) B = cross(vec, T) basis.append(B) N = cross(T, B) basis.append(N) matrix = [None, None, None] for i in range(3): matrix[i] = [float(basis[i][j]) for j in range(3)] return Frame((orig, matrix))
def frame_array(self, mode=Vector([0., 0., 1.]), n=20, mirror=False): a_frame = [] for i in range(n): s = float(i) / (float(n - 1)) a_frame.append(self.parameter_frame(s, mode=mode)) return a_frame
ceiling = extrude_polyline2d(horiz, ceiling_frame, 0.5) polylines = [] all_tree_nodes = [] thick = 0.15 for ipoint, point in enumerate(data['points']): sector = [point] for iwall, wall in enumerate(data['walls']): if ipoint in wall: nex = None if wall[0] == ipoint: nex = data['points'][wall[1]] elif wall[1] == ipoint: nex = data['points'][wall[0]] length = distance(point, nex) vec = Vector([nex[i] - point[i] for i in range(3)]).unit() half = Point([point[i] + 0.5 * length * vec[i] for i in range(3)]) sector.append([half, thick]) all_tree_nodes.append( TreeNode([sector[0]] + [secp[0] for secp in sector[1:]])) for itreenode, treenode in enumerate(all_tree_nodes): #thck = all_thicknesses[itreenode] #treenode.set_thicknesses() pl = treenode.offset(default_thickness=thick) polylines.append(pl) shapes = [] frame = Frame([[0., 0., 0.], [1., 0., 0.], [0., 1., 0.], [0., 0., 1.]])
t = -t print t print 'attributes' print 'cog = ' + str(t.cg) print 'circumcenter = ' + str(t.circumcenter) print 'normal = ' + str(t.normal) print is_on_plane(t.circumcenter, pl) print is_on_plane(t.cg, pl) print is_on_plane(Point((0., 0., 0.)), pl) idtest += 1 pretty_print('TEST n.' + str(idtest) + ': LINES') p1 = points[0] v1 = Vector([points[1][i] - points[0][i] for i in range(3)]) l1 = Line((p1, v1)) p2 = points[2] v2 = Vector([points[1][i] - points[2][i] for i in range(3)]) l2 = Line((p2, v2)) print '=======' print intersect_2_lines(l1, l2) print '--------------' print points[1] print '=======' idtest += 1 pretty_print('TEST n.' + str(idtest) + ': INTERSECT 2 SEGMENTS') p1 = Point([0., 0., 0.001]) p2 = Point([1., 1., 0.]) p3 = Point([0., 1., 0.])
} polylines = [] all_tree_nodes = [] thick = 0.2 for ipoint, point in enumerate(data['points']): sector = [point] for iwall, wall in enumerate(data['walls']): if ipoint in wall: nex = None if wall[0] == ipoint: nex = data['points'][wall[1]] elif wall[1] == ipoint: nex = data['points'][wall[0]] length = distance(point, nex) vec = Vector([nex[i] - point[i] for i in range(3)]).unit() half = Point([point[i] + 0.5 * length * vec[i] for i in range(3)]) sector.append([half, thick]) all_tree_nodes.append( TreeNode([sector[0]] + [secp[0] for secp in sector[1:]])) for itreenode, treenode in enumerate(all_tree_nodes): #thck = all_thicknesses[itreenode] #treenode.set_thicknesses() pl = treenode.offset(default_thickness=0.2) polylines.append(pl) import matplotlib.pyplot as plt for pol in polylines: plt.plot([p[0] for p in pol], [p[1] for p in pol])
span = 0.8 max_chord = 0.12 scalef = chord_function(0.78) chordf = lambda s: max_chord * scalef(s) a_point = [ Point([0., span / float(ndisc), 0.]), Point([0.01, span / 4, 0.002]), Point([0., span / 2, 0.01]), Point([-0.02, 2. * span / 3., 0.015]), Point([-0.08, span, -0.02]) ] generator = Spline3D(a_point) fa = generator.frame_array(mode=Vector([0., 0., 1.]), n=ndisc) #fa = [Frame([[0.,0.,0.], [[0.,0.,1.],[1.,0.,0.],[0.,1.,0.]]])] + fa shapes = [] generator_extrados = BRepOffsetAPI_ThruSections(False, True) generator_intrados = BRepOffsetAPI_ThruSections(False, True) generator_trailing_edge = BRepOffsetAPI_ThruSections(False, True) generator = BRepOffsetAPI_ThruSections(False, True) print dir(generator) chord = lambda x: max_chord * chordf(x) for i, f in enumerate(fa): # adimensioned position along span xspan = distance(fa[0][0], f[0]) / span
def __init__(self, polyline, generator, mode=Vector([0., 0., 1.]), n=50, *largs, **kwargs): """ polyline is wether closed 2D polyline or a dict : { 'name1' : [opened_polyline 1], ... 'nameN' : [opened_polyline N] } the reunion of all these polylines must be closed and have no zero-length segments generator must be an array of Frames along the generator, a parameter is designed by a real s in [0., 1.] in kwargs we define FUNCTIONS for ex : scale = lambda s: funcscale(s) rotation = lambda s: funcrotation(s) translate = lambda s: translate_rotation(s) ... """ obj = {} frame_array = generator.frame_array(mode=mode, n=n) if (type(polyline) == Polyline2D) and polyline.is_closed: obj['surface'] = [] print 'closed polyline' for i, frame in enumerate(frame_array): s = float(i) / float(n - 1) if kwargs.has_key('scale'): scale = kwargs['scale'](s) else: scale = 1. if kwargs.has_key('rotate'): rotate = kwargs['rotate'](s) else: rotate = 0. if kwargs.has_key('translate'): translate = kwargs['translate'](s) else: translate = [0., 0.] obj['surface'].append( polyline.to_frame(frame, scale=scale, translate=translate, rotate=rotate)) elif (type(polyline) == dict): print 'dico' for k in polyline.keys(): obj[k] = [] for i, frame in enumerate(frame_array): s = float(i) / float(n - 1) if kwargs.has_key('scale'): scale = kwargs['scale'](s) else: scale = 1. if kwargs.has_key('rotate'): rotate = kwargs['rotate'](s) else: rotate = 0. if kwargs.has_key('translate'): translate = kwargs['translate'](s) else: translate = [0., 0.] for k in polyline.keys(): named_polyline = polyline[k] obj[k].append( named_polyline.to_frame(frame, scale=scale, translate=translate, rotate=rotate)) super(Extrusion, self).__init__(obj)
def distance(p1, p2): return Vector([p2[i] - p1[i] for i in range(3)]).norm
def parameter_frame(tck, s, mode='frenet'): basis = [] t = interpolate.splev(s, tck, der=0) orig = Point([t[0], t[1], t[2]]) if mode == 'frenet': t = interpolate.splev(s, tck, der=1) xp = Vector([float(t[0]), float(t[1]), float(t[2])]) t = interpolate.splev(s, tck, der=2) xpp = Vector([float(t[0]), float(t[1]), float(t[2])]) T = xp.unit() basis.append(T.unit()) B = cross(xp, xpp) basis.append(B.unit()) N = cross(B, T) basis.append(N.unit()) if mode == 'Xnat': t = interpolate.splev(s, tck, der=1) xp = Vector([float(t[0]), float(t[1]), float(t[2])]) T = xp.unit() basis.append(T) B = cross((1., 0., 0.), T) basis.append(B) N = cross(T, B) basis.append(N) if mode == 'Ynat': t = interpolate.splev(s, tck, der=1) xp = Vector([float(t[0]), float(t[1]), float(t[2])]) T = xp.unit() basis.append(T) B = cross((0., 1., 0.), T) basis.append(B) N = cross(T, B) basis.append(N) if mode == 'Znat': t = interpolate.splev(s, tck, der=1) xp = Vector([float(t[0]), float(t[1]), float(t[2])]) T = xp.unit() basis.append(T) B = cross((0., 0., 1.), T) basis.append(B) N = cross(T, B) basis.append(N) matrix = np.zeros((3, 3), dtype=float) for i in range(3): matrix[i] = basis[i] return Frame((orig, matrix))
med_rot = lambda s: 0. med_gen = ParametricCurve3D(funX, funY, funZ) medax = Extrusion(cir_pol, med_gen, scale=funR, rotate=med_rot, n=90) fin_scale = lambda s: 0.08 finR = lambda s: 0. finX = lambda s: deltaX / 2. finY = lambda s: 0. finZ = lambda s: 0.9 * (1. - s) fin_rot = lambda s: 0. fin_gen = ParametricCurve3D(finX, finY, finZ) fin = Extrusion(fin_pol, fin_gen, mode=Vector([0., 1., 0.]), scale=fin_scale, rotate=fin_rot, n=13) print fin medax.pop_to_geom(geom) aft_wing.pop_to_geom(geom) fore_wing.pop_to_geom(geom) fin.pop_to_geom(geom) write_geo('medax', geom) import sys #fore_cad = extrusion_to_ruled_surfaces(fore_wing, cap = True) #aft_cad = extrusion_to_ruled_surfaces(aft_wing, cap = True) wing1 = extrusion_to_solid(fore_wing, 'fore')
x = [0., -0.125, 0.0, .125] y = [0., 1., 2., 3.] z = [0., 0.125, 0., -0.125] pf = Profile(typ='fon', par=[0.99, 0.1, 0.018, 0.035, 0.001], npt=11) # creation of the 2d profile pol = pf.polyline(closed=True) # TODO : Profile should herit of Polyline_2D geom = pg.built_in.Geometry() a_pt = [Point([x[i], y[i], z[i]]) for i in range(len(x))] from youbastard.geometry.Spline3D import Spline3D spline = Spline3D(a_pt) ndisc = 20 fa = spline.frame_array(mode=Vector([0., 0., 1.]), n=ndisc) for f in fa: pp = pol.to_frame(f, scale=0.2) pp.pop_to_geom(geom) cpol = spline.control_polyline pol_gen = spline.discretize(ndisc) sym = spline.symmetrize() fasym = sym.frame_array(mode=Vector([0., 0., 1.]), n=ndisc) sym_pol_gen = sym.discretize(ndisc) for i, f in enumerate(fa): bas = f[1] new_bas = [[-bas[0][0], -bas[0][1], -bas[0][1]],
def piecewise_bezier_polyline(start_value=0., end_value=0., *largs): import matplotlib.pyplot as plt from youbastard.geometry.Point import Point from youbastard.geometry.Vector import Vector from youbastard.geometry.Line import Line from youbastard.geo_functions import cross, dot, angle, intersect_2_lines prev = [0., start_value] last = [1., end_value] bezier_parts = [[prev]] plt.clf() plt.axis('equal') plt.scatter([prev[0], last[0]], [prev[1], last[1]], c='k') for i, cpl in enumerate(largs[0]): if i == len(largs[0]) - 1: nex = last else: nex = largs[0][i + 1] pt = [cpl[0], cpl[1]] tmppt = Point([pt[0], pt[1], 0.]) plt.scatter(pt[0], pt[1], c='k') rad = cpl[2] vec1 = Vector([pt[0] - prev[0], pt[1] - prev[1], 0.]) vec2 = Vector([nex[0] - pt[0], nex[1] - pt[1], 0.]) Z = Vector([0., 0., 1.]) ang = angle(vec1, vec2, plane_normal=Z) if ang > 0.: sgn = 1. elif ang < 0.: sgn = -1. print ang norm1 = sgn * cross(Z, vec1).unit() norm2 = sgn * cross(Z, vec2).unit() l1 = Line([Point([prev[0], prev[1], 0.]), vec1]) l2 = Line([Point([pt[0], pt[1], 0.]), vec2]) ln1 = Line([ Point([prev[0] + norm1[0] * rad, prev[1] + norm1[1] * rad, 0.]), vec1 ]) ln2 = Line([ Point([nex[0] + norm2[0] * rad, nex[1] + norm2[1] * rad, 0.]), vec2 ]) center_arc = intersect_2_lines(ln1, ln2) if center_arc: cen = [center_arc[j] for j in range(2)] lnorm1 = Line([center_arc, -norm1]) lnorm2 = Line([center_arc, -norm2]) start = intersect_2_lines(lnorm1, l1) end = intersect_2_lines(lnorm2, l2) vecstart = Vector([start[i] - tmppt[i] for i in range(3)]) vecend = Vector([end[i] - tmppt[i] for i in range(3)]) if vecstart.norm > 0.5 * vec1.norm: print 'too long' tmpvec = vecstart.unit() start = Point( [tmppt[i] + 0.5 * vec1.norm * tmpvec[i] for i in range(3)]) if vecend.norm > 0.5 * vec2.norm: tmpvec = vecend.unit() end = Point( [tmppt[i] + 0.5 * vec2.norm * tmpvec[i] for i in range(3)]) bezier_parts[-1].append([start[0], start[1]]) bezier_parts.append([[start[0], start[1]], [pt[0], pt[1]], [end[0], end[1]]]) bezier_parts.append([[end[0], end[1]]]) plt.scatter([start[0], end[0]], [start[1], end[1]], c='g') else: cen = pt bezier_parts[-1].append([pt[0], pt[1]]) bezier_parts.append([[pt[0], pt[1]]]) plt.scatter(cen[0], cen[1], c='r') prev = pt bezier_parts[-1].append([last[0], last[1]]) polx = [] poly = [] for bp in bezier_parts: polx += [p[0] for p in bp] poly += [p[1] for p in bp] plt.plot(polx, poly) def func(parameter): ctpts = None for i, bp in enumerate(bezier_parts): #print parameter,bp[0][0],bp[-1][0], len(bp) if (bp[0][0] <= parameter) and (parameter <= bp[-1][0]): ctpts = bp break s = (parameter - ctpts[0][0]) / (ctpts[-1][0] - ctpts[0][0]) return de_casteljau(ctpts, s)[1] N = 1000 x = [float(i) / float(N - 1) for i in range(N)] fx = [func(s) for s in x] plt.plot(x, fx, '.') plt.show() return func