def draw(self, cnvs, color, draw_center=True): if eeq(self.p0.x - self.center.x, 0.0): p0_angle = 90 if self.p0.y > self.center.y else 270 else: p0_angle = get_angle( float(self.p0.x - self.center.x), float(self.p0.y - self.center.y)) * 180. / np.pi if eeq(self.p1.x - self.center.x, 0.0): p1_angle = 90 if self.p1.y > self.center.y else 270 else: p1_angle = get_angle( float(self.p1.x - self.center.x), float(self.p1.y - self.center.y)) * 180. / np.pi halfpl = get_halfplane(self.p0, self.p1, self.center) if -1 == halfpl: p0_angle, p1_angle = p1_angle, p0_angle arc = mpt.Arc((float(self.center.x), float(self.center.y)), 2. * float(self.radius), 2. * float(self.radius), angle=0, theta1=p0_angle, theta2=p1_angle, ec=color) cnvs.add_patch(arc) if draw_center: crc = mpt.Circle((float(self.center.x), float(self.center.y)), radius=float(0.2), color=color, fill=False) cnvs.add_patch(crc)
def circles_are_equal(cntr0, radius0, cntr1, radius1): x0 = float(cntr0.x) y0 = float(cntr0.y) r0 = float(radius0) x1 = float(cntr1.x) y1 = float(cntr1.y) r1 = float(radius1) return (eeq(x0, x1) and eeq(y0, y1) and eeq(r0, r1))
def get_radii(poly): n = len(poly) - 1 radii = [] for i in range(1, n): a = poly[i - 1] b = poly[i] c = poly[i + 1] r = get_radius(a, b, c) if r != None and not eeq(r, 0.): radii.append(1. / r) else: radii.append(0.) #None) res = np.array(radii) res = res * (res < 20) + (res > 20) * 20 return res
def get_arc_seg(pt, tang, radius, jnc_cntr, jnc_radius, prev_start, prev_end): init_line = Line(pt, pt + tang) tang_perp = init_line.perpendicular_line(pt).direction.unit aux_cntr1 = pt + tang_perp * radius aux_cntr2 = pt - tang_perp * radius aux_cntr = get_closest_pt(aux_cntr1, aux_cntr2, jnc_cntr) intr = get_circles_intersection(aux_cntr, radius, jnc_cntr, jnc_radius) DEBUG = 'IN_DEBUG' in globals() if DEBUG and IN_DEBUG: crc = mpt.Circle( [float(aux_cntr.x), float(aux_cntr.y)], radius=float(radius), ec="#7DCEA0", fill=False) plt.gca().add_patch(crc) crc = mpt.Circle( [float(aux_cntr.x), float(aux_cntr.y)], radius=float(0.05), color="#7DCEA0", fill=True) plt.gca().add_patch(crc) if isinstance(intr, Circle) or 0 == len(intr): segm_min = segm_max = (pt, -1) #raise ValueError("No intersection for secondary biarc center") elif 1 == len(intr): #min_prev, max_prev = order_arc_seg(prev_start, prev_end, jnc_cntr) #intr_ang = get_angle(float(intr[0].x - jnc_cntr.x), # float(intr[0].y - jnc_cntr.y)) * 180 / np.pi np_inx = np.array([intr[0].x, intr[0].y]) np_pstart = np.array([prev_start.x, prev_start.y]) np_pend = np.array([prev_end.x, prev_end.y]) #if eeq(intr_ang, min_prev[1]) or eeq(intr_ang, max_prev[1]): if vec_eeq(np_inx, np_pstart) or vec_eeq(np_inx, np_pend): segm_min = (prev_start, -1) segm_max = (prev_end, -1) else: segm_min = segm_max = (intr[0], -1) elif 2 == len(intr): min_intr, max_intr = order_arc_seg(intr[0], intr[1], jnc_cntr) min_prev, max_prev = order_arc_seg(prev_start, prev_end, jnc_cntr) if max_intr[1] < min_prev[1] or min_intr[1] > max_prev[1] \ or eeq(max_intr[1], min_prev[1]) or eeq(min_intr[1], max_prev[1]): segm_min = (prev_start, -1) segm_max = (prev_end, -1) else: segm_min = max([min_intr, min_prev], key=lambda x: x[1]) segm_max = min([max_intr, max_prev], key=lambda x: x[1]) DEBUG = 'IN_DEBUG' in globals() if DEBUG and IN_DEBUG: crc = mpt.Circle( [float(intr[0].x), float(intr[0].y)], radius=float(0.05), color="#FFCC99", fill=True) plt.gca().add_patch(crc) crc = mpt.Circle( [float(intr[1].x), float(intr[1].y)], radius=float(0.05), color="#FFCC99", fill=True) plt.gca().add_patch(crc) #plt.gca().add_patch(crc) #plt.axis('equal') #plt.xlim([-5, 20]) #plt.ylim([-15, 10]) #plt.show() return segm_min[0], segm_max[0]
def get_circles_intersection(c0, r0, c1, r1, c0color="#7DCEA0", c1color="#FFCC99"): DEBUG = 'IN_DEBUG' in globals() if DEBUG and IN_DEBUG: crc = mpt.Circle([float(c0.x), float(c0.y)], radius=float(r0), ec=c0color, fill=False) plt.gca().add_patch(crc) crc = mpt.Circle([float(c1.x), float(c1.y)], radius=float(r1), color=c1color, fill=False) plt.gca().add_patch(crc) if circles_are_equal(c0, r0, c1, r1): intr = [] else: c2c_uvec = Line(c0, c1, evaluate=False).direction.unit pts = [ center + c2c_uvec * sign * radius for center, radius in ((c0, r0), (c1, r1)) for sign in (1, -1) ] pts_coords = [(float(p.x), float(p.y)) for p in pts] eq_pts_idxs = check_equal_points(pts_coords) if eq_pts_idxs: # we have one point touch intr = [pts[eq_pts_idxs[0]]] else: circ1_is_in_circ0 = pt_is_between(pts_coords[0], pts_coords[2], pts_coords[1]) \ and pt_is_between(pts_coords[0], pts_coords[3], pts_coords[1]) circ0_is_in_circ1 = pt_is_between(pts_coords[2], pts_coords[0], pts_coords[3]) \ and pt_is_between(pts_coords[2], pts_coords[1], pts_coords[3]) complete_inclusion = circ1_is_in_circ0 or circ0_is_in_circ1 if complete_inclusion: # one circle is completely inside the other intr = [] else: # generic case - 2 points intersection c2c_dist = float(c0.distance(c1)) cos_alpha = (r0**2 + c2c_dist**2 - r1**2) / (2. * r0 * c2c_dist) intr_proj_len = r0 * cos_alpha intr_offset = 0. if eeq( cos_alpha, 1.) else r0 * ((1. - cos_alpha**2.)**0.5) intr_proj_pt = c0 + c2c_uvec * intr_proj_len intr_perp = Point(-c2c_uvec.y, c2c_uvec.x, evaluate=False) intr = [ intr_proj_pt + intr_perp * sign * intr_offset for sign in (1., -1.) ] #intr = junc_circle.intersection(Circle(aux_cntr, radius, evaluate=False)) DEBUG = 'IN_DEBUG' in globals() #if DEBUG and IN_DEBUG: # if 0 < len(intr): # crc = mpt.Circle([float(intr[0].x), float(intr[0].y)], # radius = float(0.1), color = "#FFCC99", fill=True) # plt.gca().add_patch(crc) # if 1 < len(intr): # crc = mpt.Circle([float(intr[1].x), float(intr[1].y)], # radius = float(0.1), color = "#FFCC99", fill=True) # plt.gca().add_patch(crc) return intr
def get_slope(a, b): dx = a[0] - b[0] dy = a[1] - b[1] if eeq(dx, 0.): return 0.0 return dy / dx