def __init__(self, barycenter, location, p1, p2, p3): self.location = location self.position = p2 self.direction = pnormalized(get_bisector(p1, p2, p3, self.up_vector)) preferred_direction = pnormalized(psub(p2, barycenter)) # direction_factor: 0..1 (bigger -> better) direction_factor = (pdot(preferred_direction, self.direction) + 1) / 2 angle = get_angle_pi(p1, p2, p3, self.up_vector, pi_factor=True) # angle_factor: 0..1 (bigger -> better) if angle > 0.5: # use only angles > 90 degree angle_factor = angle / 2.0 else: angle_factor = 0 # priority: 0..1 (bigger -> better) self.priority = angle_factor * direction_factor
def _offset_loops_to_polygons(offset_loops): model = pycam.Geometry.Model.ContourModel() before = None for n_loop, loop in enumerate(offset_loops): lines = [] _log.info("loop #%d has %d lines/arcs", n_loop, len(loop)) for n_segment, item in enumerate(loop): _log.info("%d -> %s", n_segment, item) point, radius = item[:2] point = (point.x, point.y, 0.0) if before is not None: if radius == -1: lines.append(Line(before, point)) _log.info("%d line %s to %s", n_segment, before, point) else: _log.info("%d arc %s to %s r=%f", n_segment, before, point, radius) center, clock_wise = item[2:4] center = (center.x, center.y, 0.0) direction_before = (before[0] - center[0], before[1] - center[1], 0.0) direction_end = (point[0] - center[0], point[1] - center[1], 0.0) angles = [ 180.0 * get_angle_pi((1.0, 0.0, 0.0), (0, 0.0, 0.0), direction, (0.0, 0.0, 1.0), pi_factor=True) for direction in (direction_before, direction_end) ] if clock_wise: angles.reverse() points = get_points_of_arc(center, radius, angles[0], angles[1]) last_p = before for p in points: lines.append(Line(last_p, p)) last_p = p before = point for line in lines: if line.len > epsilon: model.append(line) return model.get_polygons()
def get_spiral_layer(minx, maxx, miny, maxy, z, line_distance, step_width, grid_direction, start_position, rounded_corners, reverse): current_location = _get_position(minx, maxx, miny, maxy, z, start_position) if line_distance > 0: line_steps_x = math.ceil((float(maxx - minx) / line_distance)) line_steps_y = math.ceil((float(maxy - miny) / line_distance)) line_distance_x = (maxx - minx) / line_steps_x line_distance_y = (maxy - miny) / line_steps_y lines = get_spiral_layer_lines(minx, maxx, miny, maxy, z, line_distance_x, line_distance_y, grid_direction, start_position, current_location) if reverse: lines.reverse() # turn the lines into steps if rounded_corners: rounded_lines = [] previous = None for index, (start, end) in enumerate(lines): radius = 0.5 * min(line_distance_x, line_distance_y) edge_vector = psub(end, start) # TODO: ellipse would be better than arc offset = pmul(pnormalized(edge_vector), radius) if previous: start = padd(start, offset) center = padd(previous, offset) up_vector = pnormalized( pcross(psub(previous, center), psub(start, center))) north = padd(center, (1.0, 0.0, 0.0, 'v')) angle_start = get_angle_pi( north, center, previous, up_vector, pi_factor=True) * 180.0 angle_end = get_angle_pi( north, center, start, up_vector, pi_factor=True) * 180.0 # TODO: remove these exceptions based on up_vector.z (get_points_of_arc does # not respect the plane, yet) if up_vector[2] < 0: angle_start, angle_end = -angle_end, -angle_start arc_points = get_points_of_arc(center, radius, angle_start, angle_end) if up_vector[2] < 0: arc_points.reverse() for arc_index in range(len(arc_points) - 1): p1_coord = arc_points[arc_index] p2_coord = arc_points[arc_index + 1] p1 = (p1_coord[0], p1_coord[1], z) p2 = (p2_coord[0], p2_coord[1], z) rounded_lines.append((p1, p2)) if index != len(lines) - 1: end = psub(end, offset) previous = end rounded_lines.append((start, end)) lines = rounded_lines for start, end in lines: points = [] if step_width is None: points.append(start) points.append(end) else: line = Line(start, end) if isiterable(step_width): steps = step_width else: steps = floatrange(0.0, line.len, inc=step_width) for step in steps: next_point = padd(line.p1, pmul(line.dir, step)) points.append(next_point) if reverse: points.reverse() yield points