2 # Copyright (c) 2003 Art Haas
4 # This file is part of PythonCAD.
6 # PythonCAD is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 of the License, or
9 # (at your option) any later version.
11 # PythonCAD is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with PythonCAD; if not, write to the Free Software
18 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 def __init__(self
, ctrlpts
, knots
, order
):
27 if not isinstance(ctrlpts
, list):
28 raise TypeError, "Invalid control point list: " + str(ctrlpts
)
29 if not isinstance(knots
, list):
30 raise TypeError, "Invalid knot list: " + str(knots
)
31 if not isinstance(order
, int):
32 raise TypeError, "Invalid order; " + str(order
)
33 if order
< 2 or order
> 16: # what is a good max value?
34 raise ValueError, "Invalid order: %d" % order
37 if not isinstance(_pt
, tuple):
38 raise TypeError, "Invalid control point: " + str(_pt
)
40 if not (1 < _len
< 4):
41 raise ValueError, "Invalid tuple length: " + str(_pt
)
47 if not isinstance(_x
, float):
49 if not isinstance(_y
, float):
51 if not isinstance(_w
, float):
54 raise ValueError, "Invalid weight: %g" % _w
55 _ctrlpts
.append((_x
, _y
, _w
))
58 if not isinstance(_knot
, float):
60 if (_knot
< 0.0 or _knot
> 1.0):
61 raise ValueError, "Invalid knot value: %g" % _knot
63 if _knot
< (_val
- 1e-10):
64 raise (ValueError, "Invalid decreasing knot: %g < %g" %
67 print "knots: " + str(_knots
)
68 print "ctrl: " + str(_ctrlpts
)
69 print "order: %d" % order
72 raise ValueError, "Order greater than number of control points."
73 if len(_knots
) != (_clen
+ order
):
74 raise ValueError, "Knot/Control Point/Order number error."
75 self
.__ctrlpts
= _ctrlpts
79 def getControlPoints(self
):
80 return self
.__ctrlpts
[:]
83 return self
.__knots
[:]
88 def calculate(self
, count
):
89 if not isinstance(count
, int):
90 raise TypeError, "Invalid count: " + str(count
)
91 _cpts
= self
.__ctrlpts
93 _dt
= 1.0/float(count
)
96 for _c
in range(count
):
98 # print "time: %g" % _t
100 for _i
in range(len(_cpts
)):
101 # print "using cpt %d" % _i
102 _x
, _y
, _w
= _cpts
[_i
]
103 _Ni
= self
._N
(_i
, _p
, _t
)
104 _nx
= _nx
+ (_Ni
* _x
)
105 _ny
= _ny
+ (_Ni
* _y
)
106 _nw
= _nw
+ (_Ni
* _w
)
107 # print "nw: %.3f" % _nw
108 # print "nx: %.3f" % _nx
109 # print "ny: %.3f" % _ny
111 _pts
.append((_nx
/_nw
, _ny
/_nw
))
113 print "zero weight: %f, %f" % (_nx
, _ny
)
117 def _N(self
, i
, p
, t
):
120 if abs(t
- 1.0) < 1e-10 and False:
126 _knots
= self
.__knots
130 print "ki: %.3f" % _ki
131 print "kin: %.3f" % _kin
133 if ((_ki
- 1e-10) < t
< _kin
):
139 _kipn
= _knots
[i
+ p
+ 1]
141 print "kip: %.3f" % _kip
142 print "kipn: %.3f" % _kipn
148 _t1
= (_v2
/_v1
) * self
._N
(i
, (p
- 1), t
)
154 _t2
= (_v2
/_v1
) * self
._N
((i
+ 1), (p
- 1), t
)
157 print "val: %f" % _val
160 def writedata(self
, count
, fname
):
161 if not isinstance(count
, int):
162 raise TypeError, "Invalid count: " + str(count
)
163 _f
= file(fname
, "w")
164 for _pt
in self
.calculate(count
):
166 _f
.write("%f %f\n" % (_x
, _y
))
168 _f
= file('control_points', "w")
169 for _pt
in self
.getControlPoints():
170 _x
, _y
, _w
= _pt
# ignore weight
171 _f
.write("%f %f\n" % (_x
, _y
))
173 _f
= file('knots', "w")
174 for _knot
in self
.getKnots():
175 _f
.write("%f 0.0\n" % _knot
)
178 def _NN(self
, i
, p
, t
):
179 _cpts
= self
.__ctrlpts
181 _knots
= self
.__knots
182 _kl
= len(_knots
) - 1
185 # calculate values for 0
187 for _i
in range(_kl
):
188 if ((_knots
[i
] - 1e-10) < t
< _knots
[i
+ 1]):
191 # calculate values up to the degree
193 for _j
in range(1, (p
+ 1)):
194 for _i
in range(_kl
- _j
):
196 _kin
= _knots
[_i
+ 1]
197 _kip
= _knots
[_i
+ p
]
198 _kipn
= _knots
[_i
+ p
+ 1]