def Nagon(N): """Return N-agon with side of length 1.""" side = cy2geom.LineSegment(Point(-0.5, 0), Point(0.5, 0)) angle = 2 * math.pi / N distance_to_center = 0.5 / math.tan(math.pi / N) return Path.fromList([ side.transformed( cy2geom.Translate(Point(0, -distance_to_center)) * cy2geom.Rotate(angle * i)) for i in range(N) ], stitching=Path.STITCH_DISCONTINUOUS, closed=True)
def Nagon(N): """Return N-agon with side of length 1.""" side = cy2geom.LineSegment(Point(-0.5, 0), Point(0.5, 0)) angle = 2*math.pi/N distance_to_center = 0.5 / math.tan(math.pi/N) return Path.fromList( [ side.transformed( cy2geom.Translate(Point(0, -distance_to_center))* cy2geom.Rotate(angle*i)) for i in range(N) ], stitching = Path.STITCH_DISCONTINUOUS, closed = True )
def test_path(self): a = Path() a.append_curve(CubicBezier(Point(-7, -3), Point(2, 8), Point(2, 1), Point(-2, 0))) self.assertEqual(a.size(), 1) self.assertFalse(a.closed()) self.path(a) a.close(True) self.assertTrue(a.closed()) self.path(a) a.close(False) a.append_curve(LineSegment(a.final_point(), Point(3, 5))) self.assertEqual(a.size(), 2) self.path(a) a.append_SBasis(SBasis(3, 6) * SBasis(1, 0), SBasis(5, 2)) self.path(a) a.append_curve(EllipticalArc(Point(), 1, 2, math.pi / 6, True, True, Point(1, 1)), Path.STITCH_DISCONTINUOUS) # Stitching adds new segment self.assertEqual(a.size(), 5) b = Path() for c in a: b.append_curve(c) # TODO: This fails with STITCH_DISCONTINUOUS, but also does so in C++, so # it's either correct behaviour or bug in 2geom # ~ self.path(b) b.insert(2, LineSegment(b[2 - 1](1), b[2](0))) # , Path.STITCH_DISCONTINUOUS) self.curves_equal(LineSegment(b[2 - 1](1), b[2](0)), b[2]) # TODO! fails on root finding # self.path(b) b.set_initial(a[2](1)) b.set_final(a[3](0)) a.insert_slice(3, b, 0, b.size()) self.assertEqual(a.size(), b.size() * 2 - 1) for i in range(b.size()): self.curves_equal(a[3 + i], b[i]) # Looks like bug: # A = Path() # A.append_curve( CubicBezier( Point(-7, -3), Point(2, 8), Point(2, 1), Point(-2, 0) ) ) # A.append_curve(EllipticalArc(Point(), 1, 2, math.pi/6, True, True, Point(1, 1)), Path.STITCH_DISCONTINUOUS) # print A.roots(0, 1) # Roots are [1.0, 2.768305708350847, 3.25], Point at second root is # Point (2.32, -0.48) # and third root is > 3 - it corresponds to root on closing segment, but A is open, # and computing A(3.25) results in RangeError - this might be bug or feature. self.path(a.portion(0.232, 3.12)) self.path(a.portion(interval=Interval(0.1, 4.7))) self.path(a.portion(0.232, 3.12).reverse()) b.clear() self.assertTrue(b.empty()) aa = Path() for c in a: aa.append_curve(c) a.erase(0) self.assertEqual(a.size(), aa.size() - 1) self.assertAlmostEqual(a(0), aa(1)) a.erase_last() self.assertEqual(a.size(), aa.size() - 2) self.assertAlmostEqual(a.final_point(), aa[aa.size() - 2](1)) a.replace(3, QuadraticBezier(a(3), Point(), a(4))) self.assertEqual(a.size(), aa.size() - 2) cs = [ LineSegment(Point(-0.5, 0), Point(0.5, 0)).transformed( Rotate(-math.pi / 3 * i) * Translate(Point(0, math.sqrt(3) / 2) * Rotate(-math.pi / 3 * i)) ) for i in range(6) ] hexagon = Path.fromList(cs, stitching=Path.STITCH_DISCONTINUOUS, closed=True) if draw: utils.draw(hexagon, scale=100) # to = 5 because each corner contains one stitching segment half_hexagon = Path.fromPath(hexagon, fr=0, to=5) if draw: utils.draw(half_hexagon, scale=100) half_hexagon.replace_slice(1, 5, LineSegment(half_hexagon(1), half_hexagon(5))) self.assertEqual(half_hexagon.size(), 2) self.assertAlmostEqual(half_hexagon(1.5), Point(0.5, 0)) half_hexagon.stitch_to(half_hexagon(0)) self.assertAlmostEqual(half_hexagon(2.5), Point()) a.start(Point(2, 2)) a.append_SBasis(SBasis(2, 6), SBasis(1, 5) * SBasis(2, 9)) self.assertAlmostEqual(a(1), Point(6, 5 * 9)) l = Path.fromList([QuadraticBezier(Point(6, 5 * 9), Point(1, 2), Point(-2, 0.21))]) a.append_path(l) self.assertAlmostEqual(a.final_point(), l.final_point()) k = Path.fromList([QuadraticBezier(Point(), Point(2, 1), Point(-2, 0.21)).reverse()]) k.append_portion_to(l, 0, 0.3) self.assertAlmostEqual(l.final_point(), k(0.3))
def test_path(self): a = Path() a.append_curve( CubicBezier(Point(-7, -3), Point(2, 8), Point(2, 1), Point(-2, 0))) self.assertEqual(a.size(), 1) self.assertFalse(a.closed()) self.path(a) a.close(True) self.assertTrue(a.closed()) self.path(a) a.close(False) a.append_curve(LineSegment(a.final_point(), Point(3, 5))) self.assertEqual(a.size(), 2) self.path(a) a.append_SBasis(SBasis(3, 6) * SBasis(1, 0), SBasis(5, 2)) self.path(a) a.append_curve( EllipticalArc(Point(), 1, 2, math.pi / 6, True, True, Point(1, 1)), Path.STITCH_DISCONTINUOUS) #Stitching adds new segment self.assertEqual(a.size(), 5) b = Path() for c in a: b.append_curve(c) #TODO: This fails with STITCH_DISCONTINUOUS, but also does so in C++, so #it's either correct behaviour or bug in 2geom #~ self.path(b) b.insert(2, LineSegment(b[2 - 1](1), b[2](0))) #, Path.STITCH_DISCONTINUOUS) self.curves_equal(LineSegment(b[2 - 1](1), b[2](0)), b[2]) #TODO! fails on root finding #self.path(b) b.set_initial(a[2](1)) b.set_final(a[3](0)) a.insert_slice(3, b, 0, b.size()) self.assertEqual(a.size(), b.size() * 2 - 1) for i in range(b.size()): self.curves_equal(a[3 + i], b[i]) #Looks like bug: # A = Path() # A.append_curve( CubicBezier( Point(-7, -3), Point(2, 8), Point(2, 1), Point(-2, 0) ) ) # A.append_curve(EllipticalArc(Point(), 1, 2, math.pi/6, True, True, Point(1, 1)), Path.STITCH_DISCONTINUOUS) # print A.roots(0, 1) #Roots are [1.0, 2.768305708350847, 3.25], Point at second root is #Point (2.32, -0.48) #and third root is > 3 - it corresponds to root on closing segment, but A is open, #and computing A(3.25) results in RangeError - this might be bug or feature. self.path(a.portion(0.232, 3.12)) self.path(a.portion(interval=Interval(0.1, 4.7))) self.path(a.portion(0.232, 3.12).reverse()) b.clear() self.assertTrue(b.empty()) aa = Path() for c in a: aa.append_curve(c) a.erase(0) self.assertEqual(a.size(), aa.size() - 1) self.assertAlmostEqual(a(0), aa(1)) a.erase_last() self.assertEqual(a.size(), aa.size() - 2) self.assertAlmostEqual(a.final_point(), aa[aa.size() - 2](1)) a.replace(3, QuadraticBezier(a(3), Point(), a(4))) self.assertEqual(a.size(), aa.size() - 2) cs = [ LineSegment(Point(-0.5, 0), Point(0.5, 0)).transformed( Rotate(-math.pi / 3 * i) * Translate( Point(0, math.sqrt(3) / 2) * Rotate(-math.pi / 3 * i))) for i in range(6) ] hexagon = Path.fromList(cs, stitching=Path.STITCH_DISCONTINUOUS, closed=True) if draw: utils.draw(hexagon, scale=100) #to = 5 because each corner contains one stitching segment half_hexagon = Path.fromPath(hexagon, fr=0, to=5) if draw: utils.draw(half_hexagon, scale=100) half_hexagon.replace_slice( 1, 5, LineSegment(half_hexagon(1), half_hexagon(5))) self.assertEqual(half_hexagon.size(), 2) self.assertAlmostEqual(half_hexagon(1.5), Point(0.5, 0)) half_hexagon.stitch_to(half_hexagon(0)) self.assertAlmostEqual(half_hexagon(2.5), Point()) a.start(Point(2, 2)) a.append_SBasis(SBasis(2, 6), SBasis(1, 5) * SBasis(2, 9)) self.assertAlmostEqual(a(1), Point(6, 5 * 9)) l = Path.fromList( [QuadraticBezier(Point(6, 5 * 9), Point(1, 2), Point(-2, .21))]) a.append_path(l) self.assertAlmostEqual(a.final_point(), l.final_point()) k = Path.fromList( [QuadraticBezier(Point(), Point(2, 1), Point(-2, .21)).reverse()]) k.append_portion_to(l, 0, 0.3) self.assertAlmostEqual(l.final_point(), k(0.3))