def point2d(p1_3d, p1_2d, p2_3d, p2_2d, point_3d): """Returns a third points position relative to two known points (3D+2D)""" # diffwise diff_3d = normalize(p2_3d - p1_3d) diff_2d = normalize(p2_2d - p1_2d) diff_point = point_3d-p1_3d point_2d = p1_2d + diff_2d * diff_3d.dot(diff_point) # length-wise diff_3d = normalize(diff_point - diff_3d * diff_3d.dot(diff_point)) diff_2d = diff_2d.dot([[0, 1], [-1, 0]]) # Rotate 90deg return numpy.array(point_2d + diff_2d * diff_3d.dot(diff_point))
def normvectors(self): if not self._normvectors: self.projection() profnorm = numpy.cross(self.xvect, self.yvect) func = lambda x: normalize(numpy.cross(x, profnorm)) vectors = [func(self.data[1] - self.data[0])] for i in range(1, len(self.data) - 1): vectors.append(func( normalize(self.data[i + 1] - self.data[i]) + normalize(self.data[i] - self.data[i - 1]))) vectors.append(func(self.data[-1] - self.data[-2])) self._normvectors = vectors return self._normvectors
def projection(self): p1 = self.data[0] diff = [p - p1 for p in self.data] xvect = normalize(-diff[self.noseindex]) yvect = numpy.array([0, 0, 0]) for i in range(len(diff)): sign = 1 - 2 * (i > self.noseindex) yvect = yvect + sign * (diff[i] - xvect * xvect.dot(diff[i])) yvect = normalize(yvect) print(xvect, yvect) return Layer(self.data[self.noseindex], xvect, yvect)
def normvectors(self): if not self._normvectors: self.projection() profnorm = numpy.cross(self.xvect, self.yvect) func = lambda x: normalize(numpy.cross(x, profnorm)) vectors = [func(self.data[1] - self.data[0])] for i in range(1, len(self.data) - 1): vectors.append( func( normalize(self.data[i + 1] - self.data[i]) + normalize(self.data[i] - self.data[i - 1]))) vectors.append(func(self.data[-1] - self.data[-2])) self._normvectors = vectors return self._normvectors
def store_calc_par(values, calc_par, key_dict): calc_par["GEOSTEPS"] = try_convert(values[0], int) calc_par["SAGSTEPS"] = try_convert(values[1], int) calc_par["ITER"] = try_convert(values[2], int) speed = calc_par["SPEED"] = try_convert(values[3], float) glide = calc_par["GLIDE"] = try_convert(values[4], float) calc_par["V_INF"] = (speed * normalize(numpy.array([glide, 0., 1.])))
def normvectors(self, j=None): prof1 = self.prof1.data prof2 = self.prof2.data p1 = self.prof1.tangents p2 = self.prof2.tangents # cross differenzvektor, tangentialvektor return [normalize(numpy.cross(p1[i] + p2[i], prof1[i] - prof2[i])) for i in range(len(prof1))]
def export_obj(glider, path, midribs=0, numpoints=None, floatnum=6): other = glider.copy_complete() if numpoints: other.numpoints = numpoints ribs = other.return_ribs(midribs) panels = [] points = [] numpoints = len(ribs[0]) for i in range(len(ribs)): for j in range(numpoints): # Create two Triangles from one rectangle: # Start counting from 1; i->row; j->line panels.append([i * numpoints + j + 1, i * numpoints + j + 2, (i + 1) * numpoints + j + 2]) panels.append([(i + 1) * numpoints + j + 1, i * numpoints + j + 1, (i + 1) * numpoints + j + 2]) # Calculate normvectors first = ribs[i + (i < len(ribs) - 1)][j] - ribs[i - (i > 0)][j] # Y-Axis second = ribs[i][j - (j > 0)] - ribs[i][j + (j < numpoints - 1)] try: points.append((ribs[i][j], normalize(numpy.cross(first, second)))) except ValueError: raise ValueError("vector of length 0 at: i={0}, j={1}: {2}".format(i, j, first)) # TODO: check!? panels = panels[:2 * (len(ribs) - 1) * numpoints - 2] # Write file with open(path, "w") as outfile: for point in points: #point = point[0] * [-1, -1, -1], point[1] * [-1, -1, -1] # Write Normvector outfile.write("vn {0} {1} {2}\n".format(*map(lambda x: round(-x, floatnum), point[1]))) # Write point outfile.write("v {0} {1} {2}\n".format(*map(lambda x: round(-x, floatnum), point[0]))) for polygon in panels: outfile.write("f {0} {1} {2}//{0} {1} {2}\n".format(*polygon)) return True
def tangents(self): second = self.data[0] third = self.data[1] tangents = [normalize(third - second)] for element in self.data[2:]: first = second second = third third = element tangent = numpy.array([0, 0, 0]) for vec in [third - second, second - first]: try: tangent = tangent + normalize(vec) except ValueError: # zero-length vector pass tangents.append(tangent) tangents.append(normalize(third - second)) return tangents
def store_calc_par(values, calc_par, key_dict): calc_par["GEOSTEPS"] = try_convert(values[0], int) calc_par["SAGSTEPS"] = try_convert(values[1], int) calc_par["ITER"] = try_convert(values[2], int) speed = calc_par["SPEED"] = try_convert(values[3], float) glide = calc_par["GLIDE"] = try_convert(values[4], float) calc_par["V_INF"] = ( speed * normalize(numpy.array([glide, 0., 1.])))
def tangents(self): second = self.data[0] third = self.data[1] tangents = [normalize(third - second)] for element in self.data[2:]: first = second second = third third = element tangent = numpy.array([0, 0, 0]) for vec in [third-second, second-first]: try: tangent = tangent + normalize(vec) except ValueError: # zero-length vector pass tangents.append(tangent) tangents.append(normalize(third - second)) return tangents
def get_normvector(self): p1 = self.rib1.point(-1) p2 = self.rib2.point(0) p4 = self.rib1.point(0) p3 = self.rib2.point(-1) return normalize(np.cross(p1 - p2, p3 - p4))
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 calc_forces(self, start_lines): for line_lower in start_lines: vec = line_lower.diff_vector if line_lower.upper_node.type != 2: # not a gallery line lines_upper = self.get_upper_conected_lines( line_lower.upper_node) self.calc_forces(lines_upper) force = numpy.zeros(3) for line in lines_upper: if line.force is None: print("error line force not set") else: force += line.force * line.diff_vector line_lower.force = dot(force, normalize(vec)) else: force = line_lower.upper_node.force line_lower.force = 1/proj_force(force, normalize(vec))
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 calc_forces(self, start_lines): for line_lower in start_lines: vec = line_lower.diff_vector if line_lower.upper_node.type != 2: # not a gallery line lines_upper = self.get_upper_conected_lines( line_lower.upper_node) self.calc_forces(lines_upper) force = numpy.zeros(3) for line in lines_upper: if line.force is None: print("error line force not set") else: force += line.force * line.diff_vector line_lower.force = dot(force, normalize(vec)) else: force = line_lower.upper_node.force line_lower.force = 1 / proj_force(force, normalize(vec))
def test_Cut(self): for thalist in self.vectors: i = random.randint(1, len(thalist)-3) normv = thalist.normvectors dirr = vector.normalize(normv[i]) #dirr = vector.normalize(normv[i-i % 1])+vector.normalize(normv[i - i % 1 + 1]) dirr *= 0.001 p1 = thalist[i]+dirr p2 = thalist[i]-dirr neu = thalist.cut(p1, p2, i-1)
def test_Cut(self): for thalist in self.vectors: i = random.randint(1, len(thalist) - 3) normv = thalist.normvectors dirr = vector.normalize(normv[i]) #dirr = vector.normalize(normv[i-i % 1])+vector.normalize(normv[i - i % 1 + 1]) dirr *= 0.001 p1 = thalist[i] + dirr p2 = thalist[i] - dirr neu = thalist.cut(p1, p2, i - 1)
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 calc_force_infl(self, vec): v = numpy.array(vec) return normalize(self.vec - v) / proj_force(self.force, self.vec - v)
destfile = os.path.dirname(inputfile) + "/geometry.obj" glider = Glider() glider.import_geometry(inputfile) for cell in glider.cells: pass #cell.miniribs.append(openglider.Ribs.MiniRib(0.5, 0.7)) numpoints = int(sys.argv[3]) if numpoints == 0: numpoints = None else: glider.numpoints = numpoints print("numpoints: ", numpoints) midribs = int(sys.argv[2]) print("midribs: ", midribs) glider.export_3d(destfile, midribs=midribs, numpoints=numpoints) # Print vinf, ca_projection, cw_projection alpha = math.atan(1 / glider.ribs[0].glide) v = glider.data["GESCHWINDIGKEIT"] vinf = [-math.cos(alpha) * v, 0, -math.sin(alpha) * v] ca = normalize([-vinf[2], 0, vinf[0]]) print("vinf ", vinf) print("ca: ", ca) print("cw: ", normalize(vinf)) else: print( "please give me an input file + number of midribs + numpoints (0=Original)" )
def v_inf_0(self): return normalize(self.v_inf)
def diff_vector_projected(self): return normalize(self.upper_node.vec_proj - self.lower_node.vec_proj)
def diff_vector(self): return normalize(self.upper_node.vec - self.lower_node.vec)
def get_tangential_comp(self, line, pos_vec): top_nodes = flatten(self.get_top_influence_nodes(line)) tangent = numpy.array([0., 0., 0.]) for node in top_nodes: tangent += node.calc_force_infl(pos_vec) return normalize(tangent) # TODO: why normalize?
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 _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()