-
Notifications
You must be signed in to change notification settings - Fork 34
/
Copy pathIFoldableStrip.java
177 lines (149 loc) · 5.62 KB
/
IFoldableStrip.java
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
/*---
iGeo - http://igeo.jp
Copyright (c) 2002-2013 Satoru Sugihara
This file is part of iGeo.
iGeo is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, version 3.
iGeo is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with iGeo. If not, see <http://www.gnu.org/licenses/>.
---*/
package igeo;
import java.util.ArrayList;
/**
Class of foldable geometry.
@author Satoru Sugihara
*/
public class IFoldableStrip implements IFoldable{
public ArrayList<IVecI[]> pts;
public ArrayList<ITransformable> faces;
public IFoldableStrip(IVecI[][] foldLinePts){
setFold(foldLinePts);
}
public IFoldableStrip(ArrayList<IVecI[]> foldLinePts){
setFold(foldLinePts);
}
public IFoldableStrip setFold(IVecI[][] foldLinePts){
if(foldLinePts==null){ IOut.err("fold line points are null"); return this; }
for(int i=0; i<foldLinePts.length; i++){
if(foldLinePts[i].length!=2){
IOut.err("number of fold line points needs to be 2 (at ["+i+"].length="+foldLinePts[i].length+")");
return this;
}
}
pts = new ArrayList<IVecI[]>();
for(int i=0; i<foldLinePts.length; i++) pts.add(foldLinePts[i]);
return this;
}
public IFoldableStrip setFold(ArrayList<IVecI[]> foldLinePts){
if(foldLinePts==null){ IOut.err("fold line points are null"); return this; }
for(int i=0; i<foldLinePts.size(); i++){
if(foldLinePts.get(i).length!=2){
IOut.err("number of fold line points needs to be 2 (at ["+i+"].length="+foldLinePts.get(i).length+")");
return this;
}
}
pts = foldLinePts;
return this;
}
public IFoldableStrip addFold(IVecI linePt1, IVecI linePt2){
return addFold(new IVecI[]{ linePt1, linePt2 });
}
public IFoldableStrip addFold(IVecI[] linePts){
if(linePts==null){ IOut.err("fold line points are null"); return this; }
if(linePts.length!=2){ IOut.err("number of fold line points needs to be 2 ("+linePts.length+")"); return this; }
pts.add(linePts);
return this;
}
public IFoldableStrip add(IVecI v){
if(pts==null) return this;
for(int i=0; i<pts.size(); i++){
pts.get(i)[0].add(v);
pts.get(i)[1].add(v);
}
return this;
}
public IFoldableStrip rot(IVecI axis, double angle){
if(pts==null) return this;
for(int i=0; i<pts.size(); i++){
pts.get(i)[0].rot(axis,angle);
pts.get(i)[1].rot(axis,angle);
}
return this;
}
/** unfold at the location of the first face on its plane normal. */
public IFoldableStrip unfold(){
IVecI n0 = nml(0);
for(int i=1; i<pts.size()-1; i++){
IVecI n = nml(i);
IVecI center = pts.get(i)[0];
IVecI axis = pts.get(i)[1].dif(center);
double angle = n.angle(n0, axis);
IG.p("unfold angle = "+angle); //
fold(i, angle);
}
return this;
}
/** unfold at the location of the first face on the specified plane normal. */
public IFoldableStrip unfold(IVecI planeNormal){ return unfold(planeNormal,null); }
/** unfold at the location of the first face on the specified plane normal. */
public IFoldableStrip unfold(IVecI planeNormal, IVecI stripTangent){
// orient first face
IVecI n = nml(0);
IVecI axis = n.cross(planeNormal);
double angle = n.angle(planeNormal,axis);
rot(axis,angle);
if(pts.size()>0 && stripTangent!=null){
// orient tangent dir
IVecI t = pts.get(1)[0].dif(pts.get(0)[0]);
if(t.len()<IConfig.tolerance){ t = pts.get(1)[1].dif(pts.get(0)[1]); }
double tangle = t.angle(stripTangent, planeNormal);
rot(planeNormal, tangle);
}
return unfold();
}
/** unfold at the specified point on the the specified plane normal */
//public IFoldableStrip unfold(IVecI planePt, IVecI planeNormal){} //
/** unfold at the specified point on the the specified plane normal */
public IFoldableStrip unfold(IVecI planePt, IVecI planeNormal, IVecI stripTangent){
if(pts==null||pts.size()==0){ IOut.err("fold line points are null"); return this; }
IVecI dif = planePt.dif(pts.get(0)[0]);
for(int i=0; i<pts.size(); i++){
pts.get(i)[0].add(dif);
pts.get(i)[1].add(dif);
}
return unfold(planeNormal, stripTangent);
}
public IFoldableStrip fold(int foldLineIndex, double angle){
if(pts==null){ IOut.err("fold line points are null"); return this; }
if(foldLineIndex<0 || foldLineIndex>=pts.size()-1){
IOut.err("invalid index("+foldLineIndex+") for "+pts.size()+" folding lines");
return null;
}
//IVec n = nml(foldLineIndex);
IVecI center = pts.get(foldLineIndex)[0];
IVecI axis = pts.get(foldLineIndex)[1].dif(center);
for(int i=foldLineIndex+1; i<pts.size(); i++){
pts.get(i)[0].rot(center, axis, angle);
pts.get(i)[1].rot(center, axis, angle);
}
return this;
}
/* get a normal vector of specified face at foldinLineIndex */
public IVecI nml(int foldLineIndex){
if(foldLineIndex<0 || foldLineIndex>=pts.size()-1){
IOut.err("invalid index("+foldLineIndex+") for "+pts.size()+" folding lines");
return null;
}
if(pts.get(foldLineIndex)[0].eq(pts.get(foldLineIndex+1)[0])){
// [0][0], [0][1], [1][1]
return pts.get(foldLineIndex)[0].nml(pts.get(foldLineIndex)[1], pts.get(foldLineIndex+1)[1]);
}
// [0][0], [0][1], [1][0]
return pts.get(foldLineIndex)[0].nml(pts.get(foldLineIndex)[1], pts.get(foldLineIndex+1)[0]);
}
}