From 7403641a8739bfe60d03cba31b166440c2442608 Mon Sep 17 00:00:00 2001 From: spirkelmann Date: Tue, 27 Aug 2019 22:33:53 +0200 Subject: [PATCH] added angle and distance computation + computation of tangent points --- prototype/circles.py | 92 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 89 insertions(+), 3 deletions(-) diff --git a/prototype/circles.py b/prototype/circles.py index fda173e..7322204 100644 --- a/prototype/circles.py +++ b/prototype/circles.py @@ -3,7 +3,7 @@ import matplotlib.pyplot as plt import math import operator -N = 7 # number of enclosed circles +N = 5 # number of enclosed circles # this function reads and processes data for optimal circle packaging obtained form packomania.com def read_circle_data(N): @@ -40,6 +40,22 @@ def sort_ccw(coords, center): return coords_sort + +# compute the two tangential points at the circle with center c and radius r intersecting the point p +def compute_tangent_points(p, c, r): + b = sqrt((p[0] - c[0]) ** 2 + (p[1] - c[1]) ** 2) + th = acos(r / b) # angle theta + d = atan2(p[1] - c[1], p[0] - c[0]) # direction angle of point p from c + d1 = d + th # direction angle of point T1 from c + d2 = d - th # direction angle of point T2 from c + + T1x = c[0] + r * cos(d1) + T1y = c[1] + r * sin(d1) + T2x = c[0] + r * cos(d2) + T2y = c[1] + r * sin(d2) + + return (T1x, T1y), (T2x, T2y) + # read radius and center coordinates for enclosed circles rtilde, coords = read_circle_data(N) @@ -62,6 +78,7 @@ plt.gca().add_artist(circle) plt.plot(c[0], c[1], 'o') +coords_2 = [] for k in range(0, N): p1 = coords[k] p2 = coords[(k+1) % N] @@ -72,13 +89,16 @@ for k in range(0, N): # vector in direction of midpoint v = m - np.array(c) v = v/np.linalg.norm(v) - plt.plot(m[0], m[1], 'o') + #plt.plot(m[0], m[1], 'o') + + # optimization problem for computing position and radius for a maximal circle fitting in space between two big circles + # and being fully contained in enclosing circle opti = casadi.Opti() r = opti.variable(1) # radius of new circle p = opti.variable(2) # center of new circle - lamb = opti.variable(1) + lamb = opti.variable(1) # distance of center of new circle to center of enclosing circle opti.minimize(-r) opti.subject_to(p == c + v * lamb) @@ -108,8 +128,74 @@ for k in range(0, N): print("lambda = {}".format(lamb)) print("v = {}".format(v)) + coords_2.append(p) + plt.plot(p[0], p[1], 'o') circle = plt.Circle(p, r, fill=False) plt.gca().add_artist(circle) + +# postprocessing solution: +# - output radii for circles +# - output center coordinates, angle w.r.t. origin and distance from origin +outer_radius = 0.15 # desired plate radius in meters +tube1_radius = outer_radius * rtilde +tube2_radius = outer_radius * r + +print("\n------------------") +print("plate radius = {:6.3} m = {:6.2f} mm".format(outer_radius, outer_radius * 1000)) +print("big circles:") +print(" radius = {:6.3} m = {:6.2f} mm".format(tube1_radius, tube1_radius * 1000)) +print(" diameter = {:6.3} m = {:6.2f} mm".format(2*tube1_radius, 2*tube1_radius * 1000)) +print(" coordinates:") +for k in range(0,N): + x = coords[k][0] * 1000 + y = coords[k][1] * 1000 + + t1, t2 = compute_tangent_points((0,0),(x,y), rtilde * 1000) + plt.plot(t1[0] / 1000, t1[1] / 1000, 'o') + plt.plot(t2[0] / 1000, t2[1] / 1000, 'o') + + angle = arctan2(y,x) * 360.0 / (2.0 * math.pi) + dist = (x**2 + y**2)**0.5 + + angle_t1 = arctan2(t1[1], t1[0]) * 360.0 / (2.0 * math.pi) + dist_t1 = (t1[0] ** 2 + t1[1] ** 2) ** 0.5 + + angle_t2 = arctan2(t2[1], t2[0]) * 360.0 / (2.0 * math.pi) + dist_t2 = (t2[0] ** 2 + t2[1] ** 2) ** 0.5 + print(" k = {}, (x,y) = ({:8.3f}, {:8.3f}), angle = {:8.3f} deg, dist = {:8.3f} mm".format(k, x, y, angle, dist)) + print(" t1 = ({:8.3f}, {:8.3f}), angle = {:8.3f} deg, dist = {:8.3f} mm".format(t1[0], t1[1], angle_t1, + dist_t1)) + print(" t2 = ({:8.3f}, {:8.3f}), angle = {:8.3f} deg, dist = {:8.3f} mm".format(t2[0], t2[1], angle_t2, + dist_t2)) +print("\n") + +print("small circles:") +print(" radius = {:6.3} m = {:6.2f} mm".format(tube2_radius, tube2_radius * 1000)) +print(" diameter = {:6.3} m = {:6.2f} mm".format(2*tube2_radius, 2*tube2_radius * 1000)) +print(" coordinates:") +for k in range(0,N): + x = coords_2[k][0] * 1000 + y = coords_2[k][1] * 1000 + + t1, t2 = compute_tangent_points((0, 0), (x, y), r * 1000) + plt.plot(t1[0] / 1000, t1[1] / 1000, 'o') + plt.plot(t2[0] / 1000, t2[1] / 1000, 'o') + + angle = arctan2(y, x) * 360.0 / (2.0 * math.pi) + dist = (x ** 2 + y ** 2) ** 0.5 + + angle_t1 = arctan2(t1[1], t1[0]) * 360.0 / (2.0 * math.pi) + dist_t1 = (t1[0] ** 2 + t1[1] ** 2) ** 0.5 + + angle_t2 = arctan2(t2[1], t2[0]) * 360.0 / (2.0 * math.pi) + dist_t2 = (t2[0] ** 2 + t2[1] ** 2) ** 0.5 + print(" k = {}, (x,y) = ({:8.3f}, {:8.3f}), angle = {:8.3f} deg, dist = {:8.3f} mm".format(k, x, y, angle, dist)) + print(" t1 = ({:8.3f}, {:8.3f}), angle = {:8.3f} deg, dist = {:8.3f} mm".format(t1[0], t1[1], angle_t1, + dist_t1)) + print(" t2 = ({:8.3f}, {:8.3f}), angle = {:8.3f} deg, dist = {:8.3f} mm".format(t2[0], t2[1], angle_t2, + dist_t2)) + + pass \ No newline at end of file