CMS 3D CMS Logo

Classes | Public Member Functions | Public Attributes | Static Public Attributes

svgfig::Curve Class Reference

Inheritance diagram for svgfig::Curve:
svgfig::CurveAxis svgfig::Ellipse svgfig::Line svgfig::Rect svgfig::HLine svgfig::LineAxis svgfig::VLine svgfig::XAxis svgfig::YAxis

List of all members.

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

Detailed Description

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

Definition at line 1498 of file svgfig.py.


Constructor & Destructor Documentation

def svgfig::Curve::__init__ (   self,
  f,
  low,
  high,
  loop = False,
  attr 
)

Reimplemented in svgfig::Rect.

Definition at line 1518 of file svgfig.py.

01519                                                       :
01520     self.f = f
01521     self.low = low
01522     self.high = high
01523     self.loop = loop
01524 
01525     self.attr = dict(self.defaults)
01526     self.attr.update(attr)


Member Function Documentation

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.

Definition at line 1515 of file svgfig.py.

01516                     :
01517     return "<Curve %s [%s, %s] %s>" % (self.f, self.low, self.high, self.attr)

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.

Definition at line 1649 of file svgfig.py.

01650                            :
01651     """Apply the transformation "trans" and return an SVG object."""
01652     return self.Path(trans).SVG()


Member Data Documentation

Reimplemented in svgfig::Line, svgfig::VLine, svgfig::HLine, svgfig::Rect, and svgfig::Ellipse.

Definition at line 1518 of file svgfig.py.

dictionary svgfig::Curve::defaults = {} [static]

Definition at line 1513 of file svgfig.py.

Reimplemented in svgfig::Line, svgfig::Rect, svgfig::Ellipse, and svgfig::LineAxis.

Definition at line 1518 of file svgfig.py.

Reimplemented in svgfig::Line, svgfig::Rect, svgfig::Ellipse, and svgfig::LineAxis.

Definition at line 1518 of file svgfig.py.

Definition at line 1577 of file svgfig.py.

float svgfig::Curve::linearity_limit = 0.05 [static]

Definition at line 1512 of file svgfig.py.

Reimplemented in svgfig::Line, svgfig::Rect, and svgfig::Ellipse.

Definition at line 1518 of file svgfig.py.

Reimplemented in svgfig::Line, svgfig::Rect, svgfig::Ellipse, and svgfig::LineAxis.

Definition at line 1518 of file svgfig.py.

Definition at line 1510 of file svgfig.py.

int svgfig::Curve::recursion_limit = 15 [static]

Definition at line 1511 of file svgfig.py.