def get_polygon_edgematrix(center_x, center_y, radius, sides): """ Generates an EdgeMatrix of lines representing a regular polygon centered at the given points inscribed within a circle of the given radius. Parameters: center_x: int, the x coordinate of the center of the polygon center_y: int, the y coordinate of the center of the polygon radius: int, the radius of the circle sides: int, the number of sides in the polygon """ def x(t): return cos(t) * radius + center_x def y(t): return sin(t) * radius + center_y def z(t): return 0 parametric = Parametric(x, y, z) edgematrix = EdgeMatrix() step_range = Generator.get_step_range(0, 2 * pi, sides) for i in range(len(step_range) - 1): edgematrix.add_edge(parametric.get_point(step_range[i]), parametric.get_point(step_range[i + 1])) return edgematrix
def get_bezier_curve_edgematrix(p1, i1, i2, p2, step=30): """ Generates an EdgeMatrix of lines representing a bezier curve. Parameters: p1: list, the first endpoint of the bezier curve i1: list, the first influence point of the bezier curve i2: list, the second influence point of the bezier curve p2: list, the second endpoint of the bezier curve step: int (optional), the number of steps to use when drawing splines for the hermite curve """ def x(t): return Generator.get_bezier_function(p1[0], i1[0], i2[0], p2[0])(t) def y(t): return Generator.get_bezier_function(p1[1], i1[1], i2[1], p2[1])(t) def z(t): return 0 parametric = Parametric(x, y, z) edgematrix = EdgeMatrix() step_range = Generator.get_step_range(0, 1, step) for i in range(len(step_range) - 1): edgematrix.add_edge(parametric.get_point(step_range[i]), parametric.get_point(step_range[i + 1])) return edgematrix
def get_torus_pointmatrix(center_x, center_y, center_z, radius1, radius2, theta_step=30, phi_step=30): """ Generates a Matrix of points representing the points on the surface of a torus. Parameters: center_x: int, the x coordinate of the center of the sphere center_y: int, the y coordinate of the center of the sphere center_z: int, the z coordinate of the center of the sphere radius1: int, the radius of the circle being revolved to make the torus radius2: int, the radius of the torus itself theta_step: int (optional), the number of steps to use when drawing the circle that is revolved to make the torus phi_step: int(optional), the number of steps to use when rotating the circles about the center point """ def x(theta, phi): return radius1 * cos(theta) + center_x def y(theta, phi): return cos(phi) * ( radius1 * sin(theta) + radius2) + center_y def z(theta, phi): return sin(phi) * ( radius1 * sin(theta) + radius2) + center_z parametric = Parametric(x, y, z) matrix = Matrix() theta_step_range = Generator.get_step_range(0, 2 * pi, theta_step) phi_step_range = Generator.get_step_range(0, 2 * pi, phi_step) for i in theta_step_range: for j in phi_step_range: matrix += Matrix([parametric.get_point(i, j)]) return matrix
def get_hermite_curve_edgematrix(p1, r1, p2, r2, step=30): """ Generates an EdgeMatrix of lines representing a hermite curve. Parameters: p1: list, the first point of the hermite curve r1: list, the rate of change at p1 p2: list, the second point of the hermite curve r2: list, the rate of change at p2 step: int (optional), the number of steps to use when drawing splines for the hermite curve """ points = Matrix(matrix=[p1, p2, r1, r2]) inverse = Matrix([[2, -2, 1, 1], [-3, 3, -2, -1], [0, 0, 1, 0], [1, 0, 0, 0]]) c = inverse * points def x(t): return Generator.get_hermite_function(c[0][0], c[1][0], c[2][0], c[3][0])(t) def y(t): return Generator.get_hermite_function(c[0][1], c[1][1], c[2][1], c[3][1])(t) def z(t): return 0 parametric = Parametric(x, y, z) edgematrix = EdgeMatrix() step_range = Generator.get_step_range(0, 1, step) for i in range(len(step_range) - 1): edgematrix.add_edge(parametric.get_point(step_range[i]), parametric.get_point(step_range[i + 1])) return edgematrix
def get_sphere_pointmatrix(center_x, center_y, center_z, radius, theta_step=30, phi_step=30): """ Generates a Matrix of points representing the points on the surface of a sphere. Parameters: center_x: int, the x coordinate of the center of the sphere center_y: int, the y coordinate of the center of the sphere center_z: int, the z coordinate of the center of the sphere radius: int, the radius of the sphere theta_step: int (optional), the number of steps to use when drawing the circles phi_step: int(optional), the number of steps to use when rotating the circles about the center point """ def x(theta, phi): return radius * cos(theta) + center_x def y(theta, phi): return radius * sin(theta) * cos(phi) + center_y def z(theta, phi): return radius * sin(theta) * sin(phi) + center_z parametric = Parametric(x, y, z) matrix = Matrix() theta_step_range = Generator.get_step_range(0, 2 * pi, theta_step) phi_step_range = Generator.get_step_range(0, pi, phi_step) for i in theta_step_range: for j in phi_step_range: matrix += Matrix([parametric.get_point(i, j)]) return matrix
def get_hermite_curve_edgematrix(p1, r1, p2, r2, step=30): """ Generates an EdgeMatrix of lines representing a hermite curve. Parameters: p1: list, the first point of the hermite curve r1: list, the rate of change at p1 p2: list, the second point of the hermite curve r2: list, the rate of change at p2 step: int (optional), the number of steps to use when drawing splines for the hermite curve """ points = Matrix(matrix=[p1, p2, r1, r2]) inverse = Matrix([ [2, -2, 1, 1], [-3, 3, -2, -1], [0, 0, 1, 0], [1, 0, 0, 0]]) c = inverse * points def x(t): return Generator.get_hermite_function( c[0][0], c[1][0], c[2][0], c[3][0])(t) def y(t): return Generator.get_hermite_function( c[0][1], c[1][1], c[2][1], c[3][1])(t) def z(t): return 0 parametric = Parametric(x, y, z) edgematrix = EdgeMatrix() step_range = Generator.get_step_range(0, 1, step) for i in range(len(step_range) - 1): edgematrix.add_edge(parametric.get_point(step_range[i]), parametric.get_point(step_range[i + 1])) return edgematrix
def processSolidCollision(self, servertime, othersolid): """Compute new state for object and another solid object following an elastic collision. Function will update the current state of both objects as a side effect. :param servertime: Current time on the server. :param othersolid: Reference to the other colliding object. """ self.updateCurrentState(servertime) othersolid.updateCurrentState(servertime) m1 = self.mass m2 = othersolid.mass P1 = Parametric(self.X, self.V) P2 = Parametric(othersolid.Xclosest, othersolid.V) # compute collision based on the instant the objects would have touched collisiontimes = P1.timeatdistance(P2, self.radius + othersolid.radius) if len(collisiontimes) > 0: tcollision = min(collisiontimes) self.updateCurrentState(servertime + tcollision) otheroldX = othersolid.X othersolid.updateCurrentState(servertime + tcollision) # tweak the Xclosest vector to match othersolid.Xclosest = othersolid.Xclosest + othersolid.X - otheroldX R = othersolid.Xclosest - self.X # construct unit vector normal to plane of collision R = R / linalg.norm(R) # scalar component of velocity normal to plane u1 = dot(self.V, R) # scalar component, other solid u2 = dot(othersolid.V, R) # new velocities after semi-elastic collision # see http://en.wikipedia.org/wiki/Inelastic_collision A = m1 * u1 + m2 * u2 B = m1 + m2 v1 = (CR * m2 * (u2 - u1) + A) / B v2 = (CR * m1 * (u1 - u2) + A) / B #v1 = (u1*(m1-m2)+2*m2*u2)/(m1+m2) #v2 = (u2*(m2-m1)+2*m1*u1)/(m1+m2) self.V = self.V + R * (v1 - u1) othersolid.V = othersolid.V + R * (v2 - u2) self.processCollisionDeltaV(v1 - u1) othersolid.processCollisionDeltaV(v2 - u2)
def get_torus_pointmatrix(center_x, center_y, center_z, radius1, radius2, theta_step=30, phi_step=30): """ Generates a Matrix of points representing the points on the surface of a torus. Parameters: center_x: int, the x coordinate of the center of the sphere center_y: int, the y coordinate of the center of the sphere center_z: int, the z coordinate of the center of the sphere radius1: int, the radius of the circle being revolved to make the torus radius2: int, the radius of the torus itself theta_step: int (optional), the number of steps to use when drawing the circle that is revolved to make the torus phi_step: int(optional), the number of steps to use when rotating the circles about the center point """ def x(theta, phi): return radius1 * cos(theta) + center_x def y(theta, phi): return cos(phi) * (radius1 * sin(theta) + radius2) + center_y def z(theta, phi): return sin(phi) * (radius1 * sin(theta) + radius2) + center_z parametric = Parametric(x, y, z) matrix = Matrix() theta_step_range = Generator.get_step_range(0, 2 * pi, theta_step) phi_step_range = Generator.get_step_range(0, 2 * pi, phi_step) for i in theta_step_range: for j in phi_step_range: matrix += Matrix([parametric.get_point(i, j)]) return matrix
def get_bezier_curve_edgematrix(p1, i1, i2, p2, step=30): """ Generates an EdgeMatrix of lines representing a bezier curve. Parameters: p1: list, the first endpoint of the bezier curve i1: list, the first influence point of the bezier curve i2: list, the second influence point of the bezier curve p2: list, the second endpoint of the bezier curve step: int (optional), the number of steps to use when drawing splines for the hermite curve """ def x(t): return Generator.get_bezier_function( p1[0], i1[0], i2[0], p2[0])(t) def y(t): return Generator.get_bezier_function( p1[1], i1[1], i2[1], p2[1])(t) def z(t): return 0 parametric = Parametric(x, y, z) edgematrix = EdgeMatrix() step_range = Generator.get_step_range(0, 1, step) for i in range(len(step_range) - 1): edgematrix.add_edge(parametric.get_point(step_range[i]), parametric.get_point(step_range[i + 1])) return edgematrix
def get_sphere_polygonmatrix(center_x, center_y, center_z, radius, theta_step=30, phi_step=30): """ Generates a PolygonMatrix representing the mesh surface of a sphere. Parameters: center_x: int, the x coordinate of the center of the sphere center_y: int, the y coordinate of the center of the sphere center_z: int, the z coordinate of the center of the sphere radius: int, the radius of the sphere theta_step: int (optional), the number of steps to use when drawing the circles phi_step: int(optional), the number of steps to use when rotating the circles about the center point """ def x(theta, phi): return radius * cos(theta) + center_x def y(theta, phi): return radius * sin(theta) * cos(phi) + center_y def z(theta, phi): return radius * sin(theta) * sin(phi) + center_z parametric = Parametric(x, y, z) matrix = PolygonMatrix() points = Generator.get_sphere_pointmatrix(center_x, center_y, center_z, radius, theta_step=theta_step, phi_step=phi_step) for i in range(len(points) - phi_step - 1): matrix.add_polygon(points[i], points[i + phi_step + 1], points[i + phi_step]) matrix.add_polygon(points[i], points[i + 1], points[i + phi_step + 1]) return matrix
def parse(src, p, color): l = Line(p, color) m = Matrix() t = Transformation() param = Parametric(m, .0001) f = Polygon(m) fxns = { 'line': lambda args: m.addEdge((args[0], args[1], args[2]), (args[3], args[4], args[5])), 'scale': lambda args: t.scale(args[0], args[1], args[2]), 'move': lambda args: t.move(args[0], args[1], args[2]), 'rotate': lambda args: t.rotate(args[0], args[1]), 'save': lambda args: save(l, m, args), 'circle': lambda args: param.arc((args[0], args[1], args[2]), args[3]), 'hermite': lambda args: param.hermite((args[0], args[1]), (args[2], args[3]), (args[4], args[5]), (args[6], args[7])), 'bezier': lambda args: param.bezier((args[0], args[1]), (args[2], args[3]), (args[4], args[5]), (args[6], args[7])), 'box': lambda args: f.box(args[:3], args[3:6]), 'sphere': lambda args: f.sphere(args[:3], args[3]), 'torus': lambda args: f.torus(args[:3], args[3], args[4]), } with open(src, "r") as raw: commands = raw.readlines() cmdbuf = '' for cmd in commands: if cmd == 'line\n': cmdbuf = 'line' elif cmd == 'ident\n': t = Transformation() cmdbuf = '' elif cmd == 'scale\n': cmdbuf = 'scale' elif cmd == 'move\n': cmdbuf = 'move' elif cmd == 'rotate\n': cmdbuf = 'rotate' elif cmd == 'apply\n': print('apply') t.apply(m) t = Transformation() cmdbuf = '' elif cmd == 'display\n': print('display') p.clear() l.draw(m) p.display() cmdbuf = '' elif cmd == 'save\n': cmdbuf = 'save' elif cmd == 'quit\n': break elif cmd == 'circle\n': cmdbuf = 'circle' elif cmd == 'hermite\n': cmdbuf = 'hermite' elif cmd == 'bezier\n': cmdbuf = 'bezier' elif cmd == 'clear\n': print('clear') m = Matrix() f.matrix = m cmdbuf = '' elif cmd == 'box\n': cmdbuf = 'box' elif cmd == 'sphere\n': cmdbuf = 'sphere' elif cmd == 'torus\n': cmdbuf = 'torus' elif cmd[0] == '#': pass else: args = cmd.split() fargs = list() for i in range(len(args)): try: fargs.append(float(args[i])) except ValueError: fargs.append(args[i]) print(cmdbuf + ': ' + ','.join(args)) fxns[cmdbuf](fargs) cmdbuf = ''