def index(self, indexer: Indexer): ret = [] nls_conds = indexer.index_by_type(NLineSector) for cond in nls_conds: r = cond.relationship # Existence of ratio condition is guaranteed. ratio_cond = indexer.index_value_condition(r, 'ratio') ratio = ratio_cond.attr_value near_point, split_point, far_point = r.three_points line_near = indexer.index_line_by_points(near_point, split_point) line_far = indexer.index_line_by_points(far_point, split_point) line_full = indexer.index_line_by_points(near_point, far_point) near_cond = indexer.index_value_condition(line_near, 'length') far_cond = indexer.index_value_condition(line_far, 'length') full_cond = indexer.index_value_condition(line_full, 'length') if full_cond.attr_value is None: if near_cond.attr_value is not None: ret.append([[near_cond, ratio_cond, 1/ratio], full_cond]) elif far_cond.attr_value is not None: ret.append([[far_cond, ratio_cond, 1/(1-ratio)], full_cond]) if near_cond.attr_value is None: if full_cond.attr_value is not None: ret.append([[full_cond, ratio_cond, ratio], near_cond]) elif far_cond.attr_value is not None: ret.append([[far_cond, ratio_cond, ratio/(1-ratio)], near_cond]) if far_cond.attr_value is None: if full_cond.attr_value is not None: ret.append([[full_cond, ratio_cond, 1-ratio], far_cond]) elif near_cond.attr_value is not None: ret.append([[near_cond, ratio_cond, (1-ratio)/ratio], far_cond]) return ret
def index(self, indexer: Indexer): """Find interior angles on the same side from parallel relationship.""" ret = [] def find_alternate_angles(link_col, col1, col2, p1, p2): p1_index = link_col.index(p1) p2_index = link_col.index(p2) reverse = lambda x: -1 if x == 0 else 0 compare = p1_index < p2_index p1_direction = -1 if compare else 0 for k in [0, -1]: if link_col[p1_direction] == p1 or col1[k] == p1: continue if link_col[reverse(p1_direction)] == p2 or col2[k] == p2: continue angle1 = indexer.index_angle_by_points(\ link_col[p1_direction], p1, col1[k]) angle2 = indexer.index_angle_by_points(\ link_col[reverse(p1_direction)], p2, col2[k]) a1_cond = indexer.index_value_condition(angle1, 'angle') a2_cond = indexer.index_value_condition(angle2, 'angle') if a1_cond.attr_value is None \ and a2_cond.attr_value is not None: ret.append([[a2_cond], a1_cond]) elif a1_cond.attr_value is not None \ and a2_cond.attr_value is None: ret.append([[a1_cond], a2_cond]) conds = indexer.index_by_type(Parallel) for cond in conds: r = cond.relationship line1, line2 = r.line1, r.line2 # col is a list of point entity. col1 = indexer.index_collineation_by_line(line1) col2 = indexer.index_collineation_by_line(line2) if r.reverse: col2 = list(reversed(col2)) for p1 in col1: for p2 in col2: # Link line is the line links two parallel lines. link_line = indexer.index_line_by_points(p1, p2) # One link line can generate four corresponding angles at most. if link_line is None: continue link_col = indexer.index_collineation_by_line(link_line) find_alternate_angles(link_col, col1, col2, p1, p2) return ret
def _find_lines_by_collineation(self, col_cond: RelationshipBased, indexer: Indexer): col = col_cond.relationship ps = col.points size = len(ps) # Find line sum permutation. for i in range(size): for j in range(i + 1, size): for k in range(j + 1, size): line_ij = indexer.index_line_by_points(ps[i], ps[j]) line_jk = indexer.index_line_by_points(ps[j], ps[k]) line_ik = indexer.index_line_by_points(ps[i], ps[k]) cond_ij = indexer.index_value_condition(line_ij, 'length') cond_jk = indexer.index_value_condition(line_jk, 'length') cond_ik = indexer.index_value_condition(line_ik, 'length') if sum([ cond_ij.attr_value == None, cond_jk.attr_value == None, cond_ik.attr_value == None ]) == 1: return [[col_cond, cond_ij, cond_jk], (cond_ik)] return None
def index(self, indexer: Indexer): """Find corresponding angles from parallel relationship.""" ret = [] def find_corresponding_angles(link_col, col1, col2, p1, p2): for i in [0, -1]: for j in [0, -1]: if link_col[i] == p1 or col1[j] == p1: continue if link_col[i] == p2 or col2[j] == p2: continue angle1 = indexer.index_angle_by_points(\ link_col[i], p1, col1[j]) angle2 = indexer.index_angle_by_points(\ link_col[i], p2, col2[j]) a1_cond = indexer.index_value_condition(angle1, 'angle') a2_cond = indexer.index_value_condition(angle2, 'angle') if a1_cond.attr_value is None \ and a2_cond.attr_value is not None: ret.append([[a2_cond], a1_cond]) elif a1_cond.attr_value is not None \ and a2_cond.attr_value is None: ret.append([[a1_cond], a2_cond]) conds = indexer.index_by_type(Parallel) for cond in conds: r = cond.relationship line1, line2 = r.line1, r.line2 # col is a list of point entity. col1 = indexer.index_collineation_by_line(line1) col2 = indexer.index_collineation_by_line(line2) if r.reverse: col2 = list(reversed(col2)) for p1 in col1: for p2 in col2: # Link line is the line links two parallel lines. link_line = indexer.index_line_by_points(p1, p2) # One link line can generate four corresponding angles at most. if link_line is None: continue link_col = indexer.index_collineation_by_line(link_line) find_corresponding_angles(link_col, col1, col2, p1, p2) return ret