예제 #1
0
    def calc_forces(self, start_lines):
        for line_lower in start_lines:
            upper_node = line_lower.upper_node
            vec = line_lower.diff_vector
            if line_lower.upper_node.type != 2:  # not a gallery line
                # recursive force-calculation
                # setting the force from top to down
                lines_upper = self.get_upper_connected_lines(upper_node)
                self.calc_forces(lines_upper)

                force = np.zeros(3)
                for line in lines_upper:
                    if line.force is None:
                        print("error line force not set: {}".format(line))
                    else:
                        force += line.force * line.diff_vector
                # vec = line_lower.upper_node.vec - line_lower.lower_node.vec
                line_lower.force = norm(np.dot(force, normalize(vec)))

            else:
                force = line_lower.upper_node.force
                force_projected = proj_force(force, normalize(vec))
                if force_projected is None:
                    print("shit", line_lower.upper_node.name)
                    line_lower.force = 10
                else:
                    line_lower.force = norm(force_projected)
예제 #2
0
    def get_tangential_comp(self, line, pos_vec):
        # upper_lines = self.get_upper_connected_lines(line.upper_node)
        # first we try to use already computed forces
        # and shift the upper node by residual force
        # we have to make sure to not overcompansate the residual force
        if line.has_geo and line.force is not None:
            r = self.get_residual_force(line.upper_node)
            s = 0

            for con_line in self.get_connected_lines(line.upper_node):
                s += con_line.get_correction_influence(r)
            # the additional factor is needed for stability. A better aproach would be to
            # compute the compansation factor s with a system of linear equation. The movement
            # of the upper node has impact on the compansation of residual force
            # of the lower node (and the other way).
            return normalize(line.diff_vector + r / s * 0.3)

            # if norm(r) == 0:
            #     return line.diff_vector
            # z = r / np.linalg.norm(r)
            # v0 = line.upper_node.vec - line.lower_node.vec
            # s = norm(r)  * (norm(v0) / line.force - v0.dot(z))
            # return normalize(v0 + s * z * 0.1)

        else:
            # if there are no computed forces available, use all the uppermost forces to compute
            # the direction of the line

            tangent = np.array([0., 0., 0.])
            upper_node = self.get_upper_influence_nodes(line)
            for node in upper_node:
                tangent += node.calc_force_infl(pos_vec)
            return normalize(tangent)
예제 #3
0
 def norm_segment_vectors(self):
     """
     return all the normals based on the segments of the data:
     len(data) - 1 == len(normals)
     """
     rotate = lambda x: normalize(x).dot([[0, -1], [1, 0]])
     normvectors = []
     for p1, p2 in self.segments:
         normvectors.append(rotate(normalize(p2 - p1)))
     return np.array(normvectors)
예제 #4
0
 def __init__(self, direction=None):
     if direction is None:
         direction = [1., 0., 0.]
     if len(direction) == 2:
         x, y = normalize(direction)
         self.matrix = np.array([[1 - 2 * x**2, -2 * x * y],
                                 [-2 * x * y, 1 - 2 * y**2]])
     else:
         x, y, z = normalize(direction)
         self.matrix = np.array([[1 - 2 * x**2, -2 * x * y, -2 * x * z],
                                 [-2 * x * y, 1 - 2 * y**2, -2 * y * z],
                                 [-2 * x * z, -2 * y * z, 1 - 2 * z**2]])
예제 #5
0
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 np.array(point_2d + diff_2d * diff_3d.dot(diff_point))
예제 #6
0
    def normvectors(self):
        layer = self.projection_layer
        profnorm = layer.normvector
        get_normvector = lambda x: normalize(np.cross(x, profnorm))

        vectors = [get_normvector(self.data[1] - self.data[0])]
        for i in range(1, len(self.data) - 1):
            vectors.append(
                get_normvector(
                    normalize(self.data[i + 1] - self.data[i]) +
                    normalize(self.data[i] - self.data[i - 1])))
        vectors.append(get_normvector(self.data[-1] - self.data[-2]))

        return vectors
예제 #7
0
파일: cuts.py 프로젝트: luzpaz/OpenGlider
    def apply(self, inner_lists, outer_left, outer_right, amount_3d=None):
        p1, p2 = self.get_p1_p2(inner_lists, amount_3d)
        indices = self._get_indices(inner_lists, amount_3d)

        normvector = normalize(rotation_2d(math.pi / 2).dot(p1 - p2))

        leftcut_index = next(
            outer_left.cut(p1, p2, inner_lists[0][1], extrapolate=True))
        rightcut_index = next(
            outer_right.cut(p1, p2, inner_lists[-1][1], extrapolate=True))

        index_left = leftcut_index[0]
        index_right = rightcut_index[0]

        leftcut = outer_left[index_left]
        rightcut = outer_right[index_right]

        leftcut_index_2 = outer_left.cut(p1 - normvector * self.amount,
                                         p2 - normvector * self.amount,
                                         inner_lists[0][1],
                                         extrapolate=True)
        rightcut_index_2 = outer_right.cut(p1 - normvector * self.amount,
                                           p2 - normvector * self.amount,
                                           inner_lists[-1][1],
                                           extrapolate=True)

        leftcut_2 = outer_left[next(leftcut_index_2)[0]]
        rightcut_2 = outer_right[next(rightcut_index_2)[0]]
        diff_l, diff_r = leftcut - leftcut_2, rightcut - rightcut_2

        curve = PolyLine2D(
            [leftcut, leftcut + diff_l, rightcut + diff_r, rightcut])

        return CutResult(curve, leftcut_index[0], rightcut_index[0], indices)
예제 #8
0
    def projection_layer(self):
        """
        Projection Layer of profile_3d
        """
        p1 = self.data[0]
        diff = [p - p1 for p in self.data]

        xvect = normalize(-diff[self.noseindex])
        yvect = np.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)
        return Plane(self.data[self.noseindex], xvect, yvect)
예제 #9
0
파일: cuts.py 프로젝트: luzpaz/OpenGlider
    def apply(self, inner_lists, outer_left, outer_right, amount_3d=None):
        #p1 = inner_lists[0][0][inner_lists[0][1]]  # [[list1,pos1],[list2,pos2],...]
        #p2 = inner_lists[-1][0][inner_lists[-1][1]]
        p1, p2 = self.get_p1_p2(inner_lists, amount_3d)
        indices = self._get_indices(inner_lists, amount_3d)
        normvector = normalize(rotation_2d(math.pi / 2).dot(p1 - p2))

        newlist = []
        # todo: sort by distance
        cuts_left = list(
            outer_left.cut(p1, p2, inner_lists[0][1], extrapolate=True))
        cuts_left.sort(key=lambda cut: abs(cut[1]))
        leftcut_index = cuts_left[0][0]
        leftcut = outer_left[leftcut_index]

        newlist.append(leftcut)
        newlist.append(leftcut + normvector * self.amount)

        for thislist in inner_lists:
            newlist.append(thislist[0][thislist[1]] + normvector * self.amount)

        cuts_right = list(
            outer_right.cut(p1, p2, inner_lists[-1][1], extrapolate=True))
        cuts_right.sort(key=lambda cut: abs(cut[1]))
        rightcut_index = cuts_right[0][0]
        rightcut = outer_right[rightcut_index]

        newlist.append(rightcut + normvector * self.amount)
        newlist.append(rightcut)

        curve = PolyLine2D(newlist)

        return CutResult(curve, leftcut_index, rightcut_index, indices)
예제 #10
0
 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 = np.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
예제 #11
0
 def calc_force_infl(self, vec):
     v = np.array(vec)
     force = proj_force(self.force, self.vec - v)
     if force is None:
         print(self.name)
         print(self.vec-v, self.force)
         force = 0.00001
     return normalize(self.vec - v) * force 
예제 #12
0
    def mirror(self, p1, p2):
        """
        Mirror against a line through p1 and p2
        """
        p1 = np.array(p1)
        p2 = np.array(p2)
        normvector = normalize(np.array(p1 - p2).dot([[0, -1], [1, 0]]))
        self.data = [
            point - 2 * normvector.dot(point - p1) * normvector
            for point in self.data
        ]

        return self
예제 #13
0
 def normvectors(self):  #RENAME: norm_point_vectors?
     """
     Return Normvectors to the List-Line, heading rhs
     this property returns a normal for every point,
     approximated by the 2 neighbour points (len(data) == len(normals))
     """
     rotate = lambda x: normalize(x).dot([[0, -1], [1, 0]])
     normvectors = [rotate(self.data[1] - self.data[0])]
     for j in range(1, len(self.data) - 1):
         normvectors.append(
             #rotate(normalize(self.data[j + 1] - self.data[j]) + normalize(self.data[j] - self.data[j - 1])))
             rotate(self.data[j + 1] - self.data[j - 1]))
     normvectors.append(rotate(self.data[-1] - self.data[-2]))
     return normvectors
예제 #14
0
파일: cuts.py 프로젝트: luzpaz/OpenGlider
    def apply(self, inner_lists, outer_left, outer_right, amount_3d=None):
        p1, p2 = self.get_p1_p2(inner_lists, amount_3d)
        indices = self._get_indices(inner_lists, amount_3d)

        normvector = normalize(rotation_2d(math.pi / 2).dot(p1 - p2))

        left_start_index = next(
            outer_left.cut(p1, p2, inner_lists[0][1], extrapolate=True))[0]
        right_start_index = next(
            outer_right.cut(p1, p2, inner_lists[-1][1], extrapolate=True))[0]

        pp1 = p1 - normvector * self.amount
        pp2 = p2 - normvector * self.amount
        left_end_index = next(
            outer_left.cut(pp1, pp2, inner_lists[0][1], extrapolate=True))[0]
        right_end_index = next(
            outer_right.cut(pp1, pp2, inner_lists[-1][1], extrapolate=True))[0]

        left_start = outer_left[left_start_index]
        left_end = outer_left[left_end_index]
        right_start = outer_right[right_start_index]
        right_end = outer_right[right_end_index]

        left_piece = outer_left[left_end_index:left_start_index]
        right_piece = outer_right[right_end_index:right_start_index]
        left_piece_mirrored = left_piece[::-1]
        right_piece_mirrored = right_piece[::-1]
        left_piece_mirrored.mirror(p1, p2)
        right_piece_mirrored.mirror(p1, p2)

        # mirror to (p1-p2) -> p'=p-2*(p.normvector)
        last_left, last_right = left_start, right_start
        new_left, new_right = PolyLine2D(None), PolyLine2D(None)

        for i in range(self.num_folds):
            left_this = left_piece if i % 2 else left_piece_mirrored
            right_this = right_piece if i % 2 else right_piece_mirrored
            left_this.move(last_left - left_this[0])
            right_this.move(last_right - right_this[0])
            new_left += left_this
            new_right += right_this
            last_left, last_right = new_left.data[-1], new_right.data[-1]

        curve = new_left + new_right[::-1]

        return CutResult(curve, left_start_index, right_start_index, indices)
예제 #15
0
파일: cuts.py 프로젝트: luzpaz/OpenGlider
    def apply(self, inner_lists, outer_left, outer_right, amount_3d=None):
        """

        :param inner_lists:
        :param outer_left:
        :param outer_right:
        :param amount_3d: list of 3d-shaping amounts
        :return:
        """

        inner_new = []
        point_list = []

        for offset, lst in zip(amount_3d, inner_lists):
            curve, ik = lst
            ik_new = curve.extend(ik, offset)
            inner_new.append([curve, ik_new])

        p1, p2 = self.get_p1_p2(inner_lists, amount_3d)
        normvector = normalize(rotation_2d(math.pi / 2).dot(p1 - p2))

        leftcut_index = next(
            outer_left.cut(p1, p2, inner_lists[0][1], extrapolate=True))
        rightcut_index = next(
            outer_right.cut(p1, p2, inner_lists[-1][1], extrapolate=True))

        index_left = leftcut_index[0]
        index_right = rightcut_index[0]

        leftcut = outer_left[index_left]
        rightcut = outer_right[index_right]

        point_list.append(leftcut)
        point_list.append(leftcut + normvector * self.amount)

        for curve, ik in inner_new:
            point_list.append(curve[ik] + normvector * self.amount)

        point_list.append(rightcut + normvector * self.amount)
        point_list.append(rightcut)

        curve = PolyLine2D(point_list)

        return CutResult(curve, index_left, index_right,
                         [x[1] for x in inner_new])
예제 #16
0
    def add_stuff(self, amount):
        """
        Shift the whole line for a given amount (->Sewing allowance)
        """
        # cos(vectorangle(a,b)) = (a1 b1+a2 b2)/Sqrt[(a1^2+a2^2) (b1^2+b2^2)]
        newlist = []
        second = self.data[0]
        third = self.data[1]
        newlist.append(second + self.norm_segment_vectors[0] * amount)
        for i in range(1, len(self.data) - 1):
            first = second
            second = third
            third = self.data[i + 1]
            d1 = second - first
            d2 = third - second
            cosphi = d1.dot(d2) / np.sqrt(d1.dot(d1) * d2.dot(d2))
            coresize = 1e-8
            if cosphi > 0.9999 or norm(d1) < coresize or norm(d2) < coresize:
                newlist.append(second + self.normvectors[i] * amount / cosphi)
            elif cosphi < -0.9999:  # this is true if the direction changes 180 degree
                n1 = self.norm_segment_vectors[i - 1]
                n2 = self.norm_segment_vectors[i]
                newlist.append(second +
                               self.norm_segment_vectors[i - 1] * amount)
                newlist.append(second + self.norm_segment_vectors[i] * amount)
            else:
                n1 = self.norm_segment_vectors[i - 1]
                n2 = self.norm_segment_vectors[i]
                sign = -1. + 2. * (d2.dot(n1) > 0)
                phi = np.arccos(n1.dot(n2))
                d1 = normalize(d1)
                ext_vec = n1 - sign * d1 * np.tan(phi / 2)
                newlist.append(second + ext_vec * amount)

                # newlist.append(cut(a, b, c, d)[0])
        newlist.append(third + self.norm_segment_vectors[-1] * amount)
        self.data = newlist

        return self
예제 #17
0
    def get_vectors(self, replace_unknown=True):
        # todo: add valign (space)
        vectors = []
        diff = (self.p2 - self.p1) / len(self.text)
        if self.size is not None:
            diff = normalize(diff) * self.size

        if self.align == "left":
            p1 = self.p1.copy()
        elif self.align == "center":
            p1 = self.p1 + (self.p2 - self.p1) / 2 - len(self.text) / 2 * diff
        elif self.align == "right":
            p1 = self.p2 - len(self.text) * diff
        else:
            raise ValueError

        r_x, r_y = diff[0], diff[1]

        rot = np.array([[r_x, -r_y * self.height], [r_y, r_x * self.height]])

        p1 += np.array([-r_y, r_x]) * (self.valign - 0.5)

        for letter in self.text.upper():
            if letter not in text_vectors:
                if replace_unknown:
                    letter = "_"
                else:
                    raise KeyError(
                        "Letter {} from word '{}' not available".format(
                            letter, self.text.upper()))

            if text_vectors[letter]:
                vectors.append(
                    PolyLine2D([p1 + rot.dot(p) for p in text_vectors[letter]],
                               name="text"))
            p1 += diff
        return vectors
예제 #18
0
 def diff_vector(self):
     """
     Line Direction vector (normalized)
     :return:
     """
     return normalize(self.upper_node.vec - self.lower_node.vec)
예제 #19
0
 def normalize(self):
     self.v1 = normalize(self.v1)
     self.v2 = normalize(self.v2 - self.v1 * self.v1.dot(self.v2))
예제 #20
0
 def diff_vector_projected(self):
     return normalize(self.upper_node.vec_proj - self.lower_node.vec_proj)
예제 #21
0
 def v_inf_0(self):
     return normalize(self.v_inf)
예제 #22
0
    inputfile = os.path.abspath(sys.argv[1])
    destfile = os.path.dirname(inputfile) + "/geometry.obj"
    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.profile_numpoints = numpoints
    print("numpoints: ", numpoints)
    midribs = int(sys.argv[2])
    print("midribs: ", midribs)

    glider.export_3d(destfile, midribs=midribs, numpoints=numpoints)

    # Print v_inf, ca_projection, cw_projection
    alpha = math.atan(1 / glider.ribs[0].glide)
    v = glider.data["GESCHWINDIGKEIT"]
    v_inf = [-math.cos(alpha) * v, 0, -math.sin(alpha) * v]
    ca = normalize([-v_inf[2], 0, v_inf[0]])
    print("v_inf ", v_inf)
    print("ca: ", ca)
    print("cw: ", normalize(v_inf))
else:
    print(
        "please give me an input file + number of midribs + numpoints (0=Original)"
    )