def draw_circle(self, df_calc, ax1, pt): x = df_calc['x'] y = df_calc['y']
x_m = np.mean(x) y_m = np.mean(y)
method_2 = "leastsq"
def calc_R(c): """ calculate the distance of each 2D points from the center c=(xc, yc) """ return np.sqrt((x - c[0]) ** 2 + (y - c[1]) ** 2)
def calc_ecart(c): """ calculate the algebraic distance between the 2D points and the mean circle centered at c=(xc, yc) """ Ri = calc_R(c) return Ri - Ri.mean()
center_estimate = x_m, y_m try: center_2, ier = optimize.leastsq(calc_ecart, center_estimate) except Exception as e: import traceback traceback.print_exc() errMsg = traceback.format_exc() self.status.config(fg="red", font=("simsun", 16)) self.statusStr.set('圆弧计算失败. 请调整计算点数后重试...') self.log.error("arc calc exception." + errMsg) return
xc_2, yc_2 = center_2 Ri_2 = calc_R(center_2) R_2 = Ri_2.mean() residu_2 = sum((Ri_2 - R_2) ** 2)
print('centerPoint x={},y={},r={}'.format(xc_2, yc_2, R_2))
pt['nameShow'] = pt['name'] + '\nr={:.4f}um'.format(R_2) pt['annotate'].remove() bbox = dict(boxstyle="round", fc="0.5") pt['annotate'] = plt.annotate(pt['nameShow'], xy=(pt['points'][0] + (pt['points'][2] - pt['points'][0]) / 2, pt['points'][1] + abs(pt['points'][3] - pt['points'][1]) / 3 * 2), bbox=bbox, xytext=(0, 0), xycoords='data', textcoords='offset points', fontsize=12, ha='center')
if 'arc' in pt: for it in pt['arc']: it.remove() self.canvas.draw_idle() pt['arc'].clear()
line1, = ax1.plot(x, y, 'ro', label='data', ms=9, mec='b', mew=1) pt['arc'].append(line1)
theta_fit = np.linspace(-np.pi, np.pi, 180)
x_fit2 = xc_2 + R_2 * np.cos(theta_fit) y_fit2 = yc_2 + R_2 * np.sin(theta_fit)
line2, = ax1.plot(x_fit2, y_fit2, 'k--', label=method_2, lw=2) pt['arc'].append(line2)
line3, = ax1.plot([xc_2], [yc_2], 'gD', mec='r', mew=1) pt['arc'].append(line3)
self.ax.set_ymargin(0.3) self.ax.autoscale(enable=True, tight=False) self.ax.set_aspect('equal', adjustable='box', anchor='C')
self.canvas.draw_idle()
|