def is_equal_to(self, target, error_range=0): if not isinstance(target, DxfLineStatement): return False return (is_equal_point(self.start, target.start, error_range) and \ is_equal_point(self.end, target.end, error_range)) or \ (is_equal_point(self.start, target.end, error_range) and \ is_equal_point(self.end, target.start, error_range))
def _judge_cross(self, from_pt, to_pt, index, error_range): standard = normalize_vec2d( (to_pt[0] - from_pt[0], to_pt[1] - from_pt[1])) normal = (standard[1], -standard[0]) def statements(): for i in range(index, len(self.statements)): yield self.statements[i] for i in range(0, index): yield self.statements[i] dot_standard = None for statement in statements(): tstart = statement.start tend = statement.end target = normalize_vec2d( (tend[0] - tstart[0], tend[1] - tstart[1])) dot = dot_vec2d(normal, target) if dot_standard is None: dot_standard = dot continue if is_equal_point(standard, target, error_range): continue return (dot_standard > 0 and dot > 0) or (dot_standard < 0 and dot < 0) raise Exception( 'inconsistensy is detected while cross judgement between paths')
def merge(self, element, error_range=0): if self.is_closed or element.is_closed: return False if not error_range: error_range = self.error_range if is_equal_point(self.end, element.start, error_range): return self._append_at_end(element, error_range) elif is_equal_point(self.end, element.end, error_range): element.reverse() return self._append_at_end(element, error_range) elif is_equal_point(self.start, element.end, error_range): return self._insert_on_top(element, error_range) elif is_equal_point(self.start, element.start, error_range): element.reverse() return self._insert_on_top(element, error_range) else: return False
def is_equal_to(self, target, error_range=0): if not isinstance(target, DxfArcStatement): return False aerror_range = error_range / pi * self.radius * 180 return is_equal_point(self.center, target.center, error_range) and \ is_equal_value(self.radius, target.radius, error_range) and \ ((is_equal_value(self.start_angle, target.start_angle, aerror_range) and is_equal_value(self.end_angle, target.end_angle, aerror_range)) or (is_equal_value(self.start_angle, target.end_angle, aerror_range) and is_equal_value(self.end_angle, target.end_angle, aerror_range)))
def is_equal_to(self, target, error_range=0): if not isinstance(target, DxfPath): return False if len(self.statements) != len(target.statements): return False if is_equal_point(self.start, target.start, error_range) and \ is_equal_point(self.end, target.end, error_range): for i in range(0, len(self.statements)): if not self.statements[i].is_equal_to(target.statements[i], error_range): return False return True elif is_equal_point(self.start, target.end, error_range) and \ is_equal_point(self.end, target.start, error_range): for i in range(0, len(self.statements)): if not self.statements[i].is_equal_to( target.statements[-1 - i], error_range): return False return True return False
def intersections_with_halfline(self, point_from, point_to, error_range): intersection = \ _intersections_of_line_and_circle( point_from, point_to, self.center, self.radius, error_range) if intersection is None: return [] else: p1, p2, p1_angle, p2_angle, p1_t, p2_t = intersection if is_equal_point(p1, self.start, error_range): p1 = None elif p2 is not None and is_equal_point(p2, self.start, error_range): p2 = None def is_contained(angle, region, error): if angle >= region[0] - error and angle <= region[1] + error: return True if angle < 0 and region[1] > 0: angle = angle + 2 * pi elif angle > 0 and region[0] < 0: angle = angle - 2 * pi return angle >= region[0] - error and angle <= region[1] + error aerror = error_range * self.radius pts = [] if p1 is not None and p1_t >= 0 and not is_equal_point(p1, self.start, error_range): for region in self.angle_regions: if is_contained(p1_angle, region, aerror): pts.append(p1) break if p2 is not None and p2_t >= 0 and not is_equal_point(p2, self.start, error_range): for region in self.angle_regions: if is_contained(p2_angle, region, aerror): pts.append(p2) break return pts
def _collect_intersections(self, calculator, validator, error_range): allpts = [] last = allpts for i in range(0, len(self.statements)): statement = self.statements[i] cur = calculator(statement) if cur: for pt in cur: for dest in allpts: if is_equal_point(pt, dest, error_range): break else: if validator is not None and not validator( pt, statement, i): continue allpts.append(pt) last = cur return allpts
def __init__(self, statements, units, dcode=10, draw_mode=None, fill_mode=None): if draw_mode is None: draw_mode = DxfFile.DM_LINE if fill_mode is None: fill_mode = DxfFile.FM_TURN_OVER self._units = units self.dcode = dcode self.draw_mode = draw_mode self.fill_mode = fill_mode self.pitch = inch(1) if self._units == 'inch' else 1 self.width = 0 self.error_range = inch(ACCEPTABLE_ERROR) if self._units == 'inch' else ACCEPTABLE_ERROR self.statements = list(filter( lambda i: not (isinstance(i, DxfLineStatement) and \ is_equal_point(i.start, i.end, self.error_range)), statements )) self.close_paths, self.open_paths = generate_paths(self.statements, self.error_range) self.sorted_close_paths = [] self.polarity = True # True means dark, False means clear
def intersections_with_halfline(self, point_from, point_to, error_range): denominator = (self.end[0] - self.start[0]) * (point_to[1] - point_from[1]) - \ (self.end[1] - self.start[1]) * (point_to[0] - point_from[0]) de = error_range * error_range if denominator >= -de and denominator <= de: return [] from_dx = point_from[0] - self.start[0] from_dy = point_from[1] - self.start[1] r = ((point_to[1] - point_from[1]) * from_dx - (point_to[0] - point_from[0]) * from_dy) / denominator s = ((self.end[1] - self.start[1]) * from_dx - (self.end[0] - self.start[0]) * from_dy) / denominator dx = (self.end[0] - self.start[0]) dy = (self.end[1] - self.start[1]) le = error_range / sqrt(dx * dx + dy * dy) if s < 0 or r < -le or r > 1 + le: return [] pt = (self.start[0] + (self.end[0] - self.start[0]) * r, self.start[1] + (self.end[1] - self.start[1]) * r) if is_equal_point(pt, self.start, error_range): return [] else: return [pt]
def is_closed(self): return len(self.statements) > 1 and \ is_equal_point(self.start, self.end, self.error_range)
def is_equal_to(self, target, error_range=0): if not isinstance(target, DxfCircleStatement): return False return is_equal_point(self.center, target.enter, error_range) and \ is_equal_value(self.radius, target.radius)
def validator(pt, statement, idx): if is_equal_point(pt, statement.end, error_range) and \ not self._judge_cross(point_from, point_to, idx, error_range): return False return True
def is_closed(self): if len(self.statements) == 1: return self.statements[0].is_closed else: return is_equal_point(self.start, self.end, self.error_range)