def solve_collision(self, b1, b2): # Changes the direction of non-static moving bodies, and separates overlapping bodies def penetration(normal, movable_body, fixed_body): if normal.x < -0.0001: return abs(movable_body.rect.right() - fixed_body.rect.left()) elif normal.x > 0.0001: return abs(fixed_body.rect.right() - movable_body.rect.left()) if normal.y < -0.0001: return abs(fixed_body.rect.top() - movable_body.rect.bottom()) else: return abs(movable_body.rect.top() - fixed_body.rect.bottom()) if b1.is_static and not (b2.is_static): normal = self.calculate_normal(b2, b1) pen_distance = penetration(normal, b2, b1) b2.rect.position = vector.sum(b2.rect.position, vector.mul(normal, pen_distance)) b2.direction = vector.reflect(normal, b2.direction) return normal elif not (b1.is_static) and b2.is_static: normal = self.calculate_normal(b1, b2) pen_distance = penetration(normal, b1, b2) b1.rect.position = vector.sum(b1.rect.position, vector.mul(normal, pen_distance)) b1.direction = vector.reflect(normal, b1.direction) return normal elif not (b1.is_static) and not (b2.is_static): normal = self.calculate_normal(b1, b2) normal_inv = vector.minus(normal) pen_distance = penetration(normal, b1, b2) b1.rect.set_pos(vector.sum(b1.rect.position, vector.mul(normal, 0.5 * pen_distance))) b1.direction = vector.reflect(normal, b1.direction) b2.rect.position = vector.sum(b2.rect.position, vector.mul(normal_inv, 0.5 * pen_distance)) b2.direction = vector.reflect(normal_inv, b2.get_direction()) return normal
def boundarycompute(self): try: return self.boundary except: if self[0].str2[6:9] != 'GLY': atoms = self.findatoms([" N "," C "," CA "," O "," OT1", " CB "]) else: atoms = self.findatoms([" N "," C "," CA "," O "," OT1", " HA2"]) atoms.remove(0) posterm = vector.Nlocation(atoms[1].coords(),atoms[2].coords(),atoms[3].coords()) axis = vector.translate(vector.minus(atoms[0].coords()))(posterm) N1 = vector.unit(axis) length = vector.norm(axis) N2 = vector.unit(vector.translate(vector.minus(atoms[2].coords()))(atoms[4].coords())) self.boundary = [atoms[0].coords(), N1, N2, length] return self.boundary
def circleArcAroundPivot(pivot, start, end): pivotToStart = vector.translate(vector.minus(pivot))(start) pivotToEnd = vector.translate(vector.minus(pivot))(end) normalToPlane = vector.crossproduct(pivotToStart,pivotToEnd) firstRadialDirection = vector.crossproduct(normalToPlane, pivotToStart) planeCoefficients = pivotToEnd def dotByPlaneCoefficients(vec): output = 0 for i in range(0,3): output += planeCoefficients[i] * vec[i] return output t = (dotByPlaneCoefficients(end) - dotByPlaneCoefficients(start))/(dotByPlaneCoefficients(firstRadialDirection)) center = vector.translate(start)(vector.scale(firstRadialDirection,t)) return circleArc(center, start, end)
def circleArcAroundPivotClosestPieces(pivot, start, end, smoothingFactor): pivotToStart = vector.translate(vector.minus(pivot))(start) pivotToEnd = vector.translate(vector.minus(pivot))(end) smallerNorm = min(vector.norm(pivotToStart),vector.norm(pivotToEnd)) def findActualEndPoint(vec): unitVec = vector.unit(vec) return vector.translate(pivot)(vector.scale(vector.unit(vec),smallerNorm*smoothingFactor)) circularPart = circleArcAroundPivot(pivot,findActualEndPoint(pivotToStart),findActualEndPoint(pivotToEnd)) #FIX!! if smallerNorm == vector.norm(pivotToStart): output = circularPart if smallerNorm != vector.norm(pivotToEnd): output.attachPartial(1, cutSegment(pivot, end, smallerNorm * smoothingFactor / vector.norm(pivotToEnd), smoothingFactor)) else: output = cutSegment(start, pivot, 1 - smoothingFactor, 1 - smallerNorm * smoothingFactor / vector.norm(pivotToStart)) output.attachPartial(1, circularPart) return output
def d(t): currentPoint = Wmap.ev(0)[0] currentLocationOnRnew = Rnew.projectOntoAxis(currentPoint) for x in pointsOnWmap: thisLocationOnRnew = Rnew.projectOntoAxis(x) if thisLocationOnRnew >= currentLocationOnRnew: if thisLocationOnRnew <= t: currentLocationOnRnew = thisLocationOnRnew currentPoint = x return vector.vectorToAngle(vector.unit(vector.translate(vector.minus(Rnew.ev(currentLocationOnRnew)[0]))(currentPoint)))
def detect_and_solve_collision(self): # Detect and resolve collisions. Then, call collision callback functions. for i in range(len(self.bodies) - 1): for j in range(i + 1, len(self.bodies)): if self.collide(self.bodies[i], self.bodies[j]): normal = self.solve_collision(self.bodies[i], self.bodies[j]) for c in self.list_call_backs: if self.bodies[i].object_type == c.tb1 and self.bodies[j].object_type == c.tb2: c.call_back(self.bodies[i], self.bodies[j], normal) elif self.bodies[j].object_type == c.tb1 and self.bodies[i].object_type == c.tb2: c.call_back(self.bodies[j], self.bodies[i], vector.minus(normal))
def circleArc(center, start, end): radToStart = vector.translate(vector.minus(center))(start) radToEnd = vector.translate(vector.minus(center))(end) radiusSquared = vector.norm(radToStart)*vector.norm(radToEnd) radius = math.sqrt(radiusSquared) innerProductValue = vector.innerproduct(radToStart, radToEnd) angle = math.acos(innerProductValue/radiusSquared) firstUnitRadial = vector.unit(radToStart) secondUnitRadial = vector.unit(vector.translate(vector.scale(radToStart,-innerProductValue/radiusSquared))(radToEnd)) def CN(t): point = vector.translate(center)(vector.translate(vector.scale(firstUnitRadial,radius*math.cos(t/radius)))(vector.scale(secondUnitRadial,radius*math.sin(t/radius)))) tangent = vector.translate(vector.scale(firstUnitRadial,-math.sin(t/radius)))(vector.scale(secondUnitRadial,math.cos(t/radius))) output = [point,tangent] #output.append([math.cos(t/radius),math.sin(t/radius),0]) return output return TwistingAxis(angle*radius,CN)
def boundarycompute(self): try: return self.boundary except: if self[0].str2[6:9] != 'GLY': atoms = self.findatoms( [" N ", " C ", " CA ", " O ", " OT1", " CB "]) else: atoms = self.findatoms( [" N ", " C ", " CA ", " O ", " OT1", " HA2"]) atoms.remove(0) posterm = vector.Nlocation(atoms[1].coords(), atoms[2].coords(), atoms[3].coords()) axis = vector.translate(vector.minus(atoms[0].coords()))(posterm) N1 = vector.unit(axis) length = vector.norm(axis) N2 = vector.unit( vector.translate(vector.minus(atoms[2].coords()))( atoms[4].coords())) self.boundary = [atoms[0].coords(), N1, N2, length] return self.boundary
def smoothedPieceWiseLinearFullFunctionality(points, mapFromSpaceToTime, Wnew, smoothingFactor = 0.33): if len(points) < 2: print("Error: only " + str(len(points)) + " points supplied to smoothedPieceWiseLinear") return currentPoints = copy.deepcopy(points) numPoints = len(currentPoints) attachElements = [cutSegment(points[0],points[1],0,smoothingFactor)] for i in range(0,numPoints - 2): lastToPivot = vector.translate(vector.minus(points[i]))(points[i+1]) pivotToNext = vector.translate(vector.minus(points[i+1]))(points[i+2]) angle = vector.innerproduct(lastToPivot, pivotToNext)/(vector.norm(lastToPivot)*vector.norm(pivotToNext)) collinear = (abs(angle) < 0.001) if collinear: attachElements.append(cutSegment(points[i],points[i+1],smoothingFactor,1)) attachElements.append(cutSegment(points[i+1],points[i+2],1,smoothingFactor)) else: attachElements.append(cutSegment(points[i],points[i+1],smoothingFactor,1-smoothingFactor)) attachElements.append(circleArcAroundPivotClosestPieces(points[i+1],points[i],points[i+2],smoothingFactor)) attachElements.append(cutSegment(points[-2],points[-1],smoothingFactor,1)) def iteratedAttach(start, end): if start < end: midpoint = (start + end)/2 iteratedAttach(start, midpoint) iteratedAttach(midpoint + 1, end) attachElements[start].attachPartial(1, attachElements[midpoint + 1]) iteratedAttach(0, len(attachElements)-1) Wmap = attachElements[0] produceN2 = lambda x : vector.unit(vector.orthogonalComponent(vector.translate(vector.minus(Wnew.ev(mapFromSpaceToTime(x[0]))[0]))(x[0]),x[1])) appendN2 = lambda x: [x[0],x[1],produceN2(x)] Wmap.CN = compose(appendN2,Wmap.CN) return [Wmap, Wnew, lambda t: mapFromSpaceToTime(Wmap.ev(t)[0])]
def segment(start, end): startToEnd = vector.translate(vector.minus(start))(end) distance = vector.norm(startToEnd) try: tng = vector.unit(startToEnd) def CN(t): output = [vector.translate(start)(vector.scale(tng,t)),tng] #output.append(normal) return output except: def CN(t): output = [start, [0,0,0]] return TwistingAxis(distance, CN)
def dist(self, b, a=0): """ Returns list with distribution of numbers between a to b, """ """ by number of bits in binary representation """ """ (optionally filtered by primality of sum of 1 bits). """ if (b < a or b < 0 or a < 0): raise Exception result = [] prev_bits = 0 if a > 0: #TODO : optimizable by removing common bits return vector.minus(self.dist(b), self.dist(a - 1)) else: bl = bit.list(b) l = len(bl) for i, bt in zip(range(l, 0, -1), bl) + [(1, 1)]: if bt: additional = vector.shift(self.dist_get_cache(i - 1), prev_bits) if self.prefilter: additional = self.primes.prime_mask(additional) result = vector.add(result, additional) prev_bits += 1 return result
def testMinus(self): self.assertEqual(vector.minus( [5, 7, 9], [4, 5, 6] ), [1, 2, 3] ) self.assertEqual(vector.minus( [5, 7, 9], [1, 2] ), [4, 5, 9] ) self.assertEqual(vector.minus( [1, 2], [5, 7, 9] ), [-4, -5, -9] )
import GF2 # version code ef5291f09f60+ coursera = 1 # Please fill out this stencil and submit using the provided submission script. # Some of the GF2 problems require use of the value GF2.one so the stencil imports it. from GF2 import one ## 1: (Problem 1) Vector Addition Practice 1 #Please express each answer as a list of numbers p1_v = [-1, 3] p1_u = [0, 4] p1_v_plus_u = vector.add(p1_v, p1_u) p1_v_minus_u = vector.minus(p1_v, p1_u) p1_three_v_minus_two_u = vector.minus(vector.scalar_mult(3, p1_v), vector.scalar_mult(2, p1_u)) ## 2: (Problem 2) Vector Addition Practice 2 p2_u = [-1, 1, 1] p2_v = [ 2, -1, 5] p2_v_plus_u = vector.add(p2_v, p2_u) p2_v_minus_u = vector.minus(p2_v, p2_u) p2_two_v_minus_u = vector.minus(vector.scalar_mult(2, p2_v), p2_u) p2_v_plus_two_u = vector.add(p2_v, vector.scalar_mult(2, p2_u)) ## 3: (Problem 3) Vector Addition Practice 3 p3_v = [GF2.zero, GF2.one, GF2.one] p3_u = [GF2.one, GF2.one, GF2.one] p3_vector_sum_1 = vector.add(p3_v, p3_u) p3_vector_sum_2 = vector.add(p3_v, p3_u, p3_u)
def cutSegment(start, end, startScale, endScale): segStart = vector.translate(start)(vector.scale(vector.translate(vector.minus(start))(end),startScale)) segEnd = vector.translate(start)(vector.scale(vector.translate(vector.minus(start))(end),endScale)) return segment(segStart, segEnd)
def reverseOrbs(self): temp = self.ev() temp[1] = vector.minus(temp[1]) #temp[2] = vector.minus(temp[2]) self.CN = lambda x: temp