Example #1
0
    def generate_spokes(self, root_radius, spoke_width, spokes, mount_radius, mount_hole,
                             unit_factor, unit_label):
        """ given a set of constraints
            - generate the svg path for the gear spokes
            - lies between mount_radius (inner hole) and root_radius (bottom of the teeth)
            - spoke width also defines the spacing at the root_radius
            - mount_radius is adjusted so that spokes fit if there is room
            - if no room (collision) then spokes not drawn
        """

        if not spokes:
            return []

        # Spokes
        collision = False # assume we draw spokes
        messages = []     # messages to send back about changes.
        spoke_holes = []
        r_outer = root_radius - spoke_width

        try:
            spoke_count = spokes
            spokes = [i*2*pi/spokes for i in range(spoke_count)]
        except TypeError:
            spoke_count = len(spokes)
            spokes = [radians(a) for a in spokes]
        spokes.append(spokes[0]+two_pi)

        # checks for collision with spokes
        # check for mount hole collision with inner spokes
        if mount_radius <= mount_hole/2:
            adj_factor = (r_outer - mount_hole/2) / 5

            if adj_factor < 0.1:
                # not enough reasonable room
                collision = True
            else:
                mount_radius = mount_hole/2 + adj_factor # small fix
                messages.append("Mount support too small. Auto increased to %2.2f%s." % (mount_radius/unit_factor*2, unit_label))

        # then check to see if cross-over on spoke width
        for i in range(spoke_count):
            angle = spokes[i]-spokes[i-1]

            if spoke_width >= angle * mount_radius:
                adj_factor = 1.2 # wrong value. its probably one of the points distances calculated below
                mount_radius += adj_factor
                messages.append("Too many spokes. Increased Mount support by %2.3f%s" % (adj_factor/unit_factor, unit_label))

        # check for collision with outer rim
        if r_outer <= mount_radius:
            # not enough room to draw spokes so cancel
            collision = True
        if collision: # don't draw spokes if no room.
            messages.append("Not enough room for Spokes. Decrease Spoke width.")
        else: # draw spokes

            for i in range(spoke_count):
                self.boxes.ctx.save()
                start_a, end_a = spokes[i], spokes[i+1]
                # inner circle around mount
                asin_factor = spoke_width/mount_radius/2
                # check if need to clamp radius
                asin_factor = max(-1.0, min(1.0, asin_factor)) # no longer needed - resized above
                a = asin(asin_factor)

                # is inner circle too small
                asin_factor = spoke_width/r_outer/2
                # check if need to clamp radius
                asin_factor = max(-1.0, min(1.0, asin_factor)) # no longer needed - resized above
                a2 = asin(asin_factor)
                l = vlength(vdiff(point_on_circle(mount_radius, start_a + a),
                                  point_on_circle(r_outer, start_a + a2)))
                self.boxes.moveTo(*point_on_circle(mount_radius, start_a + a), degrees=degrees(start_a))
                self.boxes.polyline(
                    l,
                    +90+degrees(a2), 0,
                    (degrees(end_a-start_a-2*a2), r_outer), 0,
                    +90+degrees(a2),
                    l, 90-degrees(a), 0,
                    (-degrees(end_a-start_a-2*a), mount_radius),
                    0, 90+degrees(a2), 0
                )

                self.boxes.ctx.restore()

        return messages
Example #2
0
    def generate_spokes(self, root_radius, spoke_width, spokes, mount_radius, mount_hole,
                             unit_factor, unit_label):
        """ given a set of constraints
            - generate the svg path for the gear spokes
            - lies between mount_radius (inner hole) and root_radius (bottom of the teeth)
            - spoke width also defines the spacing at the root_radius
            - mount_radius is adjusted so that spokes fit if there is room
            - if no room (collision) then spokes not drawn
        """

        if not spokes:
            return []

        # Spokes
        collision = False # assume we draw spokes
        messages = []     # messages to send back about changes.
        spoke_holes = []
        r_outer = root_radius - spoke_width

        try:
            spoke_count = spokes
            spokes = [i*2*pi/spokes for i in range(spoke_count)]
        except TypeError:
            spoke_count = len(spokes)
            spokes = [radians(a) for a in spokes]
        spokes.append(spokes[0]+two_pi)

        # checks for collision with spokes
        # check for mount hole collision with inner spokes
        if mount_radius <= mount_hole/2:
            adj_factor = (r_outer - mount_hole/2) / 5

            if adj_factor < 0.1:
                # not enough reasonable room
                collision = True
            else:
                mount_radius = mount_hole/2 + adj_factor # small fix
                messages.append("Mount support too small. Auto increased to %2.2f%s." % (mount_radius/unit_factor*2, unit_label))

        # then check to see if cross-over on spoke width
        for i in range(spoke_count):
            angle = spokes[i]-spokes[i-1]

            if spoke_width >= angle * mount_radius:
                adj_factor = 1.2 # wrong value. its probably one of the points distances calculated below
                mount_radius += adj_factor
                messages.append("Too many spokes. Increased Mount support by %2.3f%s" % (adj_factor/unit_factor, unit_label))

        # check for collision with outer rim
        if r_outer <= mount_radius:
            # not enough room to draw spokes so cancel
            collision = True
        if collision: # don't draw spokes if no room.
            messages.append("Not enough room for Spokes. Decrease Spoke width.")
        else: # draw spokes

            for i in range(spoke_count):
                self.boxes.ctx.save()
                start_a, end_a = spokes[i], spokes[i+1]
                # inner circle around mount
                asin_factor = spoke_width/mount_radius/2
                # check if need to clamp radius
                asin_factor = max(-1.0, min(1.0, asin_factor)) # no longer needed - resized above
                a = asin(asin_factor)

                # is inner circle too small
                asin_factor = spoke_width/r_outer/2
                # check if need to clamp radius
                asin_factor = max(-1.0, min(1.0, asin_factor)) # no longer needed - resized above
                a2 = asin(asin_factor)
                l = vlength(vdiff(point_on_circle(mount_radius, start_a + a),
                                  point_on_circle(r_outer, start_a + a2)))
                self.boxes.moveTo(*point_on_circle(mount_radius, start_a + a), degrees=degrees(start_a))
                self.boxes.polyline(
                    l,
                    +90+degrees(a2), 0,
                    (degrees(end_a-start_a-2*a2), r_outer), 0,
                    +90+degrees(a2),
                    l, 90-degrees(a), 0,
                    (-degrees(end_a-start_a-2*a), mount_radius),
                    0, 90+degrees(a2), 0
                )

                self.boxes.ctx.restore()

        return messages