def plot_edges(self, r=None, seq=False, j=0, shift=np.array([1000, 1000, 0, 0]), scale=500): """ Plots all the edges of the hypercube. """ if r is None: r = rotation(self.dim) im = Image.new("RGB", (2048, 2048), (1, 1, 1)) draw = ImageDraw.Draw(im, 'RGBA') if seq: self.generate_sequential_edges() edges = self.sequential_edges else: edges = self.edges for edge in edges: [v1, v2] = [ np.dot(r, edge.vertice1.binary), np.dot(r, edge.vertice2.binary) ] [v1x, v1y] = (shift[:self.dim] + scale * v1)[0:2] [v2x, v2y] = (shift[:self.dim] + scale * v2)[0:2] draw.line((v1x, v1y, v2x, v2y), fill=(255, 165, 0), width=2) return [im, draw]
def get_planes(self): """ Returns the planes corresponding to all the faces of a Dodecahedron. Edges based on Cartesian coordinates section here: https://en.wikipedia.org/wiki/Regular_dodecahedron """ phi = (1+np.sqrt(5)) / 2 tet_orig = [] for i in [-1,1]: for j in [-1,1]: for k in [-1,1]: tet_orig.append(np.array([i,j,k])) for i in [-1,1]: for j in [-1,1]: tet_orig.append(np.array([0,i*phi,j/phi])) tet_orig.append(np.array([i/phi,0,j*phi])) tet_orig.append(np.array([i*phi,j/phi,0])) tet_orig = np.array(tet_orig) r = rotation(3,np.pi/20.0) faces = [] for pm1 in [-1,1]: coeff1 = np.array([1, pm1 * phi, 0]) for i1 in range(3): for pm2 in [-1,1]: coeff = np.array([coeff1[ (i1+jj)%3] for jj in range(3)]) penta = np.array([i for i in tet_orig if (np.dot(i, coeff ) + pm2*phi*phi == 0)]) #Rotate the pentagon slightly so that it's visible from the front. #TODO: Need to rotate only when convex hull throws error. penta_r = np.dot(penta,r) penta_r_2d = [i[:2] for i in penta_r] hull = ConvexHull(penta_r_2d).vertices poly = np.array([penta[i] for i in hull]) #Does the cross product point outside? poly = orient_face(poly) faces.append(poly) return np.array(faces)
def plane_w_arrows(im_ind=0, scale=200, shift=np.array([824, 824, 0]), basepath=".\\"): r1 = np.eye(4) rot = general_rotation(np.array([0, 0, 1]), np.pi / 20.0 * (8 + im_ind / 3.0)) j = 4 r = rotation(3, 2 * np.pi * j / 30.0) rr = general_rotation(np.array([0, 1, 0]), np.pi / 20.0 * (im_ind / 7.0)) r = np.dot(r, rr) r = np.dot(r, rot) r1[:3, :3] = r im = Image.new("RGB", (1648, 1648), "black") draw = ImageDraw.Draw(im, "RGBA") pt1 = 3 * np.array([1.0, -1.0, 0]) pt2 = 3 * np.array([1.0, 1.0, 0]) z = 1.2**2 + 1 pt3 = 3 * np.array([-1.0, 1.0, 0]) pt4 = 3 * np.array([-1.0, -1.0, 0]) pt1 = np.dot(r, pt1) * scale + shift pt2 = np.dot(r, pt2) * scale + shift pt3 = np.dot(r, pt3) * scale + shift pt4 = np.dot(r, pt4) * scale + shift draw.polygon( [(pt1[0], pt1[1]), (pt2[0], pt2[1]), (pt3[0], pt3[1]), (pt4[0], pt4[1])], (0, 102, 255, 50), ) draw_arrows(draw, r, rgba=(255, 250, 47), shift=shift) draw_arrows(draw, r, rot_angl=np.pi / 2.0, rgba=(73, 200, 250), shift=shift) draw_arrows(draw, r, rot_angl=np.pi / 2.0 + np.pi / 3, rgba=(255, 20, 147), shift=shift) arrowV1( draw, r, np.array([0, 0, 0]), np.array([0, 0, 2.5]), shift=shift, rgb=(20, 200, 25), ) arrowV1( draw, r, np.array([0, 0, 0]), np.array([0, 0, -2.5]), shift=shift, rgb=(255, 20, 25), ) im.save(basepath + "im" + str(im_ind) + ".png")
def draw_planes(): for j in range(31): im = Image.new("RGB", (2048, 2048), (1, 1, 1)) draw = ImageDraw.Draw(im, 'RGBA') r = rotation(3, np.pi / 30 * j) #r = general_rotation(np.array([0.0,0.0,1.0]),2*np.pi*j/30) render_solid_planes(planes, draw, r, cut_back_face=True, scale=200) im.save(basedir + "im" + str(j) + ".png") im.close()
def draw_pts(): for j in range(30): im = Image.new("RGB", (2048, 2048), (1,1,1)) draw = ImageDraw.Draw(im,'RGBA') r = rotation(3,np.pi/30*j) p1 = np.dot(r,p) p1 = p1*200+1000.0 for i in range(p1.shape[1]): v = p1[:,i] draw.ellipse((v[0]-5, v[1]-5, v[0]+5, v[1]+5),fill=colors[i], outline=colors[i]) im.save(basedir + "im" + str(j) + ".png")
def paraboloid_w_grad(im_ind=0, scale=200, shift=np.array([1000, 1000, 0]), opacity=60, basepath=".\\"): r1 = np.eye(4) rot = general_rotation(np.array([0, 0, 1]), np.pi / 20.0 * (8 + im_ind / 3.0)) j = 4 r = rotation(3, 2 * np.pi * j / 30.0) rr = general_rotation(np.array([0, 1, 0]), np.pi / 20.0 * (im_ind / 7.0)) r = np.dot(r, rr) r = np.dot(r, rot) r1[:3, :3] = r im = Image.new("RGB", (2048, 2048), "black") draw = ImageDraw.Draw(im, "RGBA") render_scene_4d_axis(draw, r1, 4, scale, shift) # This is what draws the pink paraboloid. for z in np.arange(0.001, 3.5, 0.02): point1 = np.array([np.sqrt(z), 0, z]) generalized_arc( draw, r, center=np.array([0, 0, z]), vec=np.array([0, 0, 1]), point=point1, radius=np.sqrt(z), prcnt=1.0, rgba=(255, 20, 147, 50), ) xax1 = np.array([-100.0, 0, 0.0]) xax1 = np.dot(r, xax1) * scale + shift xax2 = np.array([100.0, 0, 0.0]) xax2 = np.dot(r, xax2) * scale + shift draw.line((xax1[0], xax1[1], xax2[0], xax2[1]), fill=(255, 255, 0), width=4) xax1 = np.array([0.0, -100, 0.0]) xax1 = np.dot(r, xax1) * scale + shift xax2 = np.array([0.0, 100, 0.0]) xax2 = np.dot(r, xax2) * scale + shift draw.line((xax1[0], xax1[1], xax2[0], xax2[1]), fill=(255, 255, 0), width=4) # gradients(draw,r) pt = shift draw.ellipse((pt[0] - 10, pt[1] - 10, pt[0] + 10, pt[1] + 10), fill=(0, 255, 0)) draw_paraboloid_plane(draw, r, 3.3) draw_paraboloid_plane(draw, r, 2.0, extent=1.4) draw_paraboloid_plane(draw, r, 1.0, extent=1.0) im.save(basepath + "im" + str(im_ind) + ".png")
def draw_cube(): c = Cube(3) verts = np.array([i.binary for i in c.vertices])-np.array([.5,.5,.5]) hull = ConvexHull(verts) simps = hull.simplices planes = np.array([[verts[j] for j in i] for i in simps]) for i in range(20): im = Image.new("RGB", (2048, 2048), (1,1,1)) draw = ImageDraw.Draw(im,'RGBA') r = np.transpose(rotation(3,np.pi*(9+i)/15)) #i=9 planes = [orient_face(pl) for pl in planes] render_solid_planes(planes, draw, r) im.save(".\\im" + str(i) + ".png")
def draw_tetartoid(basedir=".\\"): """ @MoneyShot Draws out a Tetartoid. args: basedir:The directory where the images are to be saved. In the main pyray repo, basedir is ..\\images\\RotatingCube\\ """ for i in range(0, 31): im = Image.new("RGB", (2048, 2048), (1, 1, 1)) draw = ImageDraw.Draw(im, 'RGBA') r = np.transpose(rotation(3, np.pi * (9 + i) / 15)) #i=9 tetartoid(draw, r, t=0.1) im.save(basedir + "im" + str(i) + ".png")
def platonic_solids(basedir=".\\"): """ @MoneyShot Draws out an Icosahedron and Dodecahedron. args: basedir:The directory where the images are to be saved. In the main pyray repo, basedir is ..\\images\\RotatingCube\\ """ for i in range(0, 31): im = Image.new("RGB", (2048, 2048), (1, 1, 1)) draw = ImageDraw.Draw(im, 'RGBA') r = np.transpose(rotation(3, np.pi * (9 + i) / 15)) #i=9 #dodecahedron(draw, r, shift = np.array([370, 1270, 0]), scale = 150) #icosahedron(draw, r, shift = np.array([1470, 1270, 0]), scale = 150) tetartoid(draw, r, t=0.1) im.save(basedir + "im" + str(i) + ".png")
def plot_faces(self, r=None, j=0, body_indice=None): """ Plots all the 2d faces of the hypercube. """ if r is None: r = rotation(self.dim) im = Image.new("RGB", (2048, 2048), "black") draw = ImageDraw.Draw(im, 'RGBA') for f in self.faces: f.plot(r, draw, (255, 55, 0, 22)) for edge in self.edges: edge.plot(r, draw, (255, 131, 0)) if body_indice is not None: indx = 0 for bi in body_indice: j = j + bi * 10**indx + 1 body = self.bodies[bi] body.plot(r, draw, colors[bi]) indx = indx + 1 im.save('Images\\RotatingCube\\im' + str(j) + '.png')
def plot_edges2(self, draw, r=None, seq=False, offset=None, fill=(255, 165, 5), scale=500, shift=np.array([1000, 1000, 0, 0])): """ Same as plot_edges, but allows for an offset. """ if offset is None: offset = np.zeros(self.dim) if r is None: r = rotation(self.dim) if seq: self.generate_sequential_edges() edges = self.sequential_edges else: edges = self.edges for edge in edges: if edge.vertice1.index == 0: [v1, v2] = [ np.dot(r, edge.vertice1.binary + offset), np.dot(r, edge.vertice2.binary + offset) ] elif edge.vertice2.index == 2**(self.dim) - 1: [v1, v2] = [ np.dot(r, edge.vertice1.binary - offset), np.dot(r, edge.vertice2.binary - offset) ] else: [v1, v2] = [ np.dot(r, edge.vertice1.binary), np.dot(r, edge.vertice2.binary) ] [v1x, v1y] = (shift[:self.dim] + scale * v1)[0:2] [v2x, v2y] = (shift[:self.dim] + scale * v2)[0:2] draw.line((v1x, v1y, v2x, v2y), fill=fill, width=4)
def tetartoid(draw, r, s=0.3, t=0.04, scale=500, shift=np.array([1000.0, 1000.0, 0])): ''' Draws a tetartoid. Based on the answer by Arentino here - https://math.stackexchange.com/questions/1393370/what-are-the-rules-for-a-tetartoid-pentagon args: s: 0 <= s <= 0.5. ''' tet_orig = np.array([[1, 1, 1], [-1, -1, 1], [1, -1, -1], [-1, 1, -1]]) # Make it a tetrahedron with unit edges. tet_orig = tet_orig / 2 / np.sqrt(2) r1 = rotation(3, np.pi / 10) tet_orig = np.dot(tet_orig, r1) v = np.dot(r, np.transpose(tet_orig)) * scale v = np.transpose(v) + shift[:3] # For each edge V_i V_j, construct two points P_ij and P_ji having a fixed distance s from V_i and V_j. p = np.zeros((4, 4, 3)) for i in range(4): for j in range(i + 1, 4): p[i, j] = (1 - s) * v[i] + s * v[j] p[j, i] = s * v[i] + (1 - s) * v[j] # Join the center C_ijk of every face V_i V_j V_k with P_ij, P_jk and P_ik. # First, let's just obtain the centers. c = np.zeros((4, 3)) for i in range(4): face = [f for f in range(4) if f != i] #TODO: Is there a better way to exclude indices? c[i] = sum(v[face]) / 3 # Now let o be the tetartoid center. o = shift # Consider the six planes o v_i v_j passing through the center and each edge. # From point p_ij, draw the perpendicular line to o v_i v_j and take on it # a point q_ij such that p_ij q_ij = t. q = np.zeros((4, 4, 3)) for i in range(4): for j in range(i + 1, 4): directn = np.cross(v[i] - o, v[j] - o) directn = directn / np.sqrt(sum(directn**2)) q[i, j] = p[i, j] + directn * t * scale q[j, i] = p[j, i] - directn * t * scale planes = [[c[3], q[2, 0], q[0, 2], v[0], q[0, 1]], [c[3], q[1, 2], q[2, 1], v[2], q[2, 0]], [c[3], q[0, 1], q[1, 0], v[1], q[1, 2]], [c[1], q[0, 2], q[2, 0], v[2], q[2, 3]], [c[1], q[2, 3], q[3, 2], v[3], q[3, 0]], [c[1], q[3, 0], q[0, 3], v[0], q[0, 2]], [c[2], q[1, 0], q[0, 1], v[0], q[0, 3]], [c[2], q[3, 1], q[1, 3], v[1], q[1, 0]], [c[2], q[0, 3], q[3, 0], v[3], q[3, 1]], [c[0], q[2, 1], q[1, 2], v[1], q[1, 3]], [c[0], q[1, 3], q[3, 1], v[3], q[3, 2]], [c[0], q[3, 2], q[2, 3], v[2], q[2, 1]]] planes = np.array(planes) for plane in planes: is_outwards = plane[0][2] > o[2] cprime = line_plane_intersection(o, plane[0], plane[1], plane[2], plane[4]) vprime = line_plane_intersection(o, plane[3], plane[1], plane[2], plane[4]) plane[0] = cprime plane[3] = vprime smat = sum(plane - o) cross_pdt = np.cross(plane[0] - plane[1], plane[0] - plane[2]) cross_pdt = cross_pdt / np.sqrt(sum(cross_pdt**2)) face_angle = np.dot(cross_pdt, np.array([0, 0.01, 0.99])) if not np.isnan(face_angle) and face_angle > 0: rgba = colorFromAngle2(face_angle, h=153, s=120, maxx=1.0) poly = [(i[0], i[1]) for i in plane] draw.polygon(poly, fill=rgba)
def best_plane_direction(j=19.5, im_ind=0, scale=250, shift=np.array([1200,580,0]), draw1=None): font = ImageFont.truetype("arial.ttf", 75) # For the axes. [a,b,c] = np.array([2.5, 2.5, -2.5]) * 410 / 200 ## Rotation matrices. r = rotation(3, 2 * np.pi*j/30.0) r1 = np.eye(4) r1[:3,:3] = r ## Image objects. if draw1 is None: im = Image.new("RGB", (2048, 2048), "black") draw = ImageDraw.Draw(im, 'RGBA') else: draw = draw1 ## Create the axes. render_scene_4d_axis(draw, r1, 4, scale = scale, shift = shift) pt1 = np.dot(r,np.array([a,0,0])) * scale + shift[:3] pt2 = np.dot(r,np.array([0,b,0])) * scale + shift[:3] pt3 = np.dot(r,np.array([0,0,c])) * scale + shift[:3] ## The point where this plane extends. pt4 = np.dot(r,np.array([a,b,-c])) * scale + shift[:3] draw.line((pt1[0],pt1[1],pt2[0],pt2[1]), fill=(200,80,100), width = 3) draw.line((pt1[0],pt1[1],pt2[0],pt2[1]), fill='orange', width = 3) draw.polygon([(pt1[0],pt1[1]),(pt3[0],pt3[1]),(pt2[0],pt2[1])], (200,80,100,100)) draw.polygon([(pt1[0],pt1[1]),(pt4[0],pt4[1]),(pt2[0],pt2[1])], (200,80,100,120)) draw.line((shift[0],shift[1],pt3[0],pt3[1]), fill = "yellow", width=7) draw.line((shift[0],shift[1],pt1[0],pt1[1]), fill = "yellow", width=7) draw.line((shift[0],shift[1],pt2[0],pt2[1]), fill = "yellow", width=7) ## Draw the x-y grid. drawXYGrid(draw, r, 1.25, scale = scale, shift = shift) ## We start at 45 degrees and trace a circular arc from there. pt_1 = np.array([a/2.0, b/2.0, 0]) arxExt = int(180*im_ind/10.0) draw_circle_x_y(draw=draw, r = r, center=pt_1[:2], radius=1, start = np.array([1/np.sqrt(2), 1/np.sqrt(2), 0]), arcExtent = arxExt, scale = scale, shift=shift) project_circle_on_plane(draw=draw, r = r, center=pt_1[:2], radius=1, plane = np.array([a,b,c]), start = np.array([1/np.sqrt(2), 1/np.sqrt(2), 0]), arcExtent=arxExt, scale = scale, shift = shift) ## Draw a point right at the center of the orange line. pt = np.dot(r, pt_1)*scale + shift[:3] width = 10 draw.ellipse((pt[0]-width,pt[1]-width,pt[0]+width,pt[1]+width),fill=(102,255,51)) # We start at 45 degrees and trace a circular arc from there. theta = np.arctan(a/b) + np.pi*im_ind/10.0 pt_2 = pt_1 + 1.0 * np.array([np.cos(theta), np.sin(theta), 0]) arrowV1(draw, r, pt_1, pt_2, scale = scale, shift = shift) ## Draw a pink triangle with vertices: head of arrow, tail of arrow, projection on plane. arrow_w_projection(im, draw, r, pt_1, pt_2, plane = np.array([a,b,c])) ## If you didn't provide the draw object, we will save the image. if draw1 is None: im.save('.\\im' + str(im_ind) + '.png')
#im.save(basedir + "im" + str(i) + ".png") for i in range(31): im = Image.new("RGB", (2048, 2048), (1, 1, 1)) draw = ImageDraw.Draw(im, 'RGBA') r = general_rotation(np.array([0.5, 0.5, 0.5]), 2 * np.pi * i / 30) render_solid_planes(faces, draw, r, scale=150) im.save(basedir + "im" + str(i) + ".png") ############################################################################# ## Scene c - teserract that is shaded. basedir = '..\\images\\RotatingCube\\' cu = Cube(4) for i in range(0, 31): r = rotation(4, 2 * np.pi * i / 30) faces = [ orient_face( np.dot(j.face_matrix - np.array([.5, .5, .5, .5]), r)[[0, 1, 3, 2]][:, :-1]) for j in cu.faces ] im = Image.new("RGB", (2048, 2048), (1, 1, 1)) draw = ImageDraw.Draw(im, 'RGBA') render_solid_planes(faces, draw, np.eye(3), scale=350) im.save(basedir + "im" + str(i) + ".png") ############################################################################# ## Scene d - Quadrilateral flap rotating about hinge. basedir = '..\\images\\RotatingCube\\' a = np.random.uniform(size=2) b = np.random.uniform(size=2)
import numpy as np from PIL import Image, ImageDraw, ImageFont, ImageMath import os from pyray.shapes.twod.paraboloid import * from pyray.shapes.twod.functional import * from pyray.rotation import * ############################### ## Warped spacetime grid for black hole. im_ind=0; scale=200; shift=np.array([1000,1000,0]) r1 = np.eye(4) rot = general_rotation(np.array([0,0,1]), np.pi/20.0 * (8 + im_ind/3.0)) j=4 r = rotation(3, 2 * np.pi * j /30.0) rr = general_rotation(np.array([0,1,0]), np.pi/20.0 * (im_ind/7.0)) r = np.dot(r, rr) r = np.dot(r, rot) r1[:3, :3] = r im = Image.new("RGB", (2048, 2048), "black") draw = ImageDraw.Draw(im, 'RGBA') render_scene_4d_axis(draw, r1, 4, scale, shift) t=0.1 ix=0 z1 = -0.000001 while abs(z1) < 1/t: ix += 1 z1 -= 0.0001*ix**1.1 z = z1
def teserract_body_diagonal2(im_ind=70, width=15, scale=500, shift1=np.array([1000, 1000, 0, 0, 0]), move=0.0): ''' @MoneyShot Draws a four dimensional teserract with two tetrahedral and one octahedral planes visible. ''' c1 = Cube(4) r = np.eye(4) r[:3, :3] = rotation(3, np.pi * 2 * (27.0 - im_ind) / 80.0) newr = general_rotation(np.array( [1, -1, 0]), (np.pi / 2 + np.arccos(np.sqrt(0.666666))) * 4.35 / 10.0) oldr = rotation(3, np.pi * 2 * (27.0) / 80.0) r[:3, :3] = oldr im = Image.new("RGB", (2048, 2048), (1, 1, 1)) draw = ImageDraw.Draw(im, 'RGBA') rotated_vertices = np.transpose(np.dot(r, np.transpose( c1.vertice_matrix))) * scale + shift1[:4] body_diag = (c1.vertices[0].to_binary() - c1.vertices[15].to_binary()) frst = [1, 2, 4] scnd = [3, 5, 6] for e in c1.edges: if e.vertice1.index == 0 and e.vertice2.index in frst: pt1 = rotated_vertices[e.vertice1.index] pt2 = rotated_vertices[e.vertice2.index] center = (pt1 + pt2) / 2.0 p = im_ind / 10.0 pp1 = (1 - p) * pt1 + p * pt2 p = p + 0.08 pp2 = (1 - p) * pt1 + p * pt2 draw.line((pp1[0], pp1[1], pp2[0], pp2[1]), fill=(200, 220, 5), width=10) tri = [] for j in frst: tri.append((rotated_vertices[j][0], rotated_vertices[j][1])) sqr1 = rotated_vertices[[ i.index for i in c1.vertices[c1.vertice_coordinate_sums == 3] ]] + (rotated_vertices[0] - rotated_vertices[15]) * -move sqr1_orig = rotated_vertices[[ i.index for i in c1.vertices[c1.vertice_coordinate_sums == 3] ]] draw.polygon(jarvis_convex_hull(sqr1), (255, 0, 0, int(65))) i = 0 a = list(range(4)) a.pop(i) tri = [] tri_orig = [] for j in a: tri.append((sqr1[j][0], sqr1[j][1])) tri_orig.append((sqr1_orig[j][0], sqr1_orig[j][1])) for ver in c1.vertices[c1.vertice_coordinate_sums == 3]: ver.plot(r, draw, (255, 0, 0), 10, offset=-body_diag * move, scale=scale, shift=shift1) for ver1 in c1.vertices[c1.vertice_coordinate_sums == 3]: e = Edge(ver, ver1) e.plot(r, draw, (255, 0, 0), width=2, offset=-body_diag * move, scale=scale, shift=shift1) hexag = rotated_vertices[[ i.index for i in c1.vertices[c1.vertice_coordinate_sums == 2] ]] for ed in [(5, 3), (5, 6), (5, 9), (5, 12), (10, 3), (10, 6), (10, 9), (10, 12), (3, 6), (3, 9), (12, 6), (12, 9)]: v1 = rotated_vertices[ed[0]] v2 = rotated_vertices[ed[1]] draw.line((v1[0], v1[1], v2[0], v2[1]), fill=(0, 255, 0), width=4) #draw.line((v1[0], v1[1], v2[0], v2[1]), fill = (255-im_ind*10,165+im_ind,0), width=4) for ver in c1.vertices[c1.vertice_coordinate_sums == 2]: ver.plot(r, draw, (0, 255, 0), 10, scale=scale, shift=shift1) #ver.plot(r, draw, (255-im_ind*25,im_ind*25,0), 10, scale=scale1, shift=shift1) draw.polygon(jarvis_convex_hull(hexag), (0, 255, 0, int(65))) for ver in c1.vertices[c1.vertice_coordinate_sums == 1]: #ver.plot(r, draw, (0,0,255), 10, offset = body_diag * move) ver.plot(r, draw, (255, 0, 0), 10, offset=body_diag * move, scale=scale, shift=shift1) #ver.plot(r, draw, (0,0,255), 10) for ver1 in c1.vertices[c1.vertice_coordinate_sums == 1]: e = Edge(ver, ver1) e.plot(r, draw, (0, 0, 255), offset=body_diag * move, scale=scale, shift=shift1) #e.plot(r,draw,(255-im_ind*16,165-im_ind*13,im_ind*25), offset = body_diag * move,scale=scale1, shift=shift1) sqr2 = rotated_vertices[[ i.index for i in c1.vertices[c1.vertice_coordinate_sums == 1] ]] + (rotated_vertices[0] - rotated_vertices[15]) * move sqr2_orig = rotated_vertices[[ i.index for i in c1.vertices[c1.vertice_coordinate_sums == 1] ]] draw.polygon(jarvis_convex_hull(sqr2), (0, 0, 255, int(65))) i = 3 a = list(range(4)) a.pop(i) tri = [] tri_orig = [] for j in a: tri.append((sqr2[j][0], sqr2[j][1])) tri_orig.append((sqr2_orig[j][0], sqr2_orig[j][1])) v1 = rotated_vertices[0] v2 = rotated_vertices[15] im.save('Images\\RotatingCube\\im' + str(im_ind) + '.png')
def teserract_body_diagonal(width=15, im_ind=70, scale=500, shift=np.array([1000, 1000, 0, 0, 0]), basepath='.\\'): """ @MoneyShot basepath in main repo: images\\RotatingCube\\ Draws a four dimensional teserract with two tetrahedral and one octahedral planes visible. """ c1 = Cube(4) r = np.eye(4) r[:3, :3] = rotation(3, np.pi * 2 * 27 / 80.0) r1 = rotation(4, np.pi * 2 * im_ind / 80.0) r = np.dot(r, r1) [im, draw] = c1.plot_edges2(r) rotated_vertices = np.transpose(np.dot(r, np.transpose( c1.vertice_matrix))) * scale + shift[:4] hexag = rotated_vertices[[ i.index for i in c1.vertices[c1.vertice_coordinate_sums == 2] ]] sqr1 = rotated_vertices[[ i.index for i in c1.vertices[c1.vertice_coordinate_sums == 3] ]] try: draw.polygon(jarvis_convex_hull(sqr1), (255, 0, 0, 60)) except: print("err") for ver in c1.vertices[c1.vertice_coordinate_sums == 3]: ver.plot(r, draw, (255, 0, 0), 10) for ver1 in c1.vertices[c1.vertice_coordinate_sums == 3]: e = Edge(ver, ver1) e.plot(r, draw, (255, 0, 0), width=2) try: draw.polygon(jarvis_convex_hull(hexag), (0, 255, 0, 30)) except: print("err") for ver in c1.vertices[c1.vertice_coordinate_sums == 1]: ver.plot(r, draw, (0, 0, 255), 10) for ver1 in c1.vertices[c1.vertice_coordinate_sums == 1]: e = Edge(ver, ver1) e.plot(r, draw, (0, 0, 255)) for ed in [(5, 3), (5, 6), (5, 9), (5, 12), (10, 3), (10, 6), (10, 9), (10, 12), (3, 6), (3, 9), (12, 6), (12, 9)]: v1 = rotated_vertices[ed[0]] v2 = rotated_vertices[ed[1]] draw.line((v1[0], v1[1], v2[0], v2[1]), fill=(0, 255, 0), width=4) for ver in c1.vertices[c1.vertice_coordinate_sums == 2]: ver.plot(r, draw, (0, 255, 0), 10) sqr2 = rotated_vertices[[ i.index for i in c1.vertices[c1.vertice_coordinate_sums == 1] ]] try: draw.polygon(jarvis_convex_hull(sqr2), (0, 0, 255, 60)) except: print("err") v1 = rotated_vertices[0] v2 = rotated_vertices[15] draw.line((v1[0], v1[1], v2[0], v2[1]), fill=(255, 255, 255), width=2) im.save(basepath + 'im' + str(im_ind) + '.png')
def cube_with_cuttingplanes(numTerms, im_ind=0, pos=[300, 700, 0], draw1=None, scale=100, popup=False, baseLocn='.\\im'): """ @MoneyShot Generates larger and larger cubes showing their cutting planes representing polynomial terms. args: numTerms: The number of values each dimension can take. im_ind: The index of the image in the video (will affect file name of dumped image). pos: The position on the image where the leftmost edge of the cube should be. draw1: The draw object of the image. If not provided, new images are created. """ for j in range(30, 31): if draw1 is None: im = Image.new("RGB", (2048, 2048), "black") draw = ImageDraw.Draw(im, 'RGBA') else: draw = draw1 r = rotation(3, j / 80.0 * np.pi * 2) # Vertices vertices = [general_base(i, numTerms, 3) for i in range(numTerms**3)] rotated_vertices = ( np.transpose(np.dot(r, np.transpose(vertices))) * scale + pos) # Draw edges. for i in range(len(vertices)): for dim in range(3): if (vertices[i][dim] < (numTerms - 1) and i + numTerms**dim <= len(vertices) - 1): v1 = rotated_vertices[i] v2 = rotated_vertices[i + numTerms**dim] draw.line((v1[0], v1[1], v2[0], v2[1]), fill="yellow", width=2) for v in rotated_vertices: draw.ellipse((v[0] - 5, v[1] - 5, v[0] + 5, v[1] + 5), fill='red', outline='red') for power in range(1, (numTerms - 1) * 3): rgb = colors[(power - 1) % 14] rgba = colors[(power - 1) % 14] + (100, ) sqr1 = rotated_vertices[np.array(range(len(vertices)))[np.array( [sum(i) == power for i in vertices])]] hull = ConvexHull([i[:2] for i in sqr1]).vertices poly = [(sqr1[i][0], sqr1[i][1]) for i in hull] draw.polygon(poly, rgba) for vv in sqr1: [vx, vy] = vv[:2] draw.ellipse((vx - 11, vy - 11, vx + 11, vy + 11), fill=rgb, outline=rgb) if draw1 is None: if popup: im.show() im.save(baseLocn + str(im_ind) + '.png')
## Paraboloid with Lagrange visualized. im = Image.new("RGB", (2048, 2048), (1, 1, 1)) draw = ImageDraw.Draw(im, "RGBA") scale = 5.0 ind = 0 sep = 24 i = 2.0 base_coeff = 0.02 start_line = -12.0 shift = np.array([1000.0, 1000.0, 0.0]) r1 = np.eye(4) j = 24 r = rotation(3, np.pi / 30 * j) r1[:3, :3] = r render_scene_4d_axis(draw, r1, 4) fn = lambda x, y: paraboloid(x, y, coeff=i * base_coeff, intercept=i) drawFunctionalXYGrid( draw, r, scale=scale, fn=fn, extent=60, rgba2=(255, 20, 147, 80), saperatingPlane=np.array([-1, -1, sep]), )
from pyray.axes import * from pyray.color import * from pyray.geometric import * from pyray.misc import * from pyray.rotation import * from pyray.shapes.solid.cube import * width = 15 im_ind = 70 scale = 500 shift = np.array([1000, 1000, 0, 0, 0]) basepath = ".\\Images\\" c1 = Cube(4) r = np.eye(4) r[:3, :3] = rotation(3, np.pi * 2 * 27 / 80.0) r1 = rotation(4, np.pi * 2 * im_ind / 80.0) r = np.dot(r, r1) [im, draw] = c1.plot_edges(r, shift=shift, scale=scale) rotated_vertices = ( np.transpose(np.dot(r, np.transpose(c1.vertice_matrix))) * scale + shift[:4]) hexag = rotated_vertices[[ i.index for i in c1.vertices[c1.vertice_coordinate_sums == 2] ]] sqr1 = rotated_vertices[[ i.index for i in c1.vertices[c1.vertice_coordinate_sums == 3] ]] sqr2 = np.delete(sqr1, -1, axis=1)