gen_cube3d.py 4.69 KB
 Jayant Khatkar committed Mar 19, 2020 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 ``````#!/usr/bin/env python3 from sympy import * from gcode2contour import Position, contour from sympy.plotting import plot3d from mpl_toolkits.mplot3d import Axes3D import matplotlib.colors as mcolors import matplotlib.pyplot as plt import numpy as np def set_aspect_equal_3d(ax): """Fix equal aspect bug for 3D plots.""" xlim = ax.get_xlim3d() ylim = ax.get_ylim3d() zlim = ax.get_zlim3d() from numpy import mean xmean = mean(xlim) ymean = mean(ylim) zmean = mean(zlim) plot_radius = max([abs(lim - mean_) for lims, mean_ in ((xlim, xmean), (ylim, ymean), (zlim, zmean)) for lim in lims]) ax.set_xlim3d([xmean - plot_radius, xmean + plot_radius]) ax.set_ylim3d([ymean - plot_radius, ymean + plot_radius]) ax.set_zlim3d([zmean - plot_radius, zmean + plot_radius]) def plot_contours(*args): """ Plots a list of contours Each input arguement is a list of contours All contours within each list will be the same color Contours in different lists will be different colors """ fig = plt.figure() ax = Axes3D(fig) # colors = [k for k in mcolors.cnames] colors = ['blue', 'red', 'green'] for i, contours in enumerate(args): for c in contours: xs = [pos[0] for pos in c.pos] ys = [pos[1] for pos in c.pos] zs = [pos[2] for pos in c.pos] ax.plot(xs, ys, zs, color=colors[i]) set_aspect_equal_3d(ax) plt.show() return class solver: """ Handles symbolic variables to solve for layer positions in various planes """ def __init__(self, cl, cx, cy, dz): self.x, self.y, self.z, self.cz = symbols('x y z cz') self.layer = cl * sin(cx*self.x)*sin(cy*self.y) + self.cz self.dz = dz self.def_prism() def get_z(self, x, y, layer=0): return float(self.layer.subs([(self.x, x), (self.y, y), (self.cz, layer*self.dz)])) def def_prism(self, x_min = -0.05, x_max = 0.05, y_min = -0.05, y_max = 0.05, z_min = 0., z_max = 0.1): """ save the prism size """ self.range = { self.x: (x_min, x_max), self.y: (y_min, y_max), self.z: (z_min, z_max), } def plane_intersection(self, sym, val, layer = 0): """ Takes a plane (not any plane, only x,y or z=val) and interesects it with the nth layer Returns symbolic expression for the intersection. Need to sample """ return self.layer.subs([(sym, val), (self.cz, layer*self.dz)]) def sample(self, expression, sym_in, res = 0.001): """ sample across one variable, get values of second variable in an expression """ v1 = np.arange(self.range[sym_in][0], self.range[sym_in][1]+ res, res) zs = [] for v in v1: zs.append(float(expression.subs(sym_in, v))) return v1, zs def contour_n(self, n): """ Get 4 contours for the nth layer 4 sides of the prism unlinked """ contours = [] expr1 = self.plane_intersection(self.x, self.range[self.x][0], layer = n) ys, zs = self.sample(expr1, self.y) contours.append(contour([Position(self.range[self.x][0],ys[i],zs[i]) for i in range(len(ys))], 0)) expr2 = self.plane_intersection(self.x, self.range[self.x][1], layer = n) ys, zs = self.sample(expr2, self.y) contours.append(contour([Position(self.range[self.x][1],ys[i],zs[i]) for i in range(len(ys))], 0)) expr3 = self.plane_intersection(self.y, self.range[self.y][0], layer = n) xs, zs = self.sample(expr3, self.x) contours.append(contour([Position(xs[i],self.range[self.y][0],zs[i]) for i in range(len(ys))], 0)) expr4 = self.plane_intersection(self.y, self.range[self.y][1], layer = n) xs, zs = self.sample(expr4, self.x) contours.append(contour([Position(xs[i],self.range[self.y][1],zs[i]) for i in range(len(ys))], 0)) # TODO Join the 4 contours into one # TODO break up contours at z limits return contours def show(self): """ Show the surface of the layer in the range of the cube at layer 0 """ plot3d(self.layer.subs(self.cz, 0), (self.x, self.range[self.x][0], self.range[self.x][1]), (self.y, self.range[self.y][0], self.range[self.y][1])) if __name__ == '__main__': s = solver(0.02, 100, 100, 0.01) contours = [] for i in range(10): contours += s.contour_n(i) plot_contours(contours)``````