-
Notifications
You must be signed in to change notification settings - Fork 2
/
curve.py
99 lines (78 loc) · 2.59 KB
/
curve.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
import numpy as np
from . import cmt
class Curve(object):
"""Base class for simple planar Jordan curves
"""
def __init__(self, positionfun=None, tangentfun=None, bounds=None ):
"""Create a curve
Parameters
----------
positionfun : function
a function from a real value (parameter) to a position (complex)
tangentfun : function
a function from a real value (parameter) to a tangent (complex)
bounds : tuple
a two element tuple that define the extents of the parameter
Examples
--------
A simple piecewise line element
>>> c = Curve(positionfun = lambda t: t + 1j,
... tangentfun = lambda t: 1.0
... bounds = (0, 1))
"""
self._positionfun = positionfun
self._tangentfun = tangentfun
self._bounds = bounds
assert(bounds is not None)
@property
def bounds(self):
return self._bounds
def boundbox(self):
"""Create a bounding box the encloses this curve
Returns
-------
out : array-like
[xmin, xmax, ymin, ymax]
"""
tmin, tmax = self._bounds
ts = np.linspace(tmin, tmax, 300)
ps = self.point(ts)
out = cmt.boundbox(ps)
return out
def plotbox(self, scale = 1.2):
"""Create a plot bounding box the encloses this curve
Returns
-------
out : array-like
[xmin, xmax, ymin, ymax]
"""
tmin, tmax = self._bounds
ts = np.linspace(tmin, tmax, 300)
ps = self.point(ts)
out = cmt.plotbox(ps, scale)
return out
def __str__(self):
return 'curve parameterized over [%s, %s]\n' % self.bounds
def isinf(self):
# False unless overridden by subclass
return False
def point(self, ts):
ts = np.asarray(ts, dtype=np.float).reshape(-1, 1)[:, 0]
# a naive solution here is fine for the moment
# anything better relies on building blocks that are not
# available yet
return self.position(ts)
def xypoint(self, t):
z = self.point(t)
return np.array([z.real, z.imag])
def position(self, ts):
ts = np.asarray(ts, dtype = np.float)
return self._positionfun(ts)
def tangent(self, ts):
ts = np.asarray(ts, dtype = np.float)
return self._tangentfun(ts)
def plot(self):
ts = np.linspace(0.0, 1.0, 200)
zs = self.point(ts)
# TODO - plot configuration
plt.plot(zs.real, zs.imag, 'k-')