示例#1
0
 def test_segment_maths(self):
     """Segments have calculations"""
     self.assertEqual(DirectedLineSegment((0, 0), (10, 0)).angle, 0)
     self.assertAlmostEqual(DirectedLineSegment((0, 0),
                                                (0.5 * sqrt(3), 0.5)).angle,
                            pi / 6,
                            delta=1e-6)
示例#2
0
 def transform_point(tbox, bbox, x, y):
     """Transform algorithm thanks to Jose Hevia (freon)"""
     vector = (x, y) - bbox.minimum
     xratio, yratio = map(truediv, vector, (bbox.width, bbox.height))
     horz = DirectedLineSegment(tbox[0].point_at_ratio(xratio), tbox[2].point_at_ratio(xratio))
     vert = DirectedLineSegment(tbox[3].point_at_ratio(yratio), tbox[1].point_at_ratio(yratio))
     denom = horz.vector.cross(vert.vector)
     if denom == 0.0:
         # Degenerate cases of intersecting envelope edges
         if horz.length == 0.0:
             return horz.start
         if vert.length == 0.0:
             return vert.start
         # Here we should know that the lines share a start or end point.
         if horz.vector.dot(vert.vector) < 0:
             # Segments point opposite directions
             if (horz.start - vert.start).length <= 1e-8:
                 return horz.start
             return horz.end
         # Otherwise they are pointing the same direction
         if (horz.start - vert.end).length < 1e-8:
             return horz.start
         return horz.end
     # If we didn't hit a degenerate case we can treat the segments as infinite lines
     intersect_ratio = (vert.start - horz.start).cross(vert.vector) / denom
     return horz.point_at_ratio(intersect_ratio)
示例#3
0
 def envelope_box_from_path(self, envelope_path):
     if len(envelope_path) < 1 or len(envelope_path[0]) < 4:
         raise inkex.AbortExtension(_("Second selected path is too short. Must be four or more nodes."))
     trafo = [[(csp[1][0], csp[1][1]) for csp in subs] for subs in envelope_path][0][:4]
     #vectors pointing away from the trafo origin
     tbox = [
         DirectedLineSegment(trafo[0], trafo[1]),
         DirectedLineSegment(trafo[1], trafo[2]),
         DirectedLineSegment(trafo[3], trafo[2]),
         DirectedLineSegment(trafo[0], trafo[3]),
     ]
     vects = [segment.vector for segment in tbox]
     if 0.0 == vects[0].cross(vects[1]) == vects[1].cross(vects[2]) == vects[2].cross(vects[3]):
         raise inkex.AbortExtension(_("The points for the selected envelope must not all be in a line."))
     return tbox
示例#4
0
 def test_segment_dy(self):
     """Test segment dy calculation"""
     self.assertEqual(DirectedLineSegment((0, 0), (0, 0)).dy, 0)
     self.assertEqual(DirectedLineSegment((0, 0), (3, 0)).dy, 0)
     self.assertEqual(DirectedLineSegment((0, 0), (0, 3)).dy, 3)
     self.assertEqual(DirectedLineSegment((0, 0), (0, -3)).dy, -3)
     self.assertEqual(DirectedLineSegment((0, 5), (0, 1)).dy, -4)
     self.assertEqual(DirectedLineSegment((0, -3), (0, 1)).dy, 4)
示例#5
0
 def test_segment_dx(self):
     """Test segment dx calculation"""
     self.assertEqual(DirectedLineSegment((0, 0), (0, 0)).dx, 0)
     self.assertEqual(DirectedLineSegment((0, 0), (0, 3)).dx, 0)
     self.assertEqual(DirectedLineSegment((0, 0), (3, 0)).dx, 3)
     self.assertEqual(DirectedLineSegment((0, 0), (-3, 0)).dx, -3)
     self.assertEqual(DirectedLineSegment((5, 0), (1, 0)).dx, -4)
     self.assertEqual(DirectedLineSegment((-3, 0), (1, 0)).dx, 4)
示例#6
0
 def test_segment_angle(self):
     """Test segment angle calculation"""
     self.assertEqual(DirectedLineSegment((0, 0), (3, 0)).angle, 0)
     self.assertEqual(DirectedLineSegment((0, 0), (-3, 0)).angle, pi)
     self.assertEqual(DirectedLineSegment((0, 0), (0, 5)).angle, pi / 2)
     self.assertEqual(DirectedLineSegment((0, 0), (0, -5)).angle, -pi / 2)
     self.assertEqual(DirectedLineSegment((2, 0), (0, 0)).angle, pi)
     self.assertEqual(DirectedLineSegment((-2, 0), (0, 0)).angle, 0)
     self.assertEqual(DirectedLineSegment((0, 4), (0, 0)).angle, -pi / 2)
     self.assertEqual(DirectedLineSegment((0, -4), (0, 0)).angle, pi / 2)
     self.assertEqual(DirectedLineSegment((0, 0), (1, 1)).angle, pi / 4)
     self.assertEqual(
         DirectedLineSegment((0, 0), (-1, 1)).angle, 3 * pi / 4)
     self.assertEqual(
         DirectedLineSegment((0, 0), (-1, -1)).angle, -3 * pi / 4)
     self.assertEqual(DirectedLineSegment((0, 0), (1, -1)).angle, -pi / 4)
示例#7
0
 def test_segment_length(self):
     """Test segment length calculation"""
     self.assertEqual(DirectedLineSegment((0, 0), (0, 0)).length, 0)
     self.assertEqual(DirectedLineSegment((0, 0), (3, 0)).length, 3)
     self.assertEqual(DirectedLineSegment((0, 0), (-3, 0)).length, 3)
     self.assertEqual(DirectedLineSegment((0, 0), (0, 5)).length, 5)
     self.assertEqual(DirectedLineSegment((0, 0), (0, -5)).length, 5)
     self.assertEqual(DirectedLineSegment((2, 0), (0, 0)).length, 2)
     self.assertEqual(DirectedLineSegment((-2, 0), (0, 0)).length, 2)
     self.assertEqual(DirectedLineSegment((0, 4), (0, 0)).length, 4)
     self.assertEqual(DirectedLineSegment((0, -4), (0, 0)).length, 4)
     self.assertEqual(DirectedLineSegment((0, 0), (3, 4)).length, 5)
     self.assertEqual(DirectedLineSegment((-3, -4), (0, 0)).length, 5)
示例#8
0
 def test_segment_vector(self):
     """Test segment delta vector"""
     self.assertEqual(
         DirectedLineSegment((0, 0), (2, 3)).vector.to_tuple(), (2, 3))
     self.assertEqual(
         DirectedLineSegment((-2, -3), (2, 3)).vector.to_tuple(), (4, 6))
示例#9
0
 def test_segment_creation(self):
     """Test segments"""
     self.assertEqual(DirectedLineSegment((1, 2), (3, 4)), (1, 3, 2, 4))
     self.assertEqual(repr(DirectedLineSegment((1, 2), (3, 4))),
                      'DirectedLineSegment((1, 2), (3, 4))')
示例#10
0
 def processOffset(self, cmd, point, pen, speed, force):
     """ Calculate offset correction """
     if self.toolOffset == 0.0 or self.dryRun:
         self.storePoint(cmd, point, pen, speed, force)
     else:
         # insert data into cache
         self.vData.pop(0)
         self.vData.insert(3, [cmd, point, pen, speed, force])
         # decide if enough data is available
         if self.vData[2][1] != 'False':
             if self.vData[1][1] == 'False':
                 self.storePoint(self.vData[2][0], self.vData[2][1],
                                 self.vData[2][2], self.vData[2][3],
                                 self.vData[2][4])
             else:
                 # perform tool offset correction (It's a *tad* complicated, if you want
                 #                     to understand it draw the data as lines on paper)
                 if self.vData[2][0] == 'PD':
                     # If the 3rd entry in the cache is a pen down command,
                     #             make the line longer by the tool offset
                     pointThree = self.changeLength(self.vData[1][1],
                                                    self.vData[2][1],
                                                    self.toolOffset)
                     self.storePoint('PD', pointThree, self.vData[2][2],
                                     self.vData[2][3], self.vData[2][4])
                 elif self.vData[0][1] != 'False':
                     # Elif the 1st entry in the cache is filled with data and the 3rd entry
                     #   is a pen up command shift the 3rd entry by the current tool offset
                     #   position according to the 2nd command
                     pointThree = self.changeLength(self.vData[0][1],
                                                    self.vData[1][1],
                                                    self.toolOffset)
                     pointThree = self.vData[2][1] - (self.vData[1][1] -
                                                      pointThree)
                     self.storePoint('PU', pointThree, self.vData[2][2],
                                     self.vData[2][3], self.vData[2][4])
                 else:
                     # Else just write the 3rd entry
                     pointThree = self.vData[2][1]
                     self.storePoint('PU', pointThree, self.vData[2][2],
                                     self.vData[2][3], self.vData[2][4])
                 if self.vData[3][0] == 'PD':
                     # If the 4th entry in the cache is a pen down command guide tool to next
                     #           line with a circle between the prolonged 3rd and 4th entry
                     originalSegment = DirectedLineSegment(
                         self.vData[2][1], self.vData[3][1])
                     if originalSegment.length >= self.toolOffset:
                         pointFour = self.changeLength(originalSegment.end,\
                                                     originalSegment.start, - self.toolOffset)
                     else:
                         pointFour = self.changeLength(originalSegment.start,\
                                 originalSegment.end, self.toolOffset - originalSegment.length)
                     # get angle start and angle vector
                     angleStart = DirectedLineSegment(
                         self.vData[2][1], pointThree).angle
                     angleVector = DirectedLineSegment(self.vData[2][1], pointFour).angle\
                                                                                 - angleStart
                     # switch direction when arc is bigger than 180°
                     if angleVector > math.pi:
                         angleVector -= math.pi * 2
                     elif angleVector < -math.pi:
                         angleVector += math.pi * 2
                     # draw arc
                     if angleVector >= 0:
                         angle = angleStart + self.toolOffsetFlat
                         while angle < angleStart + angleVector:
                             self.storePoint('PD', self.vData[2][1] + self.toolOffset *\
                                 Vector2d(math.cos(angle), math.sin(angle)), self.vData[2][2], self.vData[2][3], self.vData[2][4])
                             angle += self.toolOffsetFlat
                     else:
                         angle = angleStart - self.toolOffsetFlat
                         while angle > angleStart + angleVector:
                             self.storePoint('PD', self.vData[2][1] + self.toolOffset *\
                                 Vector2d(math.cos(angle), math.sin(angle)), self.vData[2][2], self.vData[2][3], self.vData[2][4])
                             angle -= self.toolOffsetFlat
                     self.storePoint('PD', pointFour, self.vData[3][2],
                                     self.vData[2][3], self.vData[2][4])
示例#11
0
 def changeLength(self, p1, p2, offset):
     """change length of line"""
     if p1.x == p2.x and p1.y == p2.y:  # abort if points are the same
         return p1
     return Vector2d(DirectedLineSegment(p2, p1).point_at_length(-offset))