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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
|
package demos.nurbs.curveapp;
import java.io.File;
import java.util.Vector;
import simple.xml.Element;
import simple.xml.ElementList;
import simple.xml.Root;
import simple.xml.Serializer;
import simple.xml.load.Persister;
/**
* Třída definice NURBS křivky, vystavěna podle návrhového vzoru Singleton
* @author Tomáš Hráský
*
*/
@Root(name="curve")
public class Curve
{
/**
* Odkaz na instanci třídy
*/
private static Curve singleton;
/**
* Indikuje, zda je zadání křivky kompletní
*/
@Element(name="finished")
private boolean isCurveFinished;
/**
* Index aktuálního vybraného řídícího bodu
*/
private int bodIndex = -1;
/**
* Stupeň křivky
*/
@Element(name="order")
private int order=3;
/**
* Pole souřadnic řídícíh bodů
*
*/
private float[] ctrlPoints;
/**
* Pole hodnot uzlového vektoru
*/
private float knots[];
/**
* Kolekce vektor pro persistenci souřadnic řídících bodů
*/
@ElementList(name="ctrlpoints",type=MyFloat.class)
private Vector<MyFloat> ctrlVector;
/**
* Kolekce vektor pro persistenci uzlového vektoru
*/
@ElementList(name="knots",type=MyFloat.class)
private Vector<MyFloat> knotVector;
/**
* Vytvoří prázdnou definici křivky
*/
public void clear(){
isCurveFinished=false;
ctrlPoints=new float[0];
knots=new float[0];
order=3;
}
/**
* Pomocí framweorku Simple serializuje definici křivky do XML souboru
* @param f soubor pro uložení
*/
public void persist(File f){
ctrlVector=new Vector<MyFloat>(ctrlPoints.length);
knotVector=new Vector<MyFloat>(knots.length);
for(Float ff:ctrlPoints)
ctrlVector.add(new MyFloat(ff));
for(Float ff:knots)
knotVector.add(new MyFloat(ff));
Serializer s=new Persister();
try {
System.out.println("ukládám");
s.write(Curve.getInstance(),f);
} catch (Exception e1) {
e1.printStackTrace();
}
}
/**
* Vytvoří pomocí frameworku Simple křivku z definice uložené v XML souboru
* @param f soubor,z něhož se má definice načíst
* @throws Exception chyba při čtení ze souboru
*/
public void unPersist(File f) throws Exception{
Serializer s=new Persister();
Curve c=s.read(Curve.class,f);
initFromCurve(c);
}
/**
* Inicializuje objekt podle jiného objektu typu Curve
* @param c referenční objekt - křivka
*/
private void initFromCurve(Curve c) {
this.order=c.getOrder();
this.ctrlPoints=new float[c.getCtrlVector().size()];
this.knots=new float[c.getKnotVector().size()];
int i=0;
for(MyFloat f:c.getCtrlVector())
ctrlPoints[i++]=f.getValue();
i=0;
for(MyFloat f:c.getKnotVector())
knots[i++]=f.getValue();
this.isCurveFinished=c.isCurveFinished();
}
/**
* Konstruktor, nastaví prázdné hodnoty polí definujících NURBS křivku
*/
private Curve(){
ctrlPoints=new float[0];
knots=new float[0];
isCurveFinished=false;
}
/**
* Vrací instanci třídy (podle návrhového vzoru Singleton)
* @return instance třídy Curve
*/
public static Curve getInstance() {
if (singleton == null)
singleton = new Curve();
return singleton;
}
/**
* Vrací pole uzlového vektoru
* @return pole hodnot uzlového vektoru
*/
public float[] getKnots() {
return this.knots;
}
/**
* Vrací pole s hodnotami souřadnic řídících bodů
* @return pole souřadnic řídících bodů
*/
public float[] getCtrlPoints() {
return this.ctrlPoints;
}
/**
* Vrací stupeň NURBS křivky
* @return stupeň NURBS křivky
*/
public int getOrder() {
return this.order;
}
/**
* Vrací index aktuálně vybraného řídícího bodu
* @return index aktuálně vybraného řídícího bodu
*/
public int getBodIndex() {
return bodIndex;
}
/**
* Nastavuje index požadovaného aktuálně vybraného řídícího bodu
* @param bodIndex index požadovaného aktuálně vybraného řídícího bodu
*/
public void setBodIndex(int bodIndex) {
this.bodIndex = bodIndex;
}
/**
* Vrací X-ovou souadnici aktuálně vybraného řídícího bodu, přepočítává hodnotu z homogenních souřadnic
* @return X-ová souadnice aktuálně vybraného řídícího bodu
*/
public float getActiveX(){
if(bodIndex>=0){
return ctrlPoints[bodIndex*4]/ctrlPoints[bodIndex*4+3];
}
else return 0;
}
/**
* Vrací Y-ovou souadnici aktuálně vybraného řídícího bodu, přepočítává hodnotu z homogenních souřadnic
* @return Y-ová souadnice aktuálně vybraného řídícího bodu
*/
public float getActiveY(){
if(bodIndex>=0){
return ctrlPoints[bodIndex*4+1]/ctrlPoints[bodIndex*4+3];
}
else return 0;
}
/**
* Vrací váhu aktuálně vybraného řídícího bodu
* @return váha aktuálně vybraného řídícího bodu
*/
public float getActiveW(){
if(bodIndex>=0){
return ctrlPoints[bodIndex*4+3];
}
else return 0;
}
/**
* Nastavuje X-ovou souadnici aktuálně vybraného řídícího bodu, přepočítává hodnotu do homogenních souřadnic
* @param x X-ová souřadnice aktuálně vybraného řídícího bodu
*/
public void setActiveX(float x){
if(bodIndex>=0){
ctrlPoints[bodIndex*4]=x*ctrlPoints[bodIndex*4+3];
}
}
/**
* Nastavuje Y-ovou souadnici aktuálně vybraného řídícího bodu, přepočítává hodnotu do homogenních souřadnic
* @param y Y-ová souřadnice aktuálně vybraného řídícího bodu
*/
public void setActiveY(float y){
if(bodIndex>=0){
ctrlPoints[bodIndex*4+1]=y*ctrlPoints[bodIndex*4+3];
}
}
/**
*Nastavuje váhu aktuálně vybraného řídícího bodu, upravuje hodnoty stávajícíh souřadic vzhledem k váze a použití homogenních souřadnic
* @param w váha aktuálně vybraného řídícího bodu
*/
public void setActiveW(float w){
if(bodIndex>=0){
float oldW=ctrlPoints[bodIndex*4+3];
if(w>0){
ctrlPoints[bodIndex*4+3]=w;
//úprava souřadnic
ctrlPoints[bodIndex*4]=ctrlPoints[bodIndex*4]/oldW*w;
ctrlPoints[bodIndex*4+1]=ctrlPoints[bodIndex*4+1]/oldW*w;
}
}
}
/**
* Nastavuje uzlový vektor
* @param knots nový uzlový vektor
*/
public void setKnots(float[] knots) {
this.knots = knots;
}
/**
* Vrací informaci o stavu dokončení definice křvky
* @return true pokud je definice křivky kompletní, jinak false
*/
public boolean isCurveFinished() {
return isCurveFinished;
}
/**
* Nastavuje řídící body
* @param ctrlPoints pole souřadnic řídících bodů
*/
public void setCtrlPoints(float[] ctrlPoints) {
this.ctrlPoints = ctrlPoints;
}
/**
* Nastavuje stav dokončení definice křivky
* @param b stav dokončení definice křivky
*
*/
public void setIsCurveFinished(boolean b) {
isCurveFinished=b;
}
/**
* Vrací vektor souřadnic řídích bodů pro serializaci
* @return vektor souřadnic řídících bodů
*/
private Vector<MyFloat> getCtrlVector() {
return ctrlVector;
}
/**
* Vrací vektor prvků uzlového vektoru pro serializaci
* @return vektor prvků uzlového vektoru
*/
private Vector<MyFloat> getKnotVector() {
return knotVector;
}
/**
* Nastaví stupeň křivky
* @param order požadovaný stupeň
*/
public void setOrder(int order) {
this.order = order;
}
}
|