def __init__(self, origin, along_axis, radius, debug=False): self.outer_radius = radius self.axis = self.get_axis(along_axis) xdir = self.get_ortho_vector(self.axis) self.base = cq.Plane(cq.Vector(origin), xdir, self.axis.toTuple()) if debug: utils.make_debug_cylinder(self.base, self.outer_radius)
def resulting_plane(shape0): p0 = resulting_pln(shape0) return cq.Plane( cq.Vector(p0.Location()), cq.Vector(p0.XAxis().Direction()), cq.Vector(p0.Axis().Direction()), )
def get_mate_center(self, angle=0): """ Mate at ring's center rotated ``angle`` degrees. :param angle: rotation around z-axis (unit: deg) :type angle: :class:`float` :return: mate in ring's center rotated about z-axis :rtype: :class:`Mate <cqparts.constraint.Mate>` """ return Mate(self, CoordSystem.from_plane( cadquery.Plane( origin=(0, 0, self.width / 2), xDir=(1, 0, 0), normal=(0, 0, 1), ).rotated((0, 0, angle)) # rotate about z-axis ))
def belt_wire_dir (center_sep, rad1, rad2, fc_axis_l = VX, fc_axis_s = VY, ref_l = 1, ref_s = 1, pos=V0): """ Makes a shape of a wire with 2 circles and exterior tangent lines check: https://en.wikipedia.org/wiki/Tangent_lines_to_circles It is not easy to draw it well rad1 and rad2 can be exchanged, rad1 doesnt have to be larger .... fc_axis_s : ( \ tangent | rad1 : ( \ .. rad2 |--> fc_axis_l, on the direction of rad2 .--( + +)-- ( /: ( / : : : :...: + center_sep .... fc_axis_s : ( \ tangent | rad1 : ( \ .. rad2 | --( + +)-- |--> fc_axis_l, on the direction of rad2 ( /: centered on this axis ( / : : : :...: ref_l: 3 2 1 Arguments: center_sep: separation of the circle centers rad1: Radius of the firs circle, on the opposite direction of fc_axis_l fc_axis_l: vector on the direction circle centers, pointing to rad2 fc_axis_s: vector on the direction perpendicular to fc_axis_l, on the plane of the wire ref_l: reference (zero) of the fc_axis_l 1: reference on the center 2: reference at one of the semicircle centers (point 2) the other circle center will be on the direction of fc_axis_l 3: reference at the end of rad1 circle the other end will be on the direction of fc_axis_l pos: FreeCAD vector of the position of the reference returns the shape of the wire """ # normalize the axis axis_l = DraftVecUtils.scaleTo(fc_axis_l,1) axis_s = DraftVecUtils.scaleTo(fc_axis_s,1) # .... fc_axis_s # : ( \ tangent | # rad1 : ( \ .. rad2 | # --3 2 1 45-- |--> fc_axis_l, on the direction of rad2 # ( /: centered on this axis # ( / : # : : # :...: # + center_sep # ----- Distance vectors on axis_l # distance from 1 to 2 in axis_l fc_1_2_l = DraftVecUtils.scale(axis_l, -center_sep/2.) fc_2_3_l = DraftVecUtils.scale(axis_l, -rad1) fc_2_4_l = DraftVecUtils.scale(axis_l, center_sep) fc_4_5_l = DraftVecUtils.scale(axis_l, rad2) fc_2_5_l = fc_2_4_l + fc_4_5_l # ----- reference is point 2 on axis_l # vector to go from the reference point to point 2 in l if ref_l == 1: # ref on circle center sep refto_2_l = fc_1_2_l elif ref_l == 2: # ref on circle center (rad1) refto_2_l = V0 elif ref_l == 3: # ref at the left end refto_2_l = fc_2_3_l.negative() else: logger.error('wrong ref_l in shp_belt_wire_dir') # Now define the center of the rad1 circle # and everything will be defined from this point # ln: L axis Negative side # lp: L axis Positive side # sn: S axis Negative side # sp: S axis Positive side # s0: S axis at zero # # .... ln_sp fc_axis_s # : ( \ tangent | # rad1 : ( \ lp_sp | # ln_s0 2 4lp_s0 |--> fc_axis_l, on the direction of rad2 # ( / lp_sn centered on this axis # ( / # lp_sp # # cs_rad1 is point 2 (center of circle 1) #cs_rad1 = pos + refto_2_l # reference at point 3 (ln_s0) cs_rad1 = refto_2_l + fc_2_3_l.negative() # cs_rad2 is point 4 (center of circle 2) cs_rad2 = cs_rad1 + fc_2_4_l # ln_s0 is point 3 ln_s0_pos = cs_rad1 + fc_2_3_l # should be 0,0 # lp_s0 is point 5 lp_s0_pos = cs_rad2 + fc_4_5_l dif_rad = float(abs(rad1 - rad2)) # Since we take our reference on axis_l, they are aligned, like if they were # on axis X, and axis Y would be zero. # therefore, angle gamma is zero (se wikipedia) # check: https://en.wikipedia.org/wiki/Tangent_lines_to_circles # the angle beta of the tanget is calculate from pythagoras: # the length (separation between centers) and dif_rad beta = math.atan (dif_rad/center_sep) #print('beta %f', 180*beta/math.pi) #print('beta %f', beta*math.pi/2) # depending on who is larger rad1 or rad2, the negative angle will be either # on top or down of axis_s # # ( \ # ( /alfa beta\ which is 90-beta # ( ) # ( / # ( / # cos_beta = math.cos(beta) sin_beta = math.sin(beta) tan_axis_s_rad1add = DraftVecUtils.scale(axis_s, rad1 * cos_beta) tan_axis_s_rad2add = DraftVecUtils.scale(axis_s, rad2 * cos_beta) if rad1 > rad2: # then it will be positive on axis_l on rad1 and rad2 tan_axis_l_rad1add = DraftVecUtils.scale(axis_l, rad1 * sin_beta) tan_axis_l_rad2add = DraftVecUtils.scale(axis_l, rad2 * sin_beta) else: tan_axis_l_rad1add = DraftVecUtils.scale(axis_l, - rad1 * sin_beta) tan_axis_l_rad2add = DraftVecUtils.scale(axis_l, - rad2 * sin_beta) ln_sp_pos = cs_rad1 + tan_axis_l_rad1add + tan_axis_s_rad1add ln_sn_pos = cs_rad1 + tan_axis_l_rad1add + tan_axis_s_rad1add.negative() lp_sp_pos = cs_rad2 + tan_axis_l_rad2add + tan_axis_s_rad2add lp_sn_pos = cs_rad2 + tan_axis_l_rad2add + tan_axis_s_rad2add.negative() #cq_plane = cq.Plane(origin=(pos.x,pos.y,pos.z), xDir=fc_axis_l, # normal=fc_axis_l.cross(fc_axis_s)) #cq_plane = cq.Plane(origin=(lp_sp_pos.x,lp_sp_pos.y,pos.z), cq_plane = cq.Plane(origin=(pos.x,pos.y,pos.z), xDir=axis_s.negative(), normal=axis_l.cross(axis_s)) lp_sp_pos_y = lp_sp_pos.dot(axis_l) lp_sp_pos_x = lp_sp_pos.dot(axis_s) lp_s0_pos_y = lp_s0_pos.dot(axis_l) lp_s0_pos_x = lp_s0_pos.dot(axis_s) lp_sn_pos_y = lp_sn_pos.dot(axis_l) lp_sn_pos_x = lp_sn_pos.dot(axis_s) ln_sp_pos_y = ln_sp_pos.dot(axis_l) ln_sp_pos_x = ln_sp_pos.dot(axis_s) ln_s0_pos_y = ln_s0_pos.dot(axis_l) ln_s0_pos_x = ln_s0_pos.dot(axis_s) ln_sn_pos_y = ln_sn_pos.dot(axis_l) ln_sn_pos_x = ln_sn_pos.dot(axis_s) result = cq.Workplane(cq_plane).move(lp_sp_pos_x,lp_sp_pos_y)\ .threePointArc((lp_s0_pos_x, lp_s0_pos_y), (lp_sn_pos_x, lp_sn_pos_y))\ .lineTo(ln_sn_pos_x,ln_sn_pos_y)\ .threePointArc((ln_s0_pos_x, ln_s0_pos_y), (ln_sp_pos_x, ln_sp_pos_y))\ .close() return (result)
def _create_workplane(v_center: cq.Vector, v_xaxis: cq.Vector, v_zaxis: cq.Vector) -> cq.Workplane: return cq.Workplane(cq.Plane(v_center, v_xaxis, v_zaxis), origin=v_center)
def plane(self): normal = self.normal() return cq.Plane(self.origin, (math.cos(math.radians( self.z_rot)), math.sin(math.radians(self.z_rot)), 0), (normal[0], normal[1], normal[2]))