コード例 #1
0
 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))
コード例 #2
0
    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')
コード例 #3
0
 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
コード例 #4
0
 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)))
コード例 #5
0
 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
コード例 #6
0
    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
コード例 #7
0
 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
コード例 #8
0
 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
コード例 #9
0
 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]
コード例 #10
0
 def is_closed(self):
     return len(self.statements) > 1 and \
            is_equal_point(self.start, self.end, self.error_range)
コード例 #11
0
 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)
コード例 #12
0
 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
コード例 #13
0
 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)