def __init__(self, mass: float, inertia: float, radius: float, vertices: int): self.mass = mass self.inertia = inertia self.position = vec.Vector(0,0,0) self.velocity = vec.Vector(0,0,0) self.radius = radius self.angle = 0 self.angular = 0 self.locateVertices(vertices, radius)
def get_intersection(self, line): v1 = vector.Vector(-self.vector.b, self.vector.a) v2 = vector.Vector(-line.vector.b, line.vector.a) d = v1.a * v2.b - v1.b * v2.a if abs(d) <= 0.0005: return None else: t = ((v2.b * (line.origin.x - self.origin.x)) - (v2.a * (line.origin.y - self.origin.y))) / d u = ((v1.b * (line.origin.x - self.origin.x)) - (v1.a * (line.origin.y - self.origin.y))) / d point1 = self.get_point(t) point2 = line.get_point(u) intersection = point1.equidistant(point2) return intersection
def findCollision(self, other: 'Polygon') -> vec.Vector: data = {'distance': sys.float_info.max, 'vertex': vec.Vector(0,0,0), 'edge': vec.Vector(0,0,0)} for i in range(0, len(self.vertices)): start = self.getVertex(i) end = self.getVertex((i+1) % len(self.vertices)) edge = end - start for j in range(0, len(other.vertices)): vertex = other.getVertex(j) distance = self.getDistance(vertex, start, end) if(distance < data['distance']): data = {'distance': distance, 'vertex': vertex, 'edge': edge} return data
def onBorderCollision(self, bottom: float, top: float, left: float, right: float): for i in range(len(self.vertices)): if self.getVertex(i).y < bottom and self.velocity.y < 0: self.calsu(self.getVertex(i), vec.Vector(0, 1, 0)) break if self.getVertex(i).y > top and self.velocity.y > 0: self.calsu(self.getVertex(i), vec.Vector(0, -1, 0)) break for i in range(len(self.vertices)): if self.getVertex(i).x < left and self.velocity.x < 0: self.calsu(self.getVertex(i), vec.Vector(1, 0, 0)) break if self.getVertex(i).x > right and self.velocity.x > 0: self.calsu(self.getVertex(i), vec.Vector(-1, 0, 0)) break
def calsu(self, contact: vec.Vector, normal: vec.Vector): #distance from center of mass to the collision contact rP = contact - self.position #vertex velocity before the collision velocity = self.velocity + (vec.Vector(0, 0, self.angular).cross(rP)) e = 0.8 #maybe this could be parameter impulse = -(e + 1) * (velocity.dot(normal) / ( 1/self.mass + (rP.cross(normal).magnitude()**2)/self.inertia )) self.velocity += normal.scale(impulse/self.mass) self.angular += rP.cross(normal).scale(impulse/self.inertia).z
def getDistance(self, point: vec.Vector, start: vec.Vector, end: vec.Vector) -> float: edge = end - start a = point - start b = edge.normalize() #FORMULA: a1 = (a dot b)b projection = b.scale(a.dot(b)) #FORMULA: a2 = a - a1 rejection = a - projection #the projection is to opposite direction than the edge, hypotenuse of projection and rejection is the distance if projection.dot(b) < 0: return vec.Vector(projection.magnitude(), rejection.magnitude(), 0).magnitude() #the projection is to the same direction but longer than the edge, hypotenuse of projection - edge and rejection is the distance if projection.magnitude() > edge.magnitude(): return vec.Vector(projection.magnitude() - edge.magnitude(), rejection.magnitude(), 0).magnitude() #projection is to the same direction and does not exceed edge, rejection is the distance return rejection.magnitude()
def update(self, deltaTime: float, gravity: float): #the polygon is on the ground so it will not accelerate downwards if self.position.y - self.radius > 0: self.velocity += vec.Vector(0, -gravity * deltaTime, 0) #subtract drag from the velocity self.velocity -= self.velocity.scale(0.005 * self.velocity.magnitude()) self.position += self.velocity.scale(deltaTime) self.angle += self.angular * deltaTime
def onCollision(self, other: 'Polygon') -> vec.Vector: data = self.findCollision(other) alternative = other.findCollision(self) if alternative['distance'] < data['distance']: data = alternative contact = data['vertex'] normal = self.getNormal(data['edge']) rA = contact - self.position rB = contact - other.position VAB = self.velocity + (vec.Vector(0, 0, self.angular).cross(rA)) - (other.velocity + (vec.Vector(0, 0, other.angular).cross(rB))) e = 0.8 #maybe this could be parameter impulse = -(e + 1) * (VAB.dot(normal) / ( 1/self.mass + (rA.cross(normal).magnitude()**2)/self.inertia + 1/other.mass + (rB.cross(normal).magnitude()**2)/other.inertia)) self.velocity += normal.scale(impulse/self.mass) self.angular += impulse/self.inertia * rA.cross(normal).z other.velocity -= normal.scale(impulse/other.mass) other.angular -= impulse/other.inertia * rB.cross(normal).z return contact
def getNormal(self, edge: vec.Vector) -> vec.Vector: normal = vec.Vector(-edge.y, edge.x, 0).normalize() if edge.cross(normal).z > 0: return normal.scale(-1.0) return normal
def locateVertices(self, count: int, radius: float): self.vertices = [] angle = 2.0 * math.pi / count for i in range(0, count): self.vertices.append(vec.Vector(0, radius, 0).rotate(angle * i))
def __init__(self, rho, theta): self.vector = vector.Vector(np.cos(theta), np.sin(theta)) self.origin = point.Point(self.vector.a * rho, self.vector.b * rho)
def get_points(self): line1, line2 = self.lines[0], self.lines[1] start_point = line1.get_intersection(line2) self.points.append(start_point) best_frame = self.determine_best_frame(start_point, [255, 255, 255]) self.reader.set(cv2.CAP_PROP_POS_FRAMES, best_frame) size = [ self.reader.get(cv2.CAP_PROP_FRAME_HEIGHT), self.reader.get(cv2.CAP_PROP_FRAME_WIDTH) ] ret, frame = self.reader.read() if ret: hls = cv2.cvtColor(frame, cv2.COLOR_BGR2HLS) for work_line in self.lines: threshold = 0 working_vector = vector.Vector(-work_line.vector.b, work_line.vector.a) if working_vector.orientation( ) == 1 or working_vector.orientation() == 2: working_vector = -working_vector working_point = start_point * (working_vector * 10) working_pixel = [int(working_point.y), int(working_point.x)] while threshold < 50: next_point = working_point * (working_vector * 2) next_pixel = [int(next_point.y), int(next_point.x)] if 0 < next_pixel[0] < size[0] and 0 < next_pixel[ 1] < size[1]: threshold = abs( int(hls[next_pixel[0], next_pixel[1]][0]) - int(hls[working_pixel[0], working_pixel[1]][0])) working_point, working_pixel = next_point, next_pixel else: threshold = 10000000 if not threshold == 10000000: self.points.append(working_point) else: working_point = start_point * (working_vector * 200) threshold, distance = 0, 0 if working_vector.orientation() == 0: normal_vector = vector.Vector(working_vector.b, -working_vector.a) elif working_vector.orientation() == 3: normal_vector = vector.Vector(-working_vector.b, working_vector.a) else: distance = 10000000 while distance < 30: normal_point = working_point normal_pixel = [ int(normal_point.y), int(normal_point.x) ] if 0 < normal_pixel[0] < size[0] and 0 < normal_pixel[ 1] < size[1]: working_frame = frame[normal_pixel[0], normal_pixel[1]] threshold = 0 while threshold < 50: next_point = normal_point * normal_vector next_pixel = [ int(next_point.y), int(next_point.x) ] if 0 < next_pixel[0] < size[ 0] and 0 < next_pixel[1] < size[1]: next_frame = frame[next_pixel[0], next_pixel[1]] threshold = np.mean( abs( next_frame.astype(int) - working_frame.astype(int))) normal_point = next_point else: threshold = 10000000 if threshold != 10000000: distance = working_point.distance(normal_point) working_point *= (working_vector * 2) else: distance = 10000000 if distance > 100: distance = 0 if threshold != 10000000 and distance != 10000000: self.points.append(working_point) if len(self.points) == 3: vector_1 = point.vectorize(self.points[0], self.points[1]) vector_2 = point.vectorize(self.points[0], self.points[2]) point_1 = self.points[1] * vector_2 point_2 = self.points[2] * vector_1 last_point = point_1.equidistant(point_2) self.points.append(last_point)
def vectorize(point1, point2): return vector.Vector(point2.x - point1.x, point2.y - point1.y)
# -*- coding: utf-8 -*- """ Created on Sat May 20 10:56:27 2017 @author: spiovesan """ import math import lib.vector as v if False: my_v11 = v.Vector([8.218, -9.341]) my_v12 = v.Vector([-1.129, 2.111]) my_v21 = v.Vector([7.119, 8.215]) my_v22 = v.Vector([-8.223, 0.878]) my_v31 = v.Vector([1.671, -1.012, -0.318]) print(my_v11.coordinates) t = tuple(map(lambda x, y: x + y, my_v11.coordinates, my_v12.coordinates)) t = tuple(map(lambda x, y: x - y, my_v11.coordinates, my_v12.coordinates)) print(t) print(my_v11 + my_v12) print(my_v21 - my_v22) print(my_v31 * 7.41) my_v34 = v.Vector([3, 4]) print(math.sqrt(sum(i**2 for i in my_v34.coordinates))) my_v32 = v.Vector([-0.221, 7.437]) print(my_v32.mag()) my_v33 = v.Vector([5.581, -2.136]) print(my_v33.norm())
#!/usr/bin/env python3 import lib.vector as vec import lib.polygon as pol from matplotlib import pyplot from matplotlib import animation #creating polygons polygons = [] polygons.append(pol.Polygon(1, 2, 1, 5)) polygons[0].position = vec.Vector(2,5,0) polygons[0].velocity = vec.Vector(20,0,0) polygons[0].angle = 4 polygons.append(pol.Polygon(1, 2, 1, 4)) polygons[1].position = vec.Vector(8,5,0) polygons.append(pol.Polygon(1, 2, 1, 6)) polygons[2].position = vec.Vector(4,2,0) polygons[2].velocity = vec.Vector(20,20,0) polygons.append(pol.Polygon(1, 2, 1, 4)) polygons[3].position = vec.Vector(2,2,0) polygons[3].velocity = vec.Vector(20,20,0) polygons.append(pol.Polygon(1, 2, 1, 7)) polygons[4].position = vec.Vector(1,2,0) polygons[4].velocity = vec.Vector(20,20,0) #figure settings fig = pyplot.figure()