svn-gvsig-desktop / trunk / libraries / libDwg / src / com / iver / cit / jdwglib / util / AcadExtrusionCalculator.java @ 10345
History | View | Annotate | Download (8.4 KB)
1 |
/* jdwglib. Java Library for reading Dwg files.
|
---|---|
2 |
*
|
3 |
* Author: Jose Morell Rama (jose.morell@gmail.com).
|
4 |
* Port from the Pythoncad Dwg library by Art Haas.
|
5 |
*
|
6 |
* Copyright (C) 2005 Jose Morell, IVER TI S.A. and Generalitat Valenciana
|
7 |
*
|
8 |
* This program is free software; you can redistribute it and/or
|
9 |
* modify it under the terms of the GNU General Public License
|
10 |
* as published by the Free Software Foundation; either version 2
|
11 |
* of the License, or (at your option) any later version.
|
12 |
*
|
13 |
* This program is distributed in the hope that it will be useful,
|
14 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
15 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
16 |
* GNU General Public License for more details.
|
17 |
*
|
18 |
* You should have received a copy of the GNU General Public License
|
19 |
* along with this program; if not, write to the Free Software
|
20 |
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,USA.
|
21 |
*
|
22 |
* For more information, contact:
|
23 |
*
|
24 |
* Jose Morell (jose.morell@gmail.com)
|
25 |
*
|
26 |
* or
|
27 |
*
|
28 |
* IVER TI S.A.
|
29 |
* C/Salamanca, 50
|
30 |
* 46005 Valencia
|
31 |
* Spain
|
32 |
* +34 963163400
|
33 |
* dac@iver.es
|
34 |
*/
|
35 |
package com.iver.cit.jdwglib.util; |
36 |
|
37 |
import java.lang.Math; |
38 |
|
39 |
/**
|
40 |
* This class allows to apply the extrusion transformation of Autocad given by an array
|
41 |
* of doubles to a point given by an array of doubles too. The result of this
|
42 |
* transformation is a Point2D
|
43 |
*
|
44 |
* @author jmorell
|
45 |
*/
|
46 |
public class AcadExtrusionCalculator { |
47 |
|
48 |
final static double[] WY = new double[]{0,1,0}; |
49 |
final static double[] WZ = new double[]{0,0,1}; |
50 |
final static double MINLENGHT = 1d/64d; |
51 |
/*
|
52 |
* http://personales.unican.es/togoresr/Sco-en.html
|
53 |
* http://www.autodesk.com/techpubs/autocad/acadr14/dxf/object_coordinate_systems_40ocs41_al_u05_c.htm
|
54 |
* http://www.autodesk.com/techpubs/autocad/acadr14/dxf/arbitrary_axis_algorithm_al_u05_c.htm
|
55 |
* http://vis.cs.brown.edu/resources/doc/gluebase-2.0/vector3d_8H-source.html
|
56 |
* */
|
57 |
public static double[] extrude(double[] coordToExtrude, double[] extrusionVector){ |
58 |
double[] solution = null; |
59 |
double[] ax = null; |
60 |
double[] ay = null; |
61 |
|
62 |
double normalLenght = length(extrusionVector);
|
63 |
|
64 |
if( (Math.abs(extrusionVector[0]) > MINLENGHT) && (Math.abs(extrusionVector[1]) > MINLENGHT)){ |
65 |
ax = crossProduct(WY, extrusionVector); |
66 |
}else{
|
67 |
ax = crossProduct(WZ, extrusionVector); |
68 |
} |
69 |
ax = makeUnitary(ax); |
70 |
|
71 |
ay = crossProduct(extrusionVector, ax); |
72 |
ay = makeUnitary(ay); |
73 |
|
74 |
//Llegados a este punto, tenemos tres vectores unitarios
|
75 |
|
76 |
double x = ax[0] * coordToExtrude[0] + ay[0] * coordToExtrude[1] + extrusionVector[0] * coordToExtrude[2]; |
77 |
double y = ax[1] * coordToExtrude[0] + ay[1] * coordToExtrude[1] + extrusionVector[1] * coordToExtrude[2]; |
78 |
double z = ax[2] * coordToExtrude[0] + ay[2] * coordToExtrude[1] + extrusionVector[2] * coordToExtrude[2]; |
79 |
|
80 |
solution = new double[]{x, y, z}; |
81 |
return solution;
|
82 |
} |
83 |
|
84 |
public static double[] crossProduct(double[] a, double[] b){ |
85 |
|
86 |
return new double[]{ a[1] * b[2] - a[2] * b[1], |
87 |
a[2] * b[0] - a[0] * b[2], |
88 |
a[0] * b[1] - a[1] * b[0]}; |
89 |
} |
90 |
|
91 |
|
92 |
public static double[] makeUnitary(double[] vector){ |
93 |
double[] solution = null; |
94 |
double vectorLenght = length(vector);
|
95 |
|
96 |
double x = vector[0] / vectorLenght; |
97 |
double y = vector[1] / vectorLenght; |
98 |
double z = vector[2] / vectorLenght; |
99 |
|
100 |
solution = new double[]{x, y, z}; |
101 |
return solution;
|
102 |
} |
103 |
|
104 |
public static double length(double[] vector){ |
105 |
return Math.sqrt( (vector[0] * vector[0]) + |
106 |
(vector[1] * vector[1]) + |
107 |
(vector[2] * vector[2])); |
108 |
} |
109 |
|
110 |
|
111 |
|
112 |
/**
|
113 |
* Method that allows to apply the extrusion transformation of Autocad
|
114 |
*
|
115 |
* @param coord_in Array of doubles that represents the input coordinates
|
116 |
* @param xtru array of doubles that contanins the extrusion parameters
|
117 |
* @return double[] Is the result of the application of the extrusion transformation
|
118 |
* to the input point
|
119 |
*/
|
120 |
public static double[] extrude2(double[] coord_in, double[] xtru) { |
121 |
double[] coord_out; |
122 |
|
123 |
double dxt0 = 0D, dyt0 = 0D, dzt0 = 0D; |
124 |
double dvx1, dvx2, dvx3;
|
125 |
double dvy1, dvy2, dvy3;
|
126 |
double dmod, dxt, dyt, dzt;
|
127 |
|
128 |
double aux = 1D/64D; |
129 |
double aux1 = Math.abs(xtru[0]); |
130 |
double aux2 = Math.abs(xtru[1]); |
131 |
|
132 |
dxt0 = coord_in[0];
|
133 |
dyt0 = coord_in[1];
|
134 |
dzt0 = coord_in[2];
|
135 |
|
136 |
double xtruX, xtruY, xtruZ;
|
137 |
xtruX = xtru[0];
|
138 |
xtruY = xtru[1];
|
139 |
xtruZ = xtru[2];
|
140 |
|
141 |
if ((aux1 < aux) && (aux2 < aux)) {
|
142 |
dmod = Math.sqrt(xtruZ*xtruZ + xtruX*xtruX);
|
143 |
dvx1 = xtruZ / dmod; |
144 |
dvx2 = 0;
|
145 |
dvx3 = -xtruX / dmod; |
146 |
} else {
|
147 |
dmod = Math.sqrt(xtruY*xtruY + xtruX*xtruX);
|
148 |
dvx1 = -xtruY / dmod; |
149 |
dvx2 = xtruX / dmod; |
150 |
dvx3 = 0;
|
151 |
} |
152 |
|
153 |
dvy1 = xtruY*dvx3 - xtruZ*dvx2; |
154 |
dvy2 = xtruZ*dvx1 - xtruX*dvx3; |
155 |
dvy3 = xtruX*dvx2 - xtruY*dvx1; |
156 |
|
157 |
dmod = Math.sqrt(dvy1*dvy1 + dvy2*dvy2 + dvy3*dvy3);
|
158 |
|
159 |
dvy1 = dvy1 / dmod; |
160 |
dvy2 = dvy2 / dmod; |
161 |
dvy3 = dvy3 / dmod; |
162 |
|
163 |
dxt = dvx1*dxt0 + dvy1*dyt0 + xtruX*dzt0; |
164 |
dyt = dvx2*dxt0 + dvy2*dyt0 + xtruY*dzt0; |
165 |
dzt = dvx3*dxt0 + dvy3*dyt0 + xtruZ*dzt0; |
166 |
|
167 |
coord_out = new double[]{dxt, dyt, dzt}; |
168 |
|
169 |
dxt0 = 0;
|
170 |
dyt0 = 0;
|
171 |
dzt0 = 0;
|
172 |
|
173 |
return coord_out;
|
174 |
} |
175 |
|
176 |
public final Matrix4D calcArbitMat(double[] extrusion, double[] coord) |
177 |
{ |
178 |
|
179 |
Vector3D row1 = null;
|
180 |
if(extrusion[0] == 0d && extrusion[1] == 0d && extrusion[2] > 0d && coord[2] == 0d) |
181 |
return null; |
182 |
if((extrusion[0] >= 0f ? extrusion[0]:-extrusion[0]) < 0.015625F |
183 |
&& |
184 |
(extrusion[1] >= 0f ? extrusion[1]:-extrusion[1]) < 0.015625F)){ |
185 |
|
186 |
row1 = new Vector3D(extrusion[2], 0f, -extrusion[0]); |
187 |
}else{
|
188 |
row1 = new Vector3D(-extrusion[1],extrusion[0], 0f); |
189 |
} |
190 |
float len = row1.length();
|
191 |
row1.scale(1.0F / len);
|
192 |
Vector3D upward = new Vector3D(extrusion[0], extrusion[1], extrusion[2]); |
193 |
Vector3D row2 = upward.cross(row1); |
194 |
// Matrix4D aaa = new Matrix4D(row1.x, row2.x, upward.x,
|
195 |
// height * upward.x, row1.y, row2.y,
|
196 |
// upward.y, height * upward.y, row1.z,
|
197 |
// row2.z, upward.z, height * upward.z,
|
198 |
// 0.0F, 0.0F, 0.0F, 1.0F);
|
199 |
|
200 |
|
201 |
//se asume que coord[2] es la altura (height), pero en DXF
|
202 |
//la altura podia venir dada por el code 30 y poer el 38
|
203 |
Matrix4D aaa = new Matrix4D(row1.x, row2.x, upward.x,
|
204 |
coord[2] * upward.x, row1.y, row2.y,
|
205 |
upward.y, coord[2] * upward.y, row1.z,
|
206 |
row2.z, upward.z, coord[2] * upward.z,
|
207 |
0.0F, 0.0F, 0.0F, 1.0F); |
208 |
return aaa;
|
209 |
} |
210 |
|
211 |
/*
|
212 |
|
213 |
llamamos a finalConv, y este llama a extrude internamente
|
214 |
|
215 |
static DrawAble finalConv(DrawAble dl, DxfEntity entity, boolean doTransform)
|
216 |
{
|
217 |
if(dl == null)
|
218 |
return null;
|
219 |
DrawAble dr;
|
220 |
if(doTransform)
|
221 |
{
|
222 |
if(entity.getExtrusion() != 0.0F)
|
223 |
dr = dl.extrude(entity.getExtrusion());
|
224 |
else
|
225 |
dr = dl;
|
226 |
Matrix4D mat = entity.calcArbitMat();
|
227 |
if(mat != null)
|
228 |
dr.transformBy(mat);
|
229 |
} else
|
230 |
if(entity.getExtrusion() != 0.0F)
|
231 |
dr = dl.extrude(entity.getExtrusion(), entity.getUpwardVector());
|
232 |
else
|
233 |
dr = dl;
|
234 |
return dr;
|
235 |
}
|
236 |
|
237 |
public DrawAble extrude(float dist, Vector3D up)
|
238 |
{
|
239 |
if(dist == 0.0F)
|
240 |
return this;
|
241 |
Vector3D ex = new Vector3D(dist * up.x, dist * up.y, dist * up.z);
|
242 |
DrawSet set = new DrawSet(2 + nrPoints);
|
243 |
DrawLines second = new DrawLines(nrPoints);
|
244 |
set.setLayer(super.layer);
|
245 |
set.setColor(super.color);
|
246 |
second.setLayer(super.layer);
|
247 |
second.setColor(super.color);
|
248 |
set.addDrawable(this);
|
249 |
for(int i = 0; i < nrPoints; i++)
|
250 |
{
|
251 |
second.addPoint(line[i].x + ex.x, line[i].y + ex.y, line[i].z + ex.z);
|
252 |
DrawLines conn = new DrawLines(2);
|
253 |
conn.setLayer(super.layer);
|
254 |
conn.setColor(super.color);
|
255 |
conn.addPoint(line[i]);
|
256 |
conn.addPoint(second.line[i]);
|
257 |
set.addDrawable(conn);
|
258 |
}
|
259 |
|
260 |
if(isClosed)
|
261 |
second.close();
|
262 |
set.addDrawable(second);
|
263 |
return set;
|
264 |
}
|
265 |
|
266 |
|
267 |
|
268 |
*/
|
269 |
} |