Classes | |
class | Sample |
nested class Sample More... | |
class | Samples |
end Sample More... | |
Public Member Functions | |
def | __init__ |
def | __repr__ |
def | Path |
def | sample |
end nested class | |
def | subsample |
def | SVG |
Public Attributes | |
attr | |
f | |
high | |
last_samples | |
loop | |
low | |
Static Public Attributes | |
dictionary | defaults = {} |
int | discontinuity_limit = 5 |
float | linearity_limit = 0.05 |
random_sampling = True | |
int | recursion_limit = 15 |
Draws a parametric function as a path. Curve(f, low, high, loop, attribute=value) f required a Python callable or string in the form "f(t), g(t)" low, high required left and right endpoints loop default=False if True, connect the endpoints attribute=value pairs keyword list SVG attributes
def svgfig::Curve::__init__ | ( | self, | |
f, | |||
low, | |||
high, | |||
loop = False , |
|||
attr | |||
) |
Reimplemented in svgfig::Rect.
def svgfig::Curve::__repr__ | ( | self | ) |
Reimplemented in svgfig::Line, svgfig::VLine, svgfig::HLine, svgfig::Rect, svgfig::Ellipse, svgfig::CurveAxis, svgfig::LineAxis, svgfig::XAxis, and svgfig::YAxis.
def svgfig::Curve::Path | ( | self, | |
trans = None , |
|||
local = False |
|||
) |
Apply the transformation "trans" and return a Path object in global coordinates. If local=True, return a Path in local coordinates (which must be transformed again).
Reimplemented in svgfig::Line, svgfig::VLine, svgfig::HLine, svgfig::Rect, and svgfig::Ellipse.
Definition at line 1653 of file svgfig.py.
01654 : 01655 """Apply the transformation "trans" and return a Path object in 01656 global coordinates. If local=True, return a Path in local coordinates 01657 (which must be transformed again).""" 01658 01659 if isinstance(trans, basestring): trans = totrans(trans) 01660 if isinstance(self.f, basestring): self.f = funcRtoR2(self.f) 01661 01662 self.sample(trans) 01663 01664 output = [] 01665 for s in self.last_samples: 01666 if s.X != None and s.Y != None: 01667 if s.left == None or s.left.Y == None: 01668 command = "M" 01669 else: 01670 command = "L" 01671 01672 if local: output.append((command, s.x, s.y, False)) 01673 else: output.append((command, s.X, s.Y, True)) 01674 01675 if self.loop: output.append(("Z",)) 01676 return Path(output, **self.attr)
def svgfig::Curve::sample | ( | self, | |
trans = None |
|||
) |
end nested class
Adaptive-sampling algorithm that chooses the best sample points for a parametric curve between two endpoints and detects discontinuities. Called by SVG().
Definition at line 1575 of file svgfig.py.
01576 : 01577 """Adaptive-sampling algorithm that chooses the best sample points 01578 for a parametric curve between two endpoints and detects 01579 discontinuities. Called by SVG().""" 01580 oldrecursionlimit = sys.getrecursionlimit() 01581 sys.setrecursionlimit(self.recursion_limit + 100) 01582 try: 01583 # the best way to keep all the information while sampling is to make a linked list 01584 if not (self.low < self.high): raise ValueError, "low must be less than high" 01585 low, high = self.Sample(float(self.low)), self.Sample(float(self.high)) 01586 low.link(None, high) 01587 high.link(low, None) 01588 01589 low.evaluate(self.f, trans) 01590 high.evaluate(self.f, trans) 01591 01592 # adaptive sampling between the low and high points 01593 self.subsample(low, high, 0, trans) 01594 01595 # Prune excess points where the curve is nearly linear 01596 left = low 01597 while left.right != None: 01598 # increment mid and right 01599 mid = left.right 01600 right = mid.right 01601 if right != None and left.X != None and left.Y != None and mid.X != None and mid.Y != None and right.X != None and right.Y != None: 01602 numer = left.X*(right.Y - mid.Y) + mid.X*(left.Y - right.Y) + right.X*(mid.Y - left.Y) 01603 denom = math.sqrt((left.X - right.X)**2 + (left.Y - right.Y)**2) 01604 if denom != 0. and abs(numer/denom) < self.linearity_limit: 01605 # drop mid (the garbage collector will get it) 01606 left.right = right 01607 right.left = left 01608 else: 01609 # increment left 01610 left = left.right 01611 else: 01612 left = left.right 01613 01614 self.last_samples = self.Samples(low, high) 01615 01616 finally: 01617 sys.setrecursionlimit(oldrecursionlimit)
def svgfig::Curve::subsample | ( | self, | |
left, | |||
right, | |||
depth, | |||
trans = None |
|||
) |
Part of the adaptive-sampling algorithm that chooses the best sample points. Called by sample().
Definition at line 1618 of file svgfig.py.
01619 : 01620 """Part of the adaptive-sampling algorithm that chooses the best 01621 sample points. Called by sample().""" 01622 01623 if self.random_sampling: 01624 mid = self.Sample(left.t + random.uniform(0.3, 0.7) * (right.t - left.t)) 01625 else: 01626 mid = self.Sample(left.t + 0.5 * (right.t - left.t)) 01627 01628 left.right = mid 01629 right.left = mid 01630 mid.link(left, right) 01631 mid.evaluate(self.f, trans) 01632 01633 # calculate the distance of closest approach of mid to the line between left and right 01634 numer = left.X*(right.Y - mid.Y) + mid.X*(left.Y - right.Y) + right.X*(mid.Y - left.Y) 01635 denom = math.sqrt((left.X - right.X)**2 + (left.Y - right.Y)**2) 01636 01637 # if we haven't sampled enough or left fails to be close enough to right, or mid fails to be linear enough... 01638 if depth < 3 or (denom == 0 and left.t != right.t) or denom > self.discontinuity_limit or (denom != 0. and abs(numer/denom) > self.linearity_limit): 01639 01640 # and we haven't sampled too many points 01641 if depth < self.recursion_limit: 01642 self.subsample(left, mid, depth+1, trans) 01643 self.subsample(mid, right, depth+1, trans) 01644 01645 else: 01646 # We've sampled many points and yet it's still not a small linear gap. 01647 # Break the line: it's a discontinuity 01648 mid.y = mid.Y = None
def svgfig::Curve::SVG | ( | self, | |
trans = None |
|||
) |
Apply the transformation "trans" and return an SVG object.
Reimplemented in svgfig::Line, svgfig::Rect, svgfig::Ellipse, svgfig::CurveAxis, svgfig::LineAxis, svgfig::XAxis, and svgfig::YAxis.
Reimplemented in svgfig::Line, svgfig::VLine, svgfig::HLine, svgfig::Rect, and svgfig::Ellipse.
dictionary svgfig::Curve::defaults = {} [static] |
Reimplemented in svgfig::Line, svgfig::VLine, svgfig::HLine, svgfig::Rect, svgfig::Ellipse, svgfig::CurveAxis, svgfig::LineAxis, svgfig::XAxis, and svgfig::YAxis.
int svgfig::Curve::discontinuity_limit = 5 [static] |
Reimplemented in svgfig::Line, svgfig::Rect, svgfig::Ellipse, and svgfig::LineAxis.
Reimplemented in svgfig::Line, svgfig::Rect, svgfig::Ellipse, and svgfig::LineAxis.
float svgfig::Curve::linearity_limit = 0.05 [static] |
Reimplemented in svgfig::Line, svgfig::Rect, and svgfig::Ellipse.
Reimplemented in svgfig::Line, svgfig::Rect, svgfig::Ellipse, and svgfig::LineAxis.
svgfig::Curve::random_sampling = True [static] |
int svgfig::Curve::recursion_limit = 15 [static] |