示例#1
0
    def walk_curve_from_front(self, curve, xstart, target_dist):
        #print "walk from " + str(xstart) + " dist of " + str(target_dist)
        n = len(curve)
        dist = 0
        cur = ( xstart, self.simple_interp(curve, xstart) )
        next_index = spline.binsearch(curve, xstart) + 1
        if next_index < n:
            dist_to_next = self.dist_2d(cur, curve[next_index])
        else:
            # ran out of points
            return cur[0]
        #print "idx = " + str(next_index) + " dist_to_next = " + str(dist_to_next)
        while dist + dist_to_next < target_dist:
            dist += dist_to_next
            cur = curve[next_index]
            next_index += 1
            if next_index < n:
                dist_to_next = self.dist_2d(cur, curve[next_index])
            else:
                # ran out of points
                return cur[0]
        rem = target_dist - dist
        pct = rem / dist_to_next
        dx = curve[next_index][0] - cur[0]

        return cur[0] + dx * pct
示例#2
0
    def walk_curve_from_back(self, curve, xend, target_dist):
        print "walk from " + str(xend) + " dist of " + str(target_dist)
        n = len(curve)
        print "curve is " + str(n) + " points"
        dist = 0
        cur = ( xend, self.simple_interp(curve, xend) )
        prior_index = spline.binsearch(curve, xend)
        print "prior_index = " + str(prior_index)
        if prior_index >= 0:
            dist_to_prior = self.dist_2d(cur, curve[prior_index])
        else:
            # ran out of points
            return cur[0]
        print "idx = " + str(prior_index) + " dist_to_prior = " + str(dist_to_prior)
        while dist + dist_to_prior < target_dist:
            dist += dist_to_prior
            cur = curve[prior_index]
            prior_index -= 1
            if prior_index >= 0:
                dist_to_prior = self.dist_2d(cur, curve[prior_index])
            else:
                # ran out of points
                return cur[0]
        rem = target_dist - dist
        pct = rem / dist_to_prior
        dx = cur[0] - curve[prior_index][0]

        return cur[0] - dx * pct
示例#3
0
    def walk_curve_from_back(self, curve, xend, target_dist):
        print "walk from " + str(xend) + " dist of " + str(target_dist)
        n = len(curve)
        print "curve is " + str(n) + " points"
        dist = 0
        cur = (xend, self.simple_interp(curve, xend))
        prior_index = spline.binsearch(curve, xend)
        print "prior_index = " + str(prior_index)
        if prior_index >= 0:
            dist_to_prior = self.dist_2d(cur, curve[prior_index])
        else:
            # ran out of points
            return cur[0]
        print "idx = " + str(prior_index) + " dist_to_prior = " + str(
            dist_to_prior)
        while dist + dist_to_prior < target_dist:
            dist += dist_to_prior
            cur = curve[prior_index]
            prior_index -= 1
            if prior_index >= 0:
                dist_to_prior = self.dist_2d(cur, curve[prior_index])
            else:
                # ran out of points
                return cur[0]
        rem = target_dist - dist
        pct = rem / dist_to_prior
        dx = cur[0] - curve[prior_index][0]

        return cur[0] - dx * pct
示例#4
0
    def walk_curve_from_front(self, curve, xstart, target_dist):
        #print "walk from " + str(xstart) + " dist of " + str(target_dist)
        n = len(curve)
        dist = 0
        cur = (xstart, self.simple_interp(curve, xstart))
        next_index = spline.binsearch(curve, xstart) + 1
        if next_index < n:
            dist_to_next = self.dist_2d(cur, curve[next_index])
        else:
            # ran out of points
            return cur[0]
        #print "idx = " + str(next_index) + " dist_to_next = " + str(dist_to_next)
        while dist + dist_to_next < target_dist:
            dist += dist_to_next
            cur = curve[next_index]
            next_index += 1
            if next_index < n:
                dist_to_next = self.dist_2d(cur, curve[next_index])
            else:
                # ran out of points
                return cur[0]
        rem = target_dist - dist
        pct = rem / dist_to_next
        dx = curve[next_index][0] - cur[0]

        return cur[0] + dx * pct
示例#5
0
 def get_slope(self, surf="top", xpos=0.0):
     if surf == "top":
         curve = list(self.top)
     else:
         curve = list(self.bottom)
     slopes = spline.derivative1(curve)
     index = spline.binsearch(curve, xpos)
     slope = slopes[index]
     return slope
示例#6
0
 def get_slope(self, surf="top", xpos=0.0):
     if surf == "top":
         curve = list(self.top)
     else:
         curve = list(self.bottom)
     slopes = spline.derivative1(curve)
     index = spline.binsearch(curve, xpos)
     slope = slopes[index]
     return slope
示例#7
0
    def resample(self, xdivs, use_spline):
        self.top = []
        self.bottom = []
        n = len(self.parax)
        totaldist = self.parax[n-1][0]
        # print "total surface dist = " + str(totaldist)

        # extract the top surface
        step = self.nosedist / xdivs
        parax_y2 = spline.derivative2( self.parax )
        paray_y2 = spline.derivative2( self.paray )
        for i in range(0, xdivs+1):
            d = i * step
            if use_spline:
                index = spline.binsearch(self.parax, d)
                x = spline.spline(self.parax, parax_y2, index, d)
                y = spline.spline(self.paray, paray_y2, index, d)
            else:
                x = self.simple_interp(self.parax, d )
                y = self.simple_interp(self.paray, d )
            if x >= 0.0:
                #print str(x) + " " + str(y)
                self.top.append( (x, y) )
        self.top.reverse()

        # extract the bottom surface
        step = (totaldist - self.nosedist) / xdivs
        for i in range(0, xdivs+1):
            d = i * step + self.nosedist
            if use_spline:
                index = spline.binsearch(self.parax, d)
                x = spline.spline(self.parax, parax_y2, index, d)
                y = spline.spline(self.paray, paray_y2, index, d)
            else:
                x = self.simple_interp(self.parax, d )
                y = self.simple_interp(self.paray, d )
            if x < 0.0:
                x = 0.0
            self.bottom.append( (x, y) )
示例#8
0
    def resample(self, xdivs, use_spline):
        self.top = []
        self.bottom = []
        n = len(self.parax)
        totaldist = self.parax[n - 1][0]
        # print "total surface dist = " + str(totaldist)

        # extract the top surface
        step = self.nosedist / xdivs
        parax_y2 = spline.derivative2(self.parax)
        paray_y2 = spline.derivative2(self.paray)
        for i in range(0, xdivs + 1):
            d = i * step
            if use_spline:
                index = spline.binsearch(self.parax, d)
                x = spline.spline(self.parax, parax_y2, index, d)
                y = spline.spline(self.paray, paray_y2, index, d)
            else:
                x = self.simple_interp(self.parax, d)
                y = self.simple_interp(self.paray, d)
            if x >= 0.0:
                #print str(x) + " " + str(y)
                self.top.append((x, y))
        self.top.reverse()

        # extract the bottom surface
        step = (totaldist - self.nosedist) / xdivs
        for i in range(0, xdivs + 1):
            d = i * step + self.nosedist
            if use_spline:
                index = spline.binsearch(self.parax, d)
                x = spline.spline(self.parax, parax_y2, index, d)
                y = spline.spline(self.paray, paray_y2, index, d)
            else:
                x = self.simple_interp(self.parax, d)
                y = self.simple_interp(self.paray, d)
            if x < 0.0:
                x = 0.0
            self.bottom.append((x, y))
示例#9
0
def simple_interp(points, v):
    index = spline.binsearch(points, v)
    n = len(points) - 1
    if index < n:
        xrange = points[index + 1][0] - points[index][0]
        yrange = points[index + 1][1] - points[index][1]
        # print(" xrange = $xrange\n")
        if xrange > 0.0001:
            percent = (v - points[index][0]) / xrange
            # print(" percent = $percent\n")
            return points[index][1] + percent * yrange
        else:
            return points[index][1]
    else:
        return points[index][1]
示例#10
0
    def simple_interp(self, points, v):
        index = spline.binsearch(points, v)
        n = len(points) - 1
        if index < n:
            xrange = points[index+1][0] - points[index][0]
            yrange = points[index+1][1] - points[index][1]
	    # print(" xrange = $xrange\n")
            if xrange > 0.0001:
                percent = (v - points[index][0]) / xrange
                # print(" percent = $percent\n")
                return points[index][1] + percent * yrange
            else:
                return points[index][1]
        else:
            return points[index][1]
示例#11
0
#!/usr/bin/env python

try:
    import spline
except ImportError:
    # if airfoil is not 'installed' append parent dir of __file__ to sys.path
    import sys, os
    sys.path.insert(0, os.path.abspath(os.path.split(os.path.abspath(__file__))[0]+'/../lib'))
    import spline

points = ((0.0, 9.0), (5.0, 11.0), (10, 11.0), (30.0, 6.0))
y2 = spline.derivative2( points )
for x in range(0, 31, 1):
    index = spline.binsearch(points, x)
    y = spline.spline(points, y2, index, x)
    print str(x) + " " + str(y)

示例#12
0
    def build(self):
        if len(self.stations) < 2:
            print "Must define at least 2 stations to build a wing"
            return

        sweep_y2 = spline.derivative2( self.sweep.top )
        taper_y2 = spline.derivative2( self.taper.top )

        # make the base ribs at each defined station
        for index, station in enumerate(self.stations):
            percent = station / self.span

            # generate airfoil
            if not self.tip:
                af = self.root
            else:
                af = airfoil.blend(self.root, self.tip, percent)

            # compute placement parameters
            lat_dist = station
            twist = self.twist * percent

            # compute chord
            if self.taper:
                sp_index = spline.binsearch(self.taper.top, lat_dist)
                chord = spline.spline(self.taper.top, taper_y2, sp_index, lat_dist)
            else:
                print "Cannot build a wing with no chord defined!"
                return

            print "building station @ " + str(lat_dist) \
                + " chord = " + str(chord)

            # compute sweep offset pos if a sweep function provided
            if self.sweep:
                sw_index = spline.binsearch(self.sweep.top, lat_dist)
                sweep_dist = spline.spline(self.sweep.top, sweep_y2, sw_index, \
                                               lat_dist)
            else:
                sweep_dist = 0.0

            # make the rib (cutouts will be handled later)
            label = 'WR' + str(index+1) 
            right_rib = self.make_raw_rib(af, chord, lat_dist, sweep_dist, \
                                              twist, label)
            right_rib.side = "right"
            if percent < 0.001:
                right_rib.nudge = -right_rib.thickness * 0.5
            elif percent > 0.999:
                right_rib.nudge = right_rib.thickness * 0.5
            self.right_ribs.append(right_rib)

            label = 'WL' + str(index+1)
            left_rib = self.make_raw_rib(af, chord, -lat_dist, sweep_dist, \
                                             twist, label)
            left_rib.side = "left"
            if percent < 0.001:
                left_rib.nudge = right_rib.thickness * 0.5
            elif percent > 0.999:
                left_rib.nudge = -right_rib.thickness * 0.5
            self.left_ribs.append(left_rib)

        # make the control surface ribs.  Instead of dividing the
        # original base ribs into two parts, we make copies of the
        # base ribs and then trim off the parts we don't want.  This
        # makes a bit of sense considering we need double ribs at the
        # cutout edges.  We do this in one pass per side, stepping
        # through each rib and seeing if it matches a control surface
        # cutout and if it's an inner, outer, or mid rib.
        new_ribs = []
        for rib in self.right_ribs:
            for flap in self.flaps:
                if self.match_station(flap.start_station, flap.start_station, rib.pos[0]):
                    #print "start station = " + str(rib.pos[0])
                    newrib = copy.deepcopy(rib)
                    rib.nudge = rib.thickness * 0.5
                    newrib.nudge = -rib.thickness * 1.0
                    flap.start_bot_str_pos = newrib.trim_front_wedge(flap.pos, flap.angle)
                    newrib.part = "flap"
                    newrib.has_le = False
                    new_ribs.append(newrib)
                elif self.match_station(flap.end_station, flap.end_station, rib.pos[0]):
                    #print "end station = " + str(rib.pos[0])
                    newrib = copy.deepcopy(rib)
                    rib.nudge = -rib.thickness * 0.5
                    newrib.nudge = rib.thickness * 1.0
                    flap.end_bot_str_pos = newrib.trim_front_wedge(flap.pos, flap.angle)
                    newrib.part = "flap"
                    newrib.has_le = False
                    new_ribs.append(newrib)
                elif self.match_station(flap.start_station, flap.end_station, rib.pos[0]):
                    #print "match flap at mid station " + str(rib.pos[0])
                    newrib = copy.deepcopy(rib)
                    newrib.trim_front_wedge(flap.pos, flap.angle)
                    newrib.part = "flap"
                    newrib.has_le = False
                    new_ribs.append(newrib)
                    rib.trim_rear(flap.pos)
                    rib.has_te = False

        for rib in new_ribs:
            self.right_ribs.append(rib)

        new_ribs = []
        for rib in self.left_ribs:
            for flap in self.flaps:
                if self.match_station(flap.start_station, flap.start_station, rib.pos[0]):
                    #print "start station = " + str(rib.pos[0])
                    newrib = copy.deepcopy(rib)
                    rib.nudge = -rib.thickness * 0.5
                    newrib.nudge = rib.thickness * 1.0
                    flap.start_bot_str_pos = newrib.trim_front_wedge(flap.pos, flap.angle)
                    newrib.part = "flap"
                    newrib.has_le = False
                    new_ribs.append(newrib)
                elif self.match_station(flap.end_station, flap.end_station, rib.pos[0]):
                    #print "end station = " + str(rib.pos[0])
                    newrib = copy.deepcopy(rib)
                    rib.nudge = rib.thickness * 0.5
                    newrib.nudge = -rib.thickness * 1.0
                    flap.end_bot_str_pos =  newrib.trim_front_wedge(flap.pos, flap.angle)
                    newrib.part = "flap"
                    newrib.has_le = False
                    new_ribs.append(newrib)
                elif self.match_station(flap.start_station, flap.end_station, rib.pos[0]):
                    #print "left match flap at station " + str(rib.pos[0])
                    newrib = copy.deepcopy(rib)
                    newrib.trim_front_wedge(flap.pos, flap.angle)
                    newrib.part = "flap"
                    newrib.has_le = False
                    new_ribs.append(newrib)
                    rib.trim_rear(flap.pos)
                    rib.has_te = False
                    #rib.contour.trim(surf="top", discard="rear", cutpos=flap.pos)
                    #rib.contour.trim(surf="bottom", discard="rear", cutpos=flap.pos)
        for rib in new_ribs:
            self.left_ribs.append(rib)

        # now place the leading edge bottom stringer for each flap.
        # This is left until now because this can be very dynamic
        # depending on the wing layout and control surface blending.
        for flap in self.flaps:
            if flap.start_bot_str_pos != None and flap.end_bot_str_pos != None \
                    and flap.edge_stringer_size != None:
                xdist = flap.end_station - flap.start_station
                if math.fabs(xdist) > 0.0001:
                    atstation = flap.start_station
                    ydist = flap.end_bot_str_pos - flap.start_bot_str_pos
                    slope = ydist / xdist
                    half_offset = flap.edge_stringer_size[0] * 0.5
                    if flap.side == "left":
                        atstation *= -1.0
                        slope *= -1.0
                    cutpos = contour.Cutpos(xpos=flap.start_bot_str_pos, \
                                                atstation=atstation, \
                                                slope=slope)
                    cutpos.move(half_offset)
                    cutout = contour.Cutout(surf="bottom", \
                                                orientation="tangent", \
                                                cutpos=cutpos, \
                                                xsize=flap.edge_stringer_size[0], \
                                                ysize=flap.edge_stringer_size[1] )
                    print "making bottom stringer: " + str(flap.start_station) + " - " + str(flap.end_station)
                    stringer = Stringer( cutout, flap.start_station, flap.end_station, "flap" )
                    stringer.side = flap.side
                    self.stringers.append( stringer )
            else:
                print "skipped building a flap bottom stringer"
                print str(flap.start_bot_str_pos)
                print str(flap.end_bot_str_pos)
                print str(flap.edge_stringer_size)

        # do all the cutouts now at the end after we've made and
        # positioned all the ribs for the wing and the control
        # surfaces
        for rib in self.right_ribs:
            self.make_rib_cuts(rib)
        for rib in self.left_ribs:
            self.make_rib_cuts(rib)

        # a quick pass to update labels on "flap" parts after the
        # cutouts so there is half a chance the label ends up on the
        # part itself
        for rib in self.right_ribs:
            if rib.part == "flap":
                rib.relabel_flap()
        for rib in self.left_ribs:
            if rib.part == "flap":
                rib.relabel_flap()
示例#13
0
    def project_contour(self,
                        surf="top",
                        xstart=0,
                        xend=None,
                        xdist=None,
                        ysize=0):
        #print "xstart=" + str(xstart) + " xend=" + str(xend) + " xdist=" + str(xdist)
        curve = []
        #print "surf == " + surf
        if surf == "top":
            curve = list(self.top)
        else:
            curve = list(self.bottom)
        #print str(curve)

        n = len(curve)
        slopes = spline.derivative1(curve)
        shape = []

        # make the exact sweep base line
        dist = 0.0
        xpos = xstart
        #print 'xpos:', xpos, 'curve:', curve
        ypos = self.simple_interp(curve, xstart)
        if ypos:
            shape.append((xpos, ypos))
        index = spline.binsearch(curve, xpos)
        if curve[index][0] <= xpos:
            index += 1
        next_dist = 0
        done = False
        #while index < n and dist + next_dist <= xdist:
        while index < n and not done:
            nextpt = curve[index]
            next_dist = self.dist_2d((xpos, ypos), nextpt)
            if (xdist and dist + next_dist <= xdist) or \
                    (xend and nextpt[0] <= xend):
                dist += next_dist
                xpos = nextpt[0]
                ypos = nextpt[1]
                if ypos:
                    shape.append((xpos, ypos))
                index += 1
            else:
                done = True

        # add the final point of the curve (if needed)
        if index < n and xdist and dist < xdist:
            rem = xdist - dist
            #print "rem = " + str(rem)
            pct = rem / next_dist
            #print "pct of next step = " + str(pct)
            dx = nextpt[0] - xpos
            xpos += dx * pct
            ypos = self.simple_interp(curve, xpos)
            if ypos:
                shape.append((xpos, ypos))
        elif index < n and xend and xpos < xend:
            xpos = xend
            ypos = self.simple_interp(curve, xpos)
            if ypos:
                shape.append((xpos, ypos))

        # project the sweep line at the specified thickness
        result = []
        #print 'shape:', shape
        for p in shape:
            index = spline.binsearch(curve, p[0])
            slope = slopes[index]
            #print 'p:', p
            proj = self.project_point(p, ysize, surf, slope)
            result.append(proj)

        return result
示例#14
0
    def project_contour(self, surf="top", \
                            xstart=0, xend=None, xdist=None, \
                            ysize=0):
        #print "xstart=" + str(xstart) + " xend=" + str(xend) + " xdist=" + str(xdist)
        curve = []
        #print "surf == " + surf
        if surf == "top":
            curve = list(self.top)
        else:
            curve = list(self.bottom)
        #print str(curve)

        n = len(curve)
        slopes = spline.derivative1(curve)
        shape = []

        # make the exact sweep base line
        dist = 0.0
        xpos = xstart
        ypos = self.simple_interp(curve, xstart)
        shape.append( (xpos, ypos) )
        index = spline.binsearch(curve, xpos)
        if curve[index][0] <= xpos:
            index += 1
        next_dist = 0
        done = False
        #while index < n and dist + next_dist <= xdist:
        while index < n and not done:
            nextpt = curve[index]
            next_dist = self.dist_2d( (xpos, ypos), nextpt )
            if (xdist and dist + next_dist <= xdist) or \
                    (xend and nextpt[0] <= xend):
                dist += next_dist
                xpos = nextpt[0]
                ypos = nextpt[1]
                shape.append( (xpos, ypos) )
                index += 1
            else:
                done = True

        # add the final point of the curve (if needed)
        if index < n and xdist and dist < xdist:
            rem = xdist - dist
            #print "rem = " + str(rem)
            pct = rem / next_dist
            #print "pct of next step = " + str(pct)
            dx = nextpt[0] - xpos
            xpos += dx * pct
            ypos = self.simple_interp(curve, xpos)
            shape.append( (xpos, ypos) )
        elif index < n and xend and xpos < xend:
            xpos = xend
            ypos = self.simple_interp(curve, xpos)
            shape.append( (xpos, ypos) )

        # project the sweep line at the specified thickness
        result = []
        for p in shape:
            index = spline.binsearch(curve, p[0])
            slope = slopes[index]
            proj = self.project_point(p, ysize, surf, slope)
            result.append(proj)

        return result
示例#15
0
    def build(self):
        if len(self.stations) < 2:
            print "Must define at least 2 stations to build a wing"
            return

        sweep_y2 = spline.derivative2(self.sweep.top)
        taper_y2 = spline.derivative2(self.taper.top)

        # make the base ribs at each defined station
        for index, station in enumerate(self.stations):
            percent = station / self.span

            # generate airfoil
            if not self.tip:
                af = self.root
            else:
                af = airfoil.blend(self.root, self.tip, percent)

            # compute placement parameters
            lat_dist = station
            twist = self.twist * percent

            # compute chord
            if self.taper:
                sp_index = spline.binsearch(self.taper.top, lat_dist)
                chord = spline.spline(self.taper.top, taper_y2, sp_index,
                                      lat_dist)
            else:
                print "Cannot build a wing with no chord defined!"
                return

            print "building station @ " + str(lat_dist) \
                + " chord = " + str(chord)

            # compute sweep offset pos if a sweep function provided
            if self.sweep:
                sw_index = spline.binsearch(self.sweep.top, lat_dist)
                sweep_dist = spline.spline(self.sweep.top, sweep_y2, sw_index,
                                           lat_dist)
            else:
                sweep_dist = 0.0

            # make the rib (cutouts will be handled later)
            label = 'WR' + str(index + 1)
            right_rib = self.make_raw_rib(af, chord, lat_dist, sweep_dist,
                                          twist, label)
            right_rib.side = "right"
            if percent < 0.001:
                right_rib.nudge = -right_rib.thickness * 0.5
            elif percent > 0.999:
                right_rib.nudge = right_rib.thickness * 0.5
            self.right_ribs.append(right_rib)

            label = 'WL' + str(index + 1)
            left_rib = self.make_raw_rib(af, chord, -lat_dist, sweep_dist,
                                         twist, label)
            left_rib.side = "left"
            if percent < 0.001:
                left_rib.nudge = right_rib.thickness * 0.5
            elif percent > 0.999:
                left_rib.nudge = -right_rib.thickness * 0.5
            self.left_ribs.append(left_rib)

        # at the ends of each control surface we need a full length
        # rib to cap off the space, so we need to create copies of the
        # ribs at these points.
        self.right_ribs = self.make_new_ribs_for_flaps(self.right_ribs,
                                                       'right')
        self.left_ribs = self.make_new_ribs_for_flaps(self.left_ribs, 'left')

        for rib in self.right_ribs:
            rib_pos = rib.pos[0] - rib.nudge
            for flap in self.flaps:
                if self.match_station(flap.start_station, flap.end_station,
                                      rib_pos):
                    if rib.part == "flap":
                        if rib.type == "inner":
                            pos = rib.trim_front_wedge(flap.pos, flap.angle)
                            flap.start_bot_str_pos = pos
                            print "flap start bot = " + str(pos)
                        elif rib.type == "outer":
                            pos = rib.trim_front_wedge(flap.pos, flap.angle)
                            flap.end_bot_str_pos = pos
                            print "flap end bot = " + str(pos)
                        elif rib.type == "inner-shared":
                            #pos = rib.find_flap_bottom_front(flap.pos, flap.angle)
                            pos = rib.trim_front_wedge(flap.pos, flap.angle)
                            flap.start_bot_str_pos = pos
                            print "flap start bot = " + str(pos)
                        elif rib.type == "outer-shared":
                            pos = rib.find_flap_bottom_front(
                                flap.pos, flap.angle)
                            flap.end_bot_str_pos = pos
                            print "flap end bot = " + str(pos)
                        else:
                            # add cut lines
                            rib.add_wedge_cut_lines(flap.pos, flap.angle)
                    else:
                        print "skipping rear trim"
                        # rib.trim_rear(flap.pos)

        for rib in self.left_ribs:
            rib_pos = rib.pos[0] - rib.nudge
            for flap in self.flaps:
                if self.match_station(flap.start_station, flap.end_station,
                                      rib_pos):
                    if rib.part == "flap":
                        if rib.type == "inner":
                            pos = rib.trim_front_wedge(flap.pos, flap.angle)
                            flap.start_bot_str_pos = pos
                            print "flap start bot = " + str(pos)
                        elif rib.type == "outer":
                            pos = rib.trim_front_wedge(flap.pos, flap.angle)
                            flap.end_bot_str_pos = pos
                            print "flap end bot = " + str(pos)
                        elif rib.type == "inner-shared":
                            pos = rib.find_flap_bottom_front(
                                flap.pos, flap.angle)
                            pos = rib.trim_front_wedge(flap.pos, flap.angle)
                            flap.start_bot_str_pos = pos
                            print "flap start bot = " + str(pos)
                        elif rib.type == "outer-shared":
                            pos = rib.find_flap_bottom_front(
                                flap.pos, flap.angle)
                            flap.end_bot_str_pos = pos
                            print "flap end bot = " + str(pos)
                        else:
                            # add cut lines
                            rib.add_wedge_cut_lines(flap.pos, flap.angle)
                    else:
                        print "skipping rear trim"
                        # rib.trim_rear(flap.pos)

        # now place the leading edge bottom stringer for each flap.
        # This is left until now because this can be very dynamic
        # depending on the wing layout and control surface blending.
        for flap in self.flaps:
            if flap.start_bot_str_pos != None and flap.end_bot_str_pos != None \
                    and flap.edge_stringer_size != None:
                xdist = flap.end_station - flap.start_station
                if math.fabs(xdist) > 0.0001:
                    atstation = flap.start_station
                    ydist = flap.end_bot_str_pos - flap.start_bot_str_pos
                    slope = ydist / xdist
                    half_offset = flap.edge_stringer_size[0] * 0.5
                    if flap.side == "left":
                        atstation *= -1.0
                        slope *= -1.0
                    cutpos = contour.Cutpos(xpos=flap.start_bot_str_pos, \
                                                atstation=atstation, \
                                                slope=slope)
                    cutpos.move(half_offset)
                    cutout = contour.Cutout(surf="bottom", \
                                                orientation="tangent", \
                                                cutpos=cutpos, \
                                                xsize=flap.edge_stringer_size[0], \
                                                ysize=flap.edge_stringer_size[1] )
                    print "making bottom stringer: " + str(
                        flap.start_station) + " - " + str(flap.end_station)
                    stringer = Stringer(cutout, flap.start_station,
                                        flap.end_station, "flap")
                    stringer.side = flap.side
                    self.stringers.append(stringer)
            else:
                print "skipped building a flap bottom stringer"
                print str(flap.start_bot_str_pos)
                print str(flap.end_bot_str_pos)
                print str(flap.edge_stringer_size)

        # do all the cutouts now at the end after we've made and
        # positioned all the ribs for the wing and the control
        # surfaces
        for rib in self.right_ribs:
            self.make_rib_cuts(rib)
        for rib in self.left_ribs:
            self.make_rib_cuts(rib)

        # a quick pass to update labels on "flap" parts after the
        # cutouts so there is half a chance the label ends up on the
        # part itself
        for rib in self.right_ribs:
            if rib.part == "flap":
                rib.relabel_flap()
        for rib in self.left_ribs:
            if rib.part == "flap":
                rib.relabel_flap()