Commit 7c54fa215e715a4f4bfddd2c52987dc7e3af1fc2
1 parent
68f91f03
Added meshing to the block structures and working on non-linear mass
Showing
1 changed file
with
122 additions
and
14 deletions
Show diff stats
voronoi_test.py
... | ... | @@ -7,6 +7,10 @@ Created on Tue Sep 3 13:15:54 2019 |
7 | 7 | """ |
8 | 8 | |
9 | 9 | from scipy.spatial import Voronoi, voronoi_plot_2d |
10 | +from scipy.spatial import Delaunay, delaunay_plot_2d | |
11 | + | |
12 | +from triangle import triangulate | |
13 | +from triangle import plot as triangle_plot | |
10 | 14 | from scipy.interpolate import interp1d |
11 | 15 | #import matplotlib._cntr as cntr |
12 | 16 | from shapely.geometry import Point |
... | ... | @@ -30,13 +34,59 @@ class Polygon_mass: |
30 | 34 | self.get_aabb() |
31 | 35 | self.gen_polygon() |
32 | 36 | self.torque = [] |
37 | + self.vel = 0.0 | |
38 | + self.aa = 0.0 | |
39 | + | |
40 | + | |
41 | + def clear_torques(self): | |
42 | + self.torque = [] | |
33 | 43 | |
34 | 44 | def add_torque(self, p, f): |
45 | + #direction of the torque = cross of (r, f) | |
46 | + #magnitude = ||r||*||f||*sin(theta) | |
47 | + #r = level arm vector | |
35 | 48 | d = self.CoM - p |
36 | 49 | r = np.linalg.norm(self.CoM - p) |
37 | 50 | theta = math.acos(np.dot(d, f)/np.dot(d, d)/np.dot(f, f)) |
38 | - torque = r * math.sin(theta) * f | |
39 | - self.torque.append(torque) | |
51 | + torque = math.sin(theta) * np.sqrt(f[0]*f[0]+f[1]*f[1]) * np.sqrt(r[0]*r[0]+r[1]*r[1]) | |
52 | + #if < 0 then clockwise, else counter | |
53 | + direction = np.cross(r, f) | |
54 | + if direction < 0: | |
55 | + self.torque.append([torque, "clockwise"]) | |
56 | + else: | |
57 | + self.torque.append([torque, "counterclock"]) | |
58 | + | |
59 | + def calculate_moment(self): | |
60 | + | |
61 | + #returns the area of a triangle defined by two points | |
62 | + def area(t): | |
63 | + output = 1.0/2.0*abs(t[0,0]*(t[1,1]-t[2,1]) + t[1,0]*(t[2,1]-t[0,1]) + t[2,0]*(t[0,1]-t[1,1])) | |
64 | + return output | |
65 | + | |
66 | + def center(t): | |
67 | + output = np.asarray([(t[0,0]+t[1,0]+t[2,0])/3.0, (t[0,1]+t[1,1]+t[2,1])/3.0]) | |
68 | + | |
69 | + segs = [] | |
70 | + pts = np.asarray(self.polygon.exterior.xy).T | |
71 | + pts = pts[:-1, :] | |
72 | + for k in range(pts.shape[0]-1): | |
73 | + segs.append([k, k+1]) | |
74 | + segs.append([pts.shape[0]-1, 0]) | |
75 | + mesh = dict(vertices=pts, segments=segs) | |
76 | + #print(self.polygon.area()) | |
77 | + tri = triangulate(mesh, 'pq20D') | |
78 | + moment = 0.0 | |
79 | + #NEED TO ADD MASS maybe? | |
80 | + for i in range(tri['triangles'].shape[0]): | |
81 | + t = tri['vertices'][tri['triangles'][i]] | |
82 | + A = area(t) | |
83 | + C = center(t) | |
84 | + Moi = A+A*np.linalg.norm(C-self.CoM)**2 | |
85 | + moment += Moi | |
86 | + | |
87 | + self.MoI = moment | |
88 | +# triangle_plot(plt.gca(), **tri) | |
89 | +# plt.gca().set_title(str(self.polygon.area)) | |
40 | 90 | |
41 | 91 | def rotate(self, phi, direction = "counterclock"): |
42 | 92 | if("counterclock"): |
... | ... | @@ -62,6 +112,35 @@ class Polygon_mass: |
62 | 112 | plt.scatter(p[:,0], p[:,1], color='r') |
63 | 113 | plt.scatter(self.CoM[0], self.CoM[1], marker='*') |
64 | 114 | |
115 | + | |
116 | + segs = [] | |
117 | + pts = np.asarray(self.polygon.exterior.xy).T | |
118 | + pts = pts[:-1, :] | |
119 | + for k in range(pts.shape[0]-1): | |
120 | + segs.append([k, k+1]) | |
121 | + segs.append([pts.shape[0]-1, 0]) | |
122 | + points = self.G.vertex_properties["pos"].get_2d_array(range(2)).T | |
123 | + segs2 = [] | |
124 | + n_pts = pts.shape[0] | |
125 | + for e in self.G.edges(): | |
126 | + segs2.append([int(e.source())+n_pts, int(e.target())+n_pts]) | |
127 | + | |
128 | + | |
129 | + | |
130 | + pts = np.concatenate((pts, points)) | |
131 | + segs = segs + segs2 | |
132 | + mesh = dict(vertices=pts, segments=segs) | |
133 | + #print(self.polygon.area()) | |
134 | + # tri = triangulate(mesh, 'pq20D') | |
135 | + triangle_plot(plt.gca(), **mesh) | |
136 | + for i in range(len(segs)): | |
137 | + plt.plot((pts[segs[i][0]][0], pts[segs[i][0]][1]), (pts[segs[i][1]][0], pts[segs[i][1]][1]), color='b') | |
138 | + plt.gca().set_title(str(self.polygon.area)) | |
139 | + | |
140 | + #tri = Delaunay(np.asarray(self.polygon.exterior.coords.xy).T) | |
141 | + #tri = triangulate(mesh, 'pq20a' + str(self.polygon.area/100.0)+'D') | |
142 | + #delaunay_plot_2d(tri) | |
143 | + | |
65 | 144 | # for n, contour in enumerate(self.cn): |
66 | 145 | # X = interp1d(np.arange(0, x.shape[0]), x) |
67 | 146 | # Y = interp1d(np.arange(0, y.shape[0]), y) |
... | ... | @@ -73,14 +152,14 @@ class Polygon_mass: |
73 | 152 | # level = (mx-mn)/5.5 |
74 | 153 | # cn = plt.contour(x, y, D, levels = [level]) |
75 | 154 | |
76 | - for e in self.G.edges(): | |
77 | - coord = self.G.vertex_properties["pos"][e.source()] | |
78 | - coord2 = self.G.vertex_properties["pos"][e.target()] | |
79 | - X = [coord[0], coord2[0]] | |
80 | - Y = [coord[1], coord2[1]] | |
81 | - #all_plots.plot(x, y, 'go--', linewidth=1, markersize=1) | |
82 | - plt.plot(X, Y, 'go--', linewidth=1, markersize=1) | |
83 | - | |
155 | +# for e in self.G.edges(): | |
156 | +# coord = self.G.vertex_properties["pos"][e.source()] | |
157 | +# coord2 = self.G.vertex_properties["pos"][e.target()] | |
158 | +# X = [coord[0], coord2[0]] | |
159 | +# Y = [coord[1], coord2[1]] | |
160 | +# #all_plots.plot(x, y, 'go--', linewidth=1, markersize=1) | |
161 | +# plt.plot(X, Y, 'go--', linewidth=1, markersize=1) | |
162 | +# | |
84 | 163 | plt.plot(*self.polygon.exterior.xy, color = 'r') |
85 | 164 | plt.show() |
86 | 165 | |
... | ... | @@ -211,8 +290,33 @@ class Polygon_mass: |
211 | 290 | C_x = (1.0 / (6.0 * A)) * C_x |
212 | 291 | C_y = (1.0 / (6.0 * A)) * C_y |
213 | 292 | |
214 | - return np.array([C_x, C_y]) | |
215 | - | |
293 | + return np.array([C_x, C_y]) | |
294 | + | |
295 | +#Graph G | |
296 | +#List of Polygonmass objects with the same cluster index. | |
297 | +def get_torques(G, masses): | |
298 | + for i in masses: | |
299 | + i.clear_torques() | |
300 | + for e in G.edges(): | |
301 | + #if the source and target cluster is not equal to each other | |
302 | + #add an inter subgraph edge. | |
303 | + if(G.vertex_properties["clusters"][e.source()] != G.vertex_properties["clusters"][e.target()]): | |
304 | + pf0 = G.vertex_properties["pos"][e.target()].get_2D_array(range(2)) | |
305 | + pf1 = G.vertex_properties["pos"][e.source()].get_2D_array(range(2)) | |
306 | + | |
307 | + t0 = G.vertex_properties["clusters"][e.source()] | |
308 | + t1 = G.vertex_properties["clusters"][e.target()] | |
309 | + | |
310 | + v0_index = G.vertex_properties["idx"][e.source()] | |
311 | + v1_index = G.vertex_properties["idx"][e.target()] | |
312 | + | |
313 | + p0 = masses[t0].G.vertex_properties["pos"][masses[t0].G.vertex(v0_index)].get_2D_array(range(2)) | |
314 | + p1 = masses[t1].G.vertex_properties["pos"][masses[t1].G.vertex(v1_index)].get_2D_array(range(2)) | |
315 | + | |
316 | + f0 = pf0-p1 | |
317 | + f1 = pf1-p0 | |
318 | + masses[t0].add_torque(p0, f0) | |
319 | + masses[t1].add_torque(p1, f1) | |
216 | 320 | |
217 | 321 | |
218 | 322 | def voronoi_polygons(voronoi, diameter): |
... | ... | @@ -517,15 +621,19 @@ def gen_image(G, G_c, itr, bb_flag = False, bb = None, reposition = False): |
517 | 621 | no_links.plot(x, y, 'go--', linewidth=1, markersize=1) |
518 | 622 | voronoi.plot(x, y, 'go--', linewidth=1, markersize=1) |
519 | 623 | |
520 | - #for every subgraph generate a layout and plot the result | |
624 | + #for every subgraph generate a layout and plot the resulting Polygon_mass | |
625 | + masses = [] | |
521 | 626 | for i in range(num_clusters): |
522 | 627 | g, center = gen_subclusters(G, G_c, i, reposition) |
523 | 628 | d = G_c.vertex_properties["pos"][i] - center |
524 | 629 | t = Polygon_mass(g) |
630 | + masses.append(g) | |
525 | 631 | #t.distancefield() |
526 | 632 | for v in g.vertices(): |
527 | 633 | G.vertex_properties["pos"][g.vertex_properties["idx"][v]] = g.vertex_properties["pos"][v] + d |
528 | - #g.vertex_properties["pos"][g.vertex_properties["idx"][v]] = g.vertex_properties["pos"][v] + d | |
634 | + | |
635 | + | |
636 | + #g.vertex_properties["pos"][g.vertex_properties["idx"][v]] = g.vertex_properties["pos"][v] + d | |
529 | 637 | #sub_pts = g.vertex_properties["pos"].get_2d_array(range(2)).T |
530 | 638 | #all_plots.scatter(pts[:,0], pts[:, 1], marker="*") |
531 | 639 | # for e in g.edges(): | ... | ... |