def draw (self, frame, **kwargs) : """ draw left and right max line @input: - frame @param: - color @output: - frame """ frame = frame.copy () lines = [] # first line min if self.min[1] is not None : lines.append (Line.from_two_points (self.min[1], self.vp1)) # then line max if self.max[1] is not None : lines.append (Line.from_two_points (self.max[1], self.vp1)) for l in lines : frame = l.draw (frame, **kwargs) return frame
def path1(self, r, h, stepOver, passes, direction=CW): r0 = stepOver # milling arc radius r1 = r0 / 3 # return radius a = degrees(pi / 2 + 2 * atan2(r0 - r1, r0)) x = -r y = 0 c0 = Point(x, y) path = [] if direction == CW: arc0 = Arc(c0, r0, 270, 90, direction=CW) for i in range(passes): path.append(arc0) c1 = Point(x, arc0.p1.y + r1) arc1 = Arc(c1, r1, a, 270, direction=CW) path.append(arc1) x += r0 c0 = Point(x, y) arc0 = Arc(c0, r0, 270, a, direction=CW) l = Line(arc1.p1, arc0.p0) path.append(l) else: a = 360 - a arc0 = Arc(c0, r0, 270, 90, direction=CCW) for i in range(passes): path.append(arc0) c1 = Point(x, arc0.p1.y - r1) arc1 = Arc(c1, r1, 90, a, direction=CCW) path.append(arc1) x += r0 c0 = Point(x, y) arc0 = Arc(c0, r0, a, 90, direction=CCW) l = Line(arc1.p1, arc0.p0) path.append(l) return path
def check_intersections(): cnt = 0 for i in range(len(crd) - 1): for j in range(i + 1, len(crd)): if (Vector(crd[i], crd[j]).len() < 1): cnt += 1 for i in range(len(bond_length) - 1): for j in bond_length[i]: for k in range(i + 1, len(bond_length)): for l in bond_length[k]: a1 = crd[i] a2 = crd[j[0]] b1 = crd[k] b2 = crd[l[0]] if a1 != b1 and a1 != b2 and a2 != b1 and a2 != b2: p = lines_intersection(Line(a1, a2), Line(b1, b2)) if not p is None and p.between(a1, a2) and p.between( b1, b2): cnt += 1 if p is None: cnt += t_search(a1, a2, b1, b2) return cnt
def fine_dewarp(im, lines): im_h, im_w = im.shape[:2] debug = cv2.cvtColor(im, cv2.COLOR_GRAY2BGR) points = [] y_offsets = [] for line in lines: if len(line) < 10 or abs(line.fit_line().angle()) > 0.001: continue line.fit_line().draw(debug, thickness=1) base_points = np.array([letter.base_point() for letter in line.inliers()]) median_y = np.median(base_points[:, 1]) y_offsets.append(median_y - base_points[:, 1]) points.append(base_points) for underline in line.underlines: mid_contour = (underline.top_contour() + underline.bottom_contour()) / 2 all_mid_points = np.stack([ underline.x + np.arange(underline.w), mid_contour, ]) mid_points = all_mid_points[:, ::4] points.append(mid_points) for p in base_points: pt = tuple(np.round(p).astype(int)) cv2.circle(debug, (pt[0], int(median_y)), 2, lib.RED, -1) cv2.circle(debug, pt, 2, lib.GREEN, -1) cv2.imwrite('points.png', debug) points = np.concatenate(points) y_offsets = np.concatenate(y_offsets) mesh = np.mgrid[:im_w, :im_h].astype(np.float32) xmesh, ymesh = mesh # y_offset_interp = interpolate.griddata(points, y_offsets, xmesh, ymesh, method='nearest') # y_offset_interp = y_offset_interp.clip(-5, 5) # mesh[1] += y_offset_interp # (mesh[0], mesh[1], grid=False) y_offset_interp = interpolate.SmoothBivariateSpline( points[:, 0], points[:, 1], y_offsets.clip(-3, 3), s=4 * points.shape[0] ) ymesh -= y_offset_interp(xmesh, ymesh, grid=False).clip(-3, 3) conv_xmesh, conv_ymesh = cv2.convertMaps(xmesh, ymesh, cv2.CV_16SC2) out = cv2.remap(im, conv_xmesh, conv_ymesh, interpolation=cv2.INTER_LINEAR, borderValue=np.median(im)).T cv2.imwrite('corrected.png', out) debug = cv2.cvtColor(out, cv2.COLOR_GRAY2BGR) for line in lines: base_points = np.array([letter.base_point() for letter in line.inliers()[1:-1]]) base_points[:, 1] -= y_offset_interp(base_points[:, 0], base_points[:, 1], grid=False) Line.fit(base_points).draw(debug, thickness=1) cv2.imwrite('corrected_line.png', debug) return out
def __init__(self, sensors=None, human=False): super().__init__() self.update = self.update_no_track #self.move = self.move_cor self.start_time = time.time() self.human = human # physical car parameters self.width = 10 self.length = 30 self.hwbase = self.length / 2 self.htrack = self.width / 2 self.max_speed = 150 self.rot = 0 self.speed = 0 self.max_steering = PI / 4 self.steering = 0 # for collision detection and box drawings self.quad = Quad(box=Box(-self.width/2, self.length/2, self.width, self.length)) self.corner_distance = Line(self.position, self.quad.top_left).length self.corner_angle = Line(self.position, self.quad.top_right).angle _ = self.corners # to set corner attributes # track info self.track = None self.section = None self.section_idx = -1 self.collided = False self.laps = 0 if not sensors: self.sensors = SensorRig(self, (-PI/2, -3 * self.corner_angle, -self.corner_angle, 0, self.corner_angle, 3 * self.corner_angle, PI/2), (30, 50, 100, 175, 100, 50, 30)) elif sensors == 1: self.sensors = SensorRig(self, (0,), (175,)) else: n = sensors // 2 * 2 + 1 angles = tuple(-PI/2 + i*PI/(n-1) for i in range(n)) distances = (100,) * n self.sensors = SensorRig(self, angles, distances) # neural network if cmodule: self.driver = neural.CDriver(1+self.sensors.size) else: self.driver = neural.Driver(1+self.sensors.size) # graphics stuff self.construct() self.section_batch = pyglet.graphics.Batch() self.section_batch_idx = -1
def path2(self, r, h, stepOver, passes, direction=CW): r0 = stepOver # milling arc radius r1 = r0 / 3 # return radius centerVDist = 2 * h - (r0 + r1) centerDist = sqrt(centerVDist * centerVDist + r0 * r0) a0 = atan2(centerVDist, r0) a1 = asin((r0 - r1) / centerDist) a = degrees(pi / 2 + a0 + a1) h0 = h - r0 path = [] x = -r y = 0 if direction == CW: c0 = Point(x, h0) arc0 = Arc(c0, r0, 0, 90, direction=CW) for i in range(passes): path.append(arc0) p0 = arc0.p1 l = Line(p0, Point(p0.x, -h0)) path.append(l) c1 = Point(x, -h0) l = Arc(c1, r0, 270, 0, direction=CW) path.append(l) c2 = Point(x, -h0 - r0 + r1) arc1 = Arc(c2, r1, a, 270, direction=CW) path.append(arc1) x += r0 c0 = Point(x, h0) arc0 = Arc(c0, r0, 0, a, direction=CW) l = Line(arc1.p1, arc0.p0) path.append(l) else: a = 360 - a c0 = Point(x, -h0) arc0 = Arc(c0, r0, 270, 0, direction=CCW) for i in range(passes): path.append(arc0) p0 = arc0.p1 l = Line(p0, Point(p0.x, h0)) path.append(l) c1 = Point(x, h0) l = Arc(c1, r0, 0, 90, direction=CCW) path.append(l) c2 = Point(x, h0 + r0 - r1) arc1 = Arc(c2, r1, 90, a, direction=CCW) path.append(arc1) x += r0 c0 = Point(x, -h0) arc0 = Arc(c0, r0, a, 0, direction=CCW) l = Line(arc1.p1, arc0.p0) path.append(l) return path
def test_contains_point(): l1 = Line.from_points(Point(1, 1, 1), Point(2, 2, 2)) assert l1.contains_point(Point(3, 3, 3)) assert l1.contains_point(Point(0, 0, 0)) assert not l1.contains_point(Point(2, 3, 4)) l2 = Line.from_points(Point(0, 0, 0), Point(2, 0, 0)) assert l2.contains_point(Point(4, 0, 0)) assert l2.contains_point(Point(-3, 0, 0)) assert not l2.contains_point(Point(0, 1, 0))
def car_hit_border(self, left=None, right=None, car=None): if not (left and right) and car: left = Line(car.top_left, car.bottom_left) right = Line(car.top_right, car.bottom_right) for border in [self.quad.left, self.quad.right]: if border.intersects(left): return "left" elif border.intersects(right): return "right" return False
def test_intersecting_lines(self): from geometry import Line from geometry import intersecting_lines import numpy as np l1 = Line([0, 1], [.5, .5]) l2 = Line([0, -1], [.5, -.5]) intersection = intersecting_lines([l1, l2]) np.testing.assert_almost_equal([-1, 0], intersection)
def test_orthogonal(): l1 = Line() # X-axis l2 = Line(direction_vector=Vector([0, 1, 0]), point=Point(0, 0, 0)) # Y-axis l3 = Line(direction_vector=Vector([1, 1, 0]), point=Point(0, 0, 0)) l4 = Line(direction_vector=Vector([0, 0, 1]), point=Point(0, 0, 0)) assert l1.is_orthogonal(l2) assert l3.is_orthogonal(l4) assert not l1.is_orthogonal(l3)
def full_lines(AH, lines, v): C0 = max(lines, key=lambda l: l.right() - l.left()) v_lefts = [ Line.from_points(v, l[0].left_bot()) for l in lines if l is not C0 ] v_rights = [ Line.from_points(v, l[-1].right_bot()) for l in lines if l is not C0 ] C0_lefts = [l.text_line_intersect(C0)[0] for l in v_lefts] C0_rights = [l.text_line_intersect(C0)[0] for l in v_rights] mask = np.logical_and(C0_lefts <= C0.left() + AH, C0_rights >= C0.right() - AH) return compress(lines, mask)
def test_gelernter_equidistance(): geometry.reset() init_canvas = sketch.Canvas() init_state = State() X = Point() l1, l2 = Line(), Line() hp11, hp12, hp21, hp22 = map(HalfPlane, 'hp11 hp12 hp21 hp22'.split()) init_state.add_relations( divides_halfplanes(l1, hp11, hp12) + divides_halfplanes(l2, hp21, hp22) + collinear(l1, X) + collinear(l2, X) + distinct(l1, l2) ) info = init_canvas.add_random_angle(X, l1, l2) init_state.add_spatial_relations(info) init_canvas.update_hps(init_state.line2hps) steps = [ 'angle_bisect: hp11 hp21', # l3 'free_p_on_l: l3', 'perp: P2 l1', 'perp: P2 l2', 'ASA:' ] state, canvas, action_chain = action_chain_lib.execute_steps( steps, init_state, init_canvas) prev_state = action_chain[-1].state proof_goals = list(whittling.extract_all_proof_goals(action_chain, state)) # Check if all the goals are here: name2goals = extract_name2goals(proof_goals, state, prev_state) all_target_goals = ['4.P1P3 == 4.P1P4', '4.P3P2 == 4.P4P2'] for goal in all_target_goals: assert goal in name2goals, goal state_queue, proof_queue = name2goals[goal] _, _, proof_steps = whittle( state, state_queue, proof_queue, action_chain, init_state, init_canvas, canvas, verbose=False) assert proof_steps == [4], proof_steps
def parse(dxf_file, segarc, new_origin=True): font = Font() DXF_source = " " dxf_import = DXF_CLASS() dxf_import.GET_DXF_DATA(dxf_file, tol_deg=segarc) dxfcoords = dxf_import.DXF_COORDS_GET(new_origin) if "POTRACE" in dxf_import.comment.upper(): DXF_source = "POTRACE" if "INKSCAPE" in dxf_import.comment.upper(): DXF_source = "INKSCAPE" # save the character to our dictionary key = ord("F") stroke_list = [] bbox = BoundingBox() for line in dxfcoords: line = Line(line[0:4]) stroke_list.append(line) bbox.extend(line) font.add_character(Character(key, stroke_list)) return font, DXF_source
def estimate_directrix(lines, v, n_points_w): vx, vy = v domain, C0, C1 = widest_domain(lines, v, N_POINTS) C0_points = np.vstack([domain, C0(domain)]) longitudes = [Line.from_points(v, p) for p in C0_points.T] C1_points = np.array([l.closest_poly_intersect(C1.model, p) \ for l, p in zip(longitudes, C0_points.T)]).T lambdas = (vy - C0_points[1]) / (C1_points[1] - C0_points[1]) alphas = MU * lambdas / (MU + lambdas - 1) C_points = (1 - alphas) * C0_points + alphas * C1_points C = C_points.T.mean(axis=0) theta = acos(f / sqrt(vx**2 + vy**2 + f**2)) print('theta:', theta) A = np.array([[1, C[0] / f * -sin(theta)], [0, cos(theta) - C[1] / f * sin(theta)]]) D_points = inv(A).dot(C_points) D_points_arc, _ = arc_length_points(D_points) C_points_arc = A.dot(D_points_arc) # plot_norm(np.vstack([domain, C0(domain)]).T, label='C0') # plot_norm(np.vstack([domain, C1(domain)]).T, label='C1') # plot_norm(C_points.T, label='C20') # plot_norm(D_points.T, label='D') # plot_norm(C_points_arc.T, label='C') # # plt.plot(C_points.T, label='C20') # # plt.plot(C_points_arc.T, label='C') # plt.axes().legend() # plt.show() return D_points_arc, C_points_arc
def generate_mesh(all_lines, lines, C_arc, v, n_points_h): vx, vy = v C_arc_T = C_arc.T C0, C1 = C0_C1(lines, v) # first, calculate necessary mu. global mu_debug mu_debug = cv2.cvtColor(bw, cv2.COLOR_GRAY2BGR) mu_bottom = necessary_mu(C0, C1, v, all_lines, MuMode.BOTTOM) mu_top = necessary_mu(C0, C1, v, all_lines, MuMode.TOP) lib.debug_imwrite('mu.png', mu_debug) longitude_lines = [Line.from_points(v, p) for p in C_arc_T] longitudes = [] mus = np.linspace(mu_top, mu_bottom, n_points_h) for l, C_i in zip(longitude_lines, C_arc_T): p0 = l.closest_poly_intersect(C0.model, C_i) p1 = l.closest_poly_intersect(C1.model, C_i) lam = (vy - p0[1]) / (p1[1] - p0[1]) alphas = mus * lam / (mus + lam - 1) longitudes.append(np.outer(1 - alphas, p0) + np.outer(alphas, p1)) result = np.array(longitudes) debug = cv2.cvtColor(bw, cv2.COLOR_GRAY2BGR) for l in result[::50]: for p in l[::50]: cv2.circle(debug, tuple(p.astype(int)), 6, BLUE, -1) trace_baseline(debug, C0, RED) trace_baseline(debug, C1, RED) lib.debug_imwrite('mesh.png', debug) return np.array(longitudes).transpose(1, 0, 2)
def create_guideline(self, p): self.guideline = Line(Point(p.x, self.rect.top), Point(p.x, self.rect.bottom), color=cs.YELLOW, w=3, dash=(4, 4)) self.guideline.screen_ref = self.create_line(self.guideline)
def force(self, p): l = Line(self.position, p.position) dist = l.length * 1000 * 10**6 direct = self.position - p.position F = G * self.weight * p.weight / dist**2 - K * self.elec * p.elec / dist**2 out = (F / dist) * direct return out
def generate_points(self): phi = (1 + np.sqrt(5)) / 2 x = np.array([1, 0, 0]) y = np.array([0, 1, 0]) z = np.array([0, 0, 1]) v1, v2 = (phi, 1 / phi, 0), (phi, -1 / phi, 0) vertex_pairs = [ (v1, v2), (x + y + z, v1), (x + y - z, v1), (x - y + z, v2), (x - y - z, v2), ] five_lines_points = Mobject(*[ Line(pair[0], pair[1], density=1.0 / self.epsilon) for pair in vertex_pairs ]).points #Rotate those 5 edges into all 30. for i in range(3): perm = map(lambda j: j % 3, range(i, i + 3)) for b in [-1, 1]: matrix = b * np.array([x[perm], y[perm], z[perm]]) self.add_points(np.dot(five_lines_points, matrix)) self.pose_at_angle() self.set_color(GREEN)
def update(self, delta): self.old_position = self.position displacement = (constants.BULLET_SPEED * delta / 1000.0) * self.vec self.total_distance += displacement.length() self.position = self.position.translate(displacement) self.travelled = Line(self.old_position, self.position) self.update_graphics()
def __init__(self, p, direction, owner, splash=False): super(Bullet, self).__init__() self.position = p self.direction = direction self.owner = owner self.splash = splash if not self.splash: self.original = pygame.Surface([constants.TILE_SIZE * constants.BULLET_WIDTH_RATIO, constants.TILE_SIZE * constants.BULLET_HEIGHT_RATIO], flags=pygame.SRCALPHA) self.original.fill(constants.BULLET_COLOR) else: size = int(round(constants.BULLET_WIDTH_RATIO * constants.TILE_SIZE)) self.original = pygame.Surface([size, size], flags=pygame.SRCALPHA) self.original.fill(constants.COLOR_TRANSPARENT) image_center = (self.original.get_width() / 2, self.original.get_height() / 2) pygame.draw.circle(self.original, constants.BULLET_COLOR, image_center, int(round(self.original.get_width() / 2))) self.old_position = self.position self.reset_vec() self.bounces = 0 self.total_distance = 0.0 self.dead = False self.travelled = Line(self.position, self.position) self.update_graphics()
def Upon_Click(button, button_state, cursor_x, cursor_y): global g_isDragging, g_LastRot, g_Transform, g_ThisRot global POLIEDRY, g_isFaceSelected, RAY, factor, angularSpeed if button_state == GLUT_DOWN: p_s1 = get_mouse_position_transform(cursor_x, cursor_y, 1.0) RAY = Line(Point(0.0, 0.0, 0.0), p_s1) if (g_isFaceSelected == False) and (button == GLUT_LEFT_BUTTON): if (POLIEDRY.face_intersect(RAY) != -1): POLIEDRY.face_select(POLIEDRY.last_face_clicked) g_isFaceSelected = True g_isDragging = False if (button == GLUT_RIGHT_BUTTON and button_state == GLUT_DOWN and POLIEDRY.isOpened == False): if POLIEDRY.face_selected == -1: return angularSpeed = 0. POLIEDRY.animate() if (button == GLUT_LEFT_BUTTON and button_state == GLUT_UP): g_LastRot = copy.copy( g_ThisRot) # Set Last Static Rotation To Last Dynamic One elif (button == GLUT_LEFT_BUTTON and button_state == GLUT_DOWN): g_LastRot = copy.copy( g_ThisRot) # Set Last Static Rotation To Last Dynamic One g_isDragging = True # Prepare For Dragging mouse_pt = Point2fT(cursor_x, cursor_y) g_ArcBall.click( mouse_pt) # Update Start Vector And Prepare For Dragging return
def get_intersected_neigbour(circles: [Circle], start_point: Point, end_point: Point, without=None): if without is None: without = [] line = Line([start_point, end_point]) _min = float('+inf') neigbour = None for circle in circles: if circle in without: continue intersection = line.intersection(circle) if not intersection.is_empty: minimal = Point(min(list(intersection.coords), key=lambda pair: pair[0] ** 2 + pair[1] ** 2)) distance = (start_point.x - minimal.x) ** 2 + (start_point.y - minimal.y) ** 2 if distance < _min: _min = distance neigbour = circle return neigbour
def vanishing_point(lines, v0, O): C0 = lines[-1] if v0[1] < 0 else lines[0] others = lines[:-1] if v0[1] < 0 else lines[1:] domain = np.linspace(C0.left(), C0.right(), N_LONGS + 2)[1:-1] C0_points = np.array([domain, C0.model(domain)]).T longitudes = [Line.from_points(v0, p) for p in C0_points] lefts = [longitudes[0].text_line_intersect(line)[0] for line in others] rights = [longitudes[-1].text_line_intersect(line)[0] for line in others] valid_mask = [line.left() <= L and R < line.right() \ for line, L, R in zip(others, lefts, rights)] valid_lines = [C0] + compress(others, valid_mask) derivs = [line.model.deriv() for line in valid_lines] print('valid lines:', len(others)) convergences = [] for longitude in longitudes: intersects = [ longitude.text_line_intersect(line) for line in valid_lines ] tangents = [Line.from_point_slope(p, d(p[0])) \ for p, d in zip(intersects, derivs)] convergences.append(Line.best_intersection(tangents)) # x vx + y vy + f^2 = 0 # m = -vx / vy # b = -f^2 / vy L = Line.fit(convergences) # shift into O-origin coords L_O = L.offset(-O) vy = -(f**2) / L_O.b vx = -vy * L_O.m v = np.array((vx, vy)) + O debug = cv2.cvtColor(bw, cv2.COLOR_GRAY2BGR) for t in tangents: t.draw(debug, color=RED) for longitude in longitudes: longitude.draw(debug) L.draw(debug, color=GREEN) lib.debug_imwrite('vanish.png', debug) return v, f, L
def test_intersection_1(): l1 = Line() # X axis l2 = Line(direction_vector=Vector([0, 1, 0]), point=Point(0, 1, 0)) # Y-axis l3 = Line(direction_vector=Vector([-1, 1, 0]), point=Point(3, 0, 0)) assert l1.intersection(l2) == Point(0, 0, 0) assert l3.intersection(l2) == Point(0, 3, 0)
def make_section_quad(self, point, previous, width=None): width = width or self.width point = Point(*point) left = Line(previous.top_left, point) top_right = geometry.translate(left.end, left.angle + PI / 2, width) bottom_right = geometry.translate(left.start, left.angle + PI / 2, width) right = Line(bottom_right, top_right) intersection = previous.right.intersection(right) if intersection: bottom_right = intersection p = previous previous = Quad(coords=(p.bottom_left, p.bottom_right, p.top_left, bottom_right)) else: bottom_right = previous.top_right new_quad = Quad(coords=(left.start, bottom_right, left.end, top_right)) return previous, new_quad
def create(self): """Creates lines and bounding box points.""" # Draw outer horizontal portion of Edge. # First and last components are special cases. outer_line_extend_edges = (self.is_wide and self.is_tall) outer_edge_l = self.bb_left.draw_horiz(self.notch_height_other, not outer_line_extend_edges) outer_lines = [] next_edge = outer_edge_l.dest.draw_horiz(self.notch_width, not self.is_tall) outer_lines.append(next_edge) for _notch in range(self.notch_count): next_edge = next_edge.dest.draw_horiz(self.notch_width, self.is_tall) outer_lines.append(next_edge) next_edge = next_edge.dest.draw_horiz(self.notch_width, not self.is_tall) outer_lines.append(next_edge) outer_edge_r = next_edge.dest.draw_horiz(self.notch_height_other, not outer_line_extend_edges) self.bb_right = outer_edge_r.dest # Draw inner segments. inner_line_extend_edges = self.is_wide and not self.is_tall inner_edge_l = outer_edge_l.shift_vertically(self.notch_height) inner_edge_l.is_construction = not inner_line_extend_edges self.inner_bb_left = inner_edge_l.dest # Apart from first/last, inner horizontal is the same as outer, with # construction line bit flipped and y coordinate shifted up. inner_lines = [ line.toggle_constr_and_shift_vertically(self.notch_height) for line in outer_lines ] inner_edge_r = outer_edge_r.shift_vertically(self.notch_height) inner_edge_r.is_construction = not inner_line_extend_edges # Merge inner/outer special cases. outer_lines = [outer_edge_l] + outer_lines + [outer_edge_r] inner_lines = [inner_edge_l] + inner_lines + [inner_edge_r] # Draw a vertical portion of the edge where we see gaps between real # lines. vert_lines = [] for index in range(len(inner_lines) - 1): draw_gap = (not inner_lines[index].is_construction and not outer_lines[index + 1].is_construction) or ( not outer_lines[index].is_construction and not inner_lines[index + 1].is_construction) line = Line(inner_lines[index].dest, outer_lines[index].dest, not draw_gap) vert_lines.append(line) unsorted_lines = inner_lines + outer_lines + vert_lines self.lines = sorted(unsorted_lines, key=lambda x: x.coords_for_plot())
def recur(node, depth=0): node_point = Point(node.value[0], node.value[1]) if depth < self.max_recursion: for child in node.children: child_point = Point(child.value[0], child.value[1]) Line(node_point, child_point).draw(window, color=color, width=1) recur(child, depth + 1)
def test_x_y_and_point_side(first_level, second_level, limit, epsilon): """Check that we can calculate the point on a line with a high precision.""" for _ in range(first_level): m = random.uniform(-limit, limit) n = random.uniform(-limit, limit) x1 = random.uniform(-limit, limit) x2 = random.uniform(-limit, limit) y1 = m * x1 + n y2 = m * x2 + n line = Line(Point(x1, y1), Point(x2, y2)) for _ in range(second_level): x = random.uniform(-limit, limit) y = m * x + n assert -epsilon <= line.x(y) - x <= epsilon assert -epsilon <= line.y(x) - y <= epsilon assert line.point_side(Point(x, y + epsilon)) == sign(x2 - x1)
def create_guideline(self, face): width = 4 vertical_line = Line(face.middle, face.chin) start_line = Line(Point(-10000, 0), Point(10000, 0)) top_point = intersects(vertical_line, start_line) if top_point is not None: self.guideline = Line(top_point, face.chin, color=cs.GREEN, w=width, dash=(4, 4)) else: self.guideline = Line(face.middle, face.chin, color=cs.GREEN, w=width, dash=(4, 4)) self.guideline.screen_ref = self.create_line(self.guideline)
def __init__(self, quad=None, line=None, width=50, section=None, point=None): super().__init__() if quad: self.quad = quad self.line = quad.get_line() elif line: self.line = line if (line.end.x - line.start.x) == 0: angle = 0 if line.end.y < line.start.y else -1 else: angle = math.atan( (line.end.y - line.start.y) / (line.end.x - line.start.x)) self.quad = Quad(coords=( self.move_point(line.start.x, line.start.y, angle, width / 2, 'left'), self.move_point(line.start.x, line.start.y, angle, width / 2, 'right'), self.move_point(line.end.x, line.end.y, angle, width / 2, 'left'), self.move_point(line.end.x, line.end.y, angle, width / 2, 'right'), )) elif section and point and width: self.line = Line(section.quad.get_line().end, point) if (self.line.end.x - self.line.start.x) == 0: angle = 0 if self.line.end.y < self.line.start.y else -1 else: angle = math.atan((self.line.end.y - self.line.start.y) / (self.line.end.x - self.line.start.x)) if self.line.end.x < self.line.start.x: angle = -angle self.quad = Quad(coords=( section.quad.top_left, section.quad.top_right, self.move_point(self.line.end.x, self.line.end.y, angle, width / 2, 'left'), self.move_point(self.line.end.x, self.line.end.y, angle, width / 2, 'right'), )) else: raise ValueError( "Either quad or line with width must be provided to built a Track Section" ) self.colour = (100, 100, 100) self.colour = (200 / 255, 200 / 255, 200 / 255) self.length = self.line.length self.rotated_corners() self.make_box()
def test_parallel(): l1 = Line() # X-axis l2 = Line(direction_vector=Vector([4, 0, 0]), point=Point(8, 0, 0)) l3 = Line.from_points(Point(1, 1, 1), Point(2, 2, 2)) l4 = Line.from_points(Point(0, 0, 0), Point(-1, -1, -1)) assert l1.is_parallel(l2) assert not l1.is_parallel(l3) assert l3.is_parallel(l4)
def get_corner_ground (vp1, vp2, points) : # convention of points : # [left, top, right, bottom] lines = [ Line.from_two_points (vp1, points[0]), # left line Line.from_two_points (vp2, points[1]), # top line, Line.from_two_points (vp1, points[2]), # right line Line.from_two_points (vp2, points[3]) # bottom line ] corner = ( lines[0].get_intersection (lines[1]), # top left corner lines[1].get_intersection (lines[2]), # top right corner lines[2].get_intersection (lines[3]), # bottom right corner lines[3].get_intersection (lines[0]) # bottom left corner ) return corner
def bounce(self, tiles): results = [] while True: if self.travelled.as_vector().length2() == 0: return results max_dist2 = -1.0 reflectors = [] for tile in tiles: # if the distance between the bullet and the center of the tile is # greater than the distance travelled by the bullet plus the # size of the tile, then no collision could have occurred if self.travelled.length() + math.sqrt(2) / 2 < (self.position - tile.position).length(): continue for tile_side in tile.get_sides(): # first check that we're coming from the right direction if self.travelled.as_vector().normalize().dot(tile_side.normal()) > 0: continue p = self.travelled.intersect_segments(tile_side) if not p is None: if reflectors is None or (p - self.position).length2() > max_dist2: reflectors = [(p, tile_side)] elif max_dist2 < (p - self.position).length2() <= max_dist2: reflectors.append((p, tile_side)) if len(reflectors) == 1: if self.has_bounces() and not self.splash: (p, wall) = reflectors[0] self.position = wall.reflect(self.position) self.direction = (self.position - p).angle() self.travelled = Line(p, self.position) self.reset_vec() self.bounces += 1 self.update_graphics() results.append((BOUNCED, self.position)) else: results.append((EXPLODED, self.position)) break elif reflectors: print "multiple reflectors!" else: break return results
class Bullet(pygame.sprite.Sprite): # position holds xy coordinates of the bullet as a Point # direction contains an angle in radians from the positive # x axis. def __init__(self, p, direction, owner, splash=False): super(Bullet, self).__init__() self.position = p self.direction = direction self.owner = owner self.splash = splash if not self.splash: self.original = pygame.Surface([constants.TILE_SIZE * constants.BULLET_WIDTH_RATIO, constants.TILE_SIZE * constants.BULLET_HEIGHT_RATIO], flags=pygame.SRCALPHA) self.original.fill(constants.BULLET_COLOR) else: size = int(round(constants.BULLET_WIDTH_RATIO * constants.TILE_SIZE)) self.original = pygame.Surface([size, size], flags=pygame.SRCALPHA) self.original.fill(constants.COLOR_TRANSPARENT) image_center = (self.original.get_width() / 2, self.original.get_height() / 2) pygame.draw.circle(self.original, constants.BULLET_COLOR, image_center, int(round(self.original.get_width() / 2))) self.old_position = self.position self.reset_vec() self.bounces = 0 self.total_distance = 0.0 self.dead = False self.travelled = Line(self.position, self.position) self.update_graphics() def get_explosion(self): if self.splash: return BigExplosion(self.position, True) else: return Explosion(self.position) def expired(self): return self.dead def die(self): self.owner.bullets -= 1 self.dead = True def has_bounces(self): return self.bounces < 1 def has_bounced(self): return self.bounces > 0 def reset_vec(self): self.vec = Vector(math.cos(self.direction), math.sin(self.direction)).normalize() # bounce off wall (which is a line segment). # traces movement of bullet backwards def bounce(self, tiles): results = [] while True: if self.travelled.as_vector().length2() == 0: return results max_dist2 = -1.0 reflectors = [] for tile in tiles: # if the distance between the bullet and the center of the tile is # greater than the distance travelled by the bullet plus the # size of the tile, then no collision could have occurred if self.travelled.length() + math.sqrt(2) / 2 < (self.position - tile.position).length(): continue for tile_side in tile.get_sides(): # first check that we're coming from the right direction if self.travelled.as_vector().normalize().dot(tile_side.normal()) > 0: continue p = self.travelled.intersect_segments(tile_side) if not p is None: if reflectors is None or (p - self.position).length2() > max_dist2: reflectors = [(p, tile_side)] elif max_dist2 < (p - self.position).length2() <= max_dist2: reflectors.append((p, tile_side)) if len(reflectors) == 1: if self.has_bounces() and not self.splash: (p, wall) = reflectors[0] self.position = wall.reflect(self.position) self.direction = (self.position - p).angle() self.travelled = Line(p, self.position) self.reset_vec() self.bounces += 1 self.update_graphics() results.append((BOUNCED, self.position)) else: results.append((EXPLODED, self.position)) break elif reflectors: print "multiple reflectors!" else: break return results def update(self, delta): self.old_position = self.position displacement = (constants.BULLET_SPEED * delta / 1000.0) * self.vec self.total_distance += displacement.length() self.position = self.position.translate(displacement) self.travelled = Line(self.old_position, self.position) self.update_graphics() def update_graphics(self): self.image = pygame.transform.rotate(self.original, -self.direction * 180.0 / math.pi) self.rect = self.image.get_rect(center=(constants.TILE_SIZE * self.position.x, constants.TILE_SIZE * self.position.y))