Statistics
| Revision:

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
}