def rebars_in_stress_block(x_sb, y_sb, xr, yr): ''' Returns a list with entry 'True' for rebars located inside the stress block, 'False' otherwise ''' if xr and yr: # Arrange rebar coordinates rebar_coords = [[xr[i], yr[i]] for i in range(len(xr))] else: raise ValueError('No rebars in section.') # Compute area of stress block Asb = geometry.polygon_area(x_sb, y_sb) if Asb != 0: # Arrange stress block coordinates sb_poly = [[x_sb[i], y_sb[i]] for i in range(len(x_sb))] # Check if rebars are inside the stress block path = mpltPath.Path(sb_poly) # Returns 'True' if rebar is inside stress block rebars_inside = path.contains_points(rebar_coords) else: # All rebars are in tension (all entries are 'False') rebars_inside = [False] * len(xr) return rebars_inside
def transformed_axial_stiffness(x, y, xr, yr, dia, P, Ec=EC, Es=ES): ''' Return axial stiffness EA of transformed concrete section. ''' # Stiffness ratio n = Es / Ec # Area of rebars As = sum([pi * d**2 / 4 for d in dia]) if P <= 0: # Axial force is compressive # Compute area of section A = geometry.polygon_area(x, y) # Area of concrete Ac = A - As # Transformed stiffness weighed by actual area (not transformed area in this case) Et = (Ec * Ac + (n - 1) * Es * As) / A # Transformed arae At = Ac + (n - 1) * As return Et * At else: # Axial force is tensile # Stiffness and area contribution comes from rebars only E = Es return E * As
def convert(self, element: Element, tags: dict, osm_helper: OsmHelper): if element.tag == 'node': return (float(element.attrib['lat']), float(element.attrib['lon'])), 0 else: polygons = [(polygon, polygon_area(polygon)) for polygon in element_to_polygons(element, osm_helper)] if len(polygons) > 0: polygon, area = max(polygons, key=itemgetter(1)) return polygon_centroid(polygon), element_to_area_m(element, osm_helper)
def compute_plastic_centroid(x, y, xr, yr, As, fck, fyk): ''' Return plastic centroid of a reinforced concrete section. ''' Ac = geometry.polygon_area(x, y) eta = 0.85 # TODO Look into whether eta should be an input arg F = sum([As[i] * fyk for i in As]) + eta * (Ac - sum(As)) * fck # TODO Find correct and general arm for concrete force (polygon section) F_dx = sum([As[i] * fyk * xr[i] for i in range(len(xr)) ]) + eta * (Ac - sum(As)) * fck * 500 / 2 F_dy = sum([As[i] * fyk * yr[i] for i in range(len(yr)) ]) + eta * (Ac - sum(As)) * fck * 375 / 2 xpl = F_dx / F ypl = F_dy / F return xpl, ypl
def jaccard_index_3d(a: BBox3D, b: BBox3D): """ Compute the Jaccard Index / Intersection over Union (IoU) of a pair of 3D bounding boxes. We compute the IoU using the top-down bird's eye view of the boxes. **Note**: We follow the KITTI format and assume only yaw rotations (along z-axis). Args: a (:py:class:`BBox3D`): 3D bounding box. b (:py:class:`BBox3D`): 3D bounding box. Returns: :py:class:`float`: The IoU of the 2 bounding boxes. """ # check if the two boxes don't overlap if not polygon_collision(a.p[0:4, 0:2], b.p[0:4, 0:2]): return np.round_(0, decimals=5) intersection_points = polygon_intersection(a.p[0:4, 0:2], b.p[0:4, 0:2]) inter_area = polygon_area(intersection_points) zmax = np.minimum(a.cz, b.cz) zmin = np.maximum(a.cz - a.h, b.cz - b.h) inter_vol = inter_area * np.maximum(0, zmax - zmin) a_vol = a.l * a.w * a.h b_vol = b.l * b.w * b.h union_vol = (a_vol + b_vol - inter_vol) iou = inter_vol / union_vol # set nan and +/- inf to 0 if np.isinf(iou) or np.isnan(iou): iou = 0 return np.round_(iou, decimals=5)
print('testing geometry.polygon_area') test_count = 0 correct_tests = 0 failure = None with open('testdata/area.in', 'r') as f: count = int(f.readline()) for i in range(count): node_count = int(f.readline()) polygon = [] for j in range(node_count): x, y = map(float, f.readline().split()) polygon.append((x, y)) expected = float(f.readline()) f.readline() result = geometry.polygon_area(polygon) fail = None if not isinstance(result, float): fail = 'expected float, got {}'.format(type(result)) elif not close_enough(result, expected): fail = 'expected {}, got {}'.format(expected, result) else: correct_tests += 1 test_count += 1 if failure is None and fail is not None: failure = 'for polygon:\n{}\n {}'.format(polygon, fail) print('{} out of {} test cases correct.'.format(correct_tests, test_count)) if failure is not None: print('First failed test: {}'.format(failure))
def stress_block_geometry(x, y, dv, dr, alpha_deg, na_y, lambda_=0.8): ''' Returns stress block geometry. INPUT x - List of x-coordinates of concrete section vertices y - List of y-coordinates of concrete section vertices dv - List of distances from neutral axis to each section vertex dr - List of distances from neutral axis to each rebar alpha_deg - na_y - OUTPUT x_sb - List of x-coordinates of stress block vertices y_sb - List of y-coordinates of stress block vertices Asb - Area of stress block sb_cog - Cenntroid of stress block represented as tuple, i.e. in the format (x, y) ''' # TODO Split this to multiple functions that are easier to understand and test/debug # PURE TENSION CASE # NOTE Test if this is true! Does not account for gap btw. sb and tension zone if all(d >= 0 for d in dv): cross_section_state = 'PURE TENSION' # Distance from neutral axis to extreme tension bar (all distances will be positve) c = max([d for d in dr if d > 0]) # Set vertices of stress block x_sb = None y_sb = None # Set stress block area Asb = 0 sb_cog = None # PURE COMPRESSION CASE elif all(d <= 0 for d in dv): # NOTE Test if this is true! cross_section_state = 'PURE COMPRESSION' # Distance from neutral axis to extreme compression fiber (all distances will be negative) c = min(dv) # Set vertices of stress block (entire section) x_sb = x y_sb = y Asb = geometry.polygon_area(x, y) sb_cog = geometry.polygon_centroid(x, y) # MIXED TENSION/COMPRESSION CASE else: cross_section_state = 'MIXED TENSION/COMPRESSION' # Distance from neutral axis to extreme compression fiber (pos. in tension / negative in compression) # FIXME This might not be correct in all cases (if compression zone is very small, tension will dominate) c = min(dv) # NOTE beta_1=0.85 from ACI should be replaced by lambda = 0.8 from Eurocode for concrete strengths < C50 (change also default function input) # Signed distance from inner stress block edge to extreme compression fiber a = lambda_ * c # Signed perpendicular distance between neutral axis and stress block delta_p = c - a # Vert. dist. in y-coordinate from neutral axis to inner edge of stress block delta_v = delta_p / cos(alpha_deg * pi / 180) # Intersection between stress block inner edge and y-axis (parallel with neutral axis) # if alpha_deg == 90: # sb_y_intersect = delta_v - na_y # NOTE I can't really explain why this conditional is necessary, but it fixed the immediate problem # else: sb_y_intersect = na_y - delta_v # Intersections between inner edge of stress block (parrallel with neutral axis) and section sb_xint, sb_yint = geometry.line_polygon_collisions( alpha_deg, sb_y_intersect, x, y) # Find concrete section vertices that are in compression x_compr_vertices, y_compr_vertices = geometry.get_section_compression_vertices( x, y, na_y, alpha_deg, delta_v) # Collect all stress block vertices x_sb = sb_xint + x_compr_vertices y_sb = sb_yint + y_compr_vertices # Order stress block vertices with respect to centroid for the entire section # NOTE Might fail for non-convex polygons, e.g. a T-beam x_sb, y_sb = geometry.order_polygon_vertices(x_sb, y_sb, x, y, counterclockwise=True) # NOTE Calc of area and centre of gravity is unnecessary in this function and should be done elsewhere if needed # Compute area of the stress block by shoelace algorithm Asb = geometry.polygon_area(x_sb, y_sb) # Compute location of centroid for stress block polygon sb_cog = geometry.polygon_centroid(x_sb, y_sb) return x_sb, y_sb, Asb, sb_cog, c