def get_gradient(self, point): """ central differences, with tetrahedron technique. 30-40% faster regular `get_gradient_regular`. """ d0 = self.o.get_distance(Point(point.x + self.e, point.y - self.e, point.z - self.e)) d1 = self.o.get_distance(Point(point.x - self.e, point.y - self.e, point.z + self.e)) d2 = self.o.get_distance(Point(point.x - self.e, point.y + self.e, point.z - self.e)) d3 = self.o.get_distance(Point(point.x + self.e, point.y + self.e, point.z + self.e)) v = Vector(d0 - d1 - d2 + d3, -d0 - d1 + d2 + d3, -d0 + d1 - d2 + d3) v.unitize() return v
def __init__(self, xyz='1 0 0', **kwargs): # We are not using Vector here because we # cannot attach _urdf_source to it due to __slots__ super(Axis, self).__init__() xyz = _parse_floats(xyz) xyz = Vector(*xyz) if xyz.length != 0: xyz.unitize() self.x = xyz[0] self.y = xyz[1] self.z = xyz[2] self.attr = kwargs
def gluepath_creator(int_surf, path_width): def interval_checker(dimension): underflow = dimension % path_width if underflow > 0.2: no_paths = dimension // path_width + 1 new_path_width = dimension / no_paths return new_path_width else: return path_width wid_gap = int_surf[1] - int_surf[0] wid_vec = Vector(wid_gap[0], wid_gap[1], wid_gap[2]) wid = wid_vec.length wid_vec.unitize() len_gap = int_surf[2] - int_surf[1] len_vec = Vector(len_gap[0], len_gap[1], len_gap[2]) len = len_vec.length len_vec.unitize() wid_path = interval_checker(wid) len_path = interval_checker(len) path_dims = [wid_path, len_path] path_points = [] iteration = 0 path_unfinished = True current_pt = int_surf[0] + scale_vector( wid_vec, wid_path / 2) + scale_vector(len_vec, len_path / 2) current_vec = len_vec.unitized() len_left = len - len_path wid_left = wid - wid_path dims_left = [len_left, wid_left] path_points.append(current_pt) R = Rotation.from_axis_and_angle([0, 0, 1], -math.pi / 2) while path_unfinished: current_index = iteration % 2 current_dim = dims_left[current_index] if iteration > 2: current_dim -= path_dims[current_index] dims_left[current_index] = current_dim if current_dim < path_width * 0.95: break current_pt = current_pt + scale_vector(current_vec, current_dim) path_points.append(current_pt) current_vec.transform(R) current_vec.unitize() iteration += 1 if not is_point_in_polygon_xy(current_pt, int_surf): print("Error: Point not in polygon") return path_points
def extrude_normal(polygon, distance, plane=None): if plane is None: x, y, z = cross_vectors(subtract_vectors(polygon[0], polygon[1]), subtract_vectors(polygon[0], polygon[2])) normal = Vector(x, y, z) else: normal = plane.normal Vector.unitize(normal) normal = scale_vector(normal, distance) # normal = Vector(x, y, z) moved = [add_vectors(pt, normal) for pt in polygon] polygon.extend(moved) return polygon
def get_distance(self, point): if not isinstance(point, Point): point = Point(*point) point.transform(self.inversetransform) x, y, z = point # Tetrahedron if self.type == 0: return (max(abs(x + y) - z, abs(x - y) + z) - self.radius) / self.sqrt3 # Octahedron elif self.type == 1: s = abs(x) + abs(y) + abs(z) return (s - self.radius) * self.tan30 # Dodecahedron elif self.type == 2: v = Vector((1+sqrt(5))/2, 1, 0) v.unitize() px = abs(x / self.radius) py = abs(y / self.radius) pz = abs(z / self.radius) p = Vector(px, py, pz) a = p.dot(v) b = p.dot(Vector(v.z, v.x, v.y)) c = p.dot(Vector(v.y, v.z, v.x)) q = (max(max(a, b), c) - v.x) * self.radius return q # Icosahedron elif self.type == 3: r = self.radius * 0.8506507174597755 v = Vector((sqrt(5) + 3)/2, 1, 0) v.unitize() w = sqrt(3)/3 px = abs(x / r) py = abs(y / r) pz = abs(z / r) p = Vector(px, py, pz) a = p.dot(v) b = p.dot(Vector(v.z, v.x, v.y)) c = p.dot(Vector(v.y, v.z, v.x)) d = p.dot([w,w,w]) - v.x q = max(max(max(a, b), c) - v.x, d) * r return q else: return 0
def get_gradient_regular(self, point): """ central difference gradient method """ import warnings warnings.warn("get_gradient_regular is deprecated and might/will be removed in the future", DeprecationWarning, 2) dx = self.o.get_distance(point + self.ex) - self.o.get_distance( point + self.ex * -1 ) dy = self.o.get_distance(point + self.ey) - self.o.get_distance( point + self.ey * -1 ) dz = self.o.get_distance(point + self.ez) - self.o.get_distance( point + self.ez * -1 ) v = Vector(dx, dy, dz) v.unitize() return v
def gusset_points(self): ''' Gusset points defined in Q1 of XY plane: all transformation done wrt this system. ''' pt0 = list(Point(self.eb, self.ec)) pt1 = translate_points_xy([pt0], Vector(self.width, 0, 0))[0] pt2 = translate_points_xy([pt1], Vector(0, self.offset, 0))[0] pt6 = translate_points_xy([pt0], Vector(0, self.height, 0))[0] pt5 = translate_points_xy([pt6], Vector(self.offset, 0, 0))[0] # Brace CL brace_vector = Vector(sin(radians(self.design_angle)), cos(radians(self.design_angle)), 0) brace_vector.unitize() brace_vector.scale(100) brace_pt = translate_points_xy([self.work_point], brace_vector)[0] test = brace_vector.copy() test.scale(1) brace_pt_out = translate_points_xy([self.work_point], test)[0] brace_CL = Line(self.work_point, brace_pt) self.gusset_lines.append(Line(self.work_point, brace_pt_out)) brace_vector.unitize() brace_vector.scale(self.connection_length) # Brace shoulder lines brace_depth = self.get_brace_depth() column_offset = brace_depth * 0.5 + self.offset beam_offset = -(brace_depth * 0.5 + self.offset) column_line = Line(pt5, Point(pt5[0], 0, 0)) beam_line = Line(pt2, Point(0, pt2[1], 0)) self.gusset_lines.append(column_line) self.gusset_lines.append(beam_line) def get_brace_points(offset_value, offset_member, brace_CL, brace_vector, offset_dir='+'): offset_brace = offset_line(brace_CL, offset_value) if offset_dir == '+': offset_brace_signed = offset_line(brace_CL, offset_value - self.offset) elif offset_dir == '-': offset_brace_signed = offset_line(brace_CL, offset_value + self.offset) else: raise ValueError brace_member_int = intersection_line_line_xy( offset_brace, offset_member) brace_pt = translate_points_xy([brace_member_int], brace_vector)[0] pt_mirrored = mirror_points_line([brace_pt], brace_CL) line_segment = Line(brace_pt, pt_mirrored) pt_CL = intersection_line_line_xy(line_segment, brace_CL) pt_distance = distance_point_point(self.work_point, pt_CL) return line_segment, pt_distance, offset_brace, offset_brace_signed column_line, col_dist, os_brace_column, os_column = get_brace_points( column_offset, column_line, brace_CL, brace_vector, offset_dir='+') beam_line, beam_dist, os_brace_beam, os_beam = get_brace_points( beam_offset, beam_line, brace_CL, brace_vector, offset_dir='-') self.gusset_lines.append(os_brace_column) self.gusset_lines.append(os_brace_beam) self.gusset_lines.append(os_column) self.gusset_lines.append(os_beam) self.gusset_lines.append(column_line) self.gusset_lines.append(beam_line) if col_dist > beam_dist: pt3 = column_line[1] pt4 = column_line[0] else: pt3 = beam_line[0] pt4 = beam_line[1] # TODO: set check to make sure gusset is non concave # (i.e. force points to line between pt2 and pt5) # Points list to point pt0 = Point(pt0[0], pt0[1], pt0[2]) pt1 = Point(pt1[0], pt1[1], pt1[2]) pt2 = Point(pt2[0], pt2[1], pt2[2]) pt6 = Point(pt6[0], pt6[1], pt6[2]) pt5 = Point(pt5[0], pt5[1], pt5[2]) self._gusset_points = [pt0, pt1, pt2, pt3, pt4, pt5, pt6] return self._gusset_points