summaryrefslogtreecommitdiff
path: root/basegfx/inc/basegfx/vector/b3dvector.hxx
blob: 855abb7f71e8c8df6a6f7e37af12a897fb687b82 (plain)
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
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
/*************************************************************************
 *
 *  $RCSfile: b3dvector.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: aw $ $Date: 2003-11-26 14:40:05 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library 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 this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _BGFX_VECTOR_B3DVECTOR_HXX
#define _BGFX_VECTOR_B3DVECTOR_HXX

#ifndef _BGFX_TUPLE_B3DTUPLE_HXX
#include <basegfx/tuple/b3dtuple.hxx>
#endif

namespace basegfx
{
    namespace matrix
    {
        // predeclaration
        class B3DHomMatrix;
    } // end of namespace matrix;

    namespace vector
    {
        /** Base Point class with three double values

            This class derives all operators and common handling for
            a 3D data class from B3DTuple. All necessary extensions
            which are special for 3D Vectors are added here.

            @see B3DTuple
        */
        class B3DVector : public ::basegfx::tuple::B3DTuple
        {
        public:
            /** Create a 3D Vector

                @param fVal
                This parameter is used to initialize the coordinate
                part of the 3D Vector.
            */
            B3DVector(double fVal = 0.0)
            :   B3DTuple(fVal)
            {}

            /** Create a 3D Vector

                @param fX
                This parameter is used to initialize the X-coordinate
                of the 3D Vector.

                @param fY
                This parameter is used to initialize the Y-coordinate
                of the 3D Vector.

                @param fZ
                This parameter is used to initialize the Z-coordinate
                of the 3D Vector.
            */
            B3DVector(double fX, double fY, double fZ)
            :   B3DTuple(fX, fY, fZ)
            {}

            /** Create a copy of a 3D Vector

                @param rVec
                The 3D Vector which will be copied.
            */
            B3DVector(const B3DVector& rVec)
            :   B3DTuple(rVec)
            {}

            /** constructor with tuple to allow copy-constructing
                from B3DTuple-based classes
            */
            B3DVector(const ::basegfx::tuple::B3DTuple& rTuple)
            :   B3DTuple(rTuple)
            {}

            ~B3DVector()
            {}

            /** *=operator to allow usage from B3DVector, too
            */
            B3DVector& operator*=( const B3DVector& rPnt )
            {
                mfX *= rPnt.mfX;
                mfY *= rPnt.mfY;
                mfZ *= rPnt.mfZ;
                return *this;
            }

            /** *=operator to allow usage from B3DVector, too
            */
            B3DVector& operator*=(double t)
            {
                mfX *= t;
                mfY *= t;
                mfZ *= t;
                return *this;
            }

            /** assignment operator to allow assigning the results
                of B3DTuple calculations
            */
            B3DVector& operator=( const ::basegfx::tuple::B3DTuple& rVec )
            {
                mfX = rVec.getX();
                mfY = rVec.getY();
                mfZ = rVec.getZ();
                return *this;
            }

            /** Calculate the length of this 3D Vector

                @return The Length of the 3D Vector
            */
            double getLength(void) const
            {
                double fLen(scalar(*this));
                if((0.0 == fLen) || (1.0 == fLen))
                    return fLen;
                return sqrt(fLen);
            }

            /** Calculate the length in the XY-Plane for this 3D Vector

                @return The XY-Plane Length of the 3D Vector
            */
            double getXYLength(void) const
            {
                double fLen((mfX * mfX) + (mfY * mfY));
                if((0.0 == fLen) || (1.0 == fLen))
                    return fLen;
                return sqrt(fLen);
            }

            /** Calculate the length in the XZ-Plane for this 3D Vector

                @return The XZ-Plane Length of the 3D Vector
            */
            double getXZLength(void) const
            {
                double fLen((mfX * mfZ) + (mfY * mfZ));
                if((0.0 == fLen) || (1.0 == fLen))
                    return fLen;
                return sqrt(fLen);
            }

            /** Calculate the length in the YZ-Plane for this 3D Vector

                @return The YZ-Plane Length of the 3D Vector
            */
            double getYZLength(void) const
            {
                double fLen((mfY * mfY) + (mfZ * mfZ));
                if((0.0 == fLen) || (1.0 == fLen))
                    return fLen;
                return sqrt(fLen);
            }

            /** Set the length of this 3D Vector

                @param fLen
                The to be achieved length of the 3D Vector
            */
            B3DVector& setLength(double fLen)
            {
                double fLenNow(scalar(*this));

                if(!::basegfx::numeric::fTools::equalZero(fLenNow))
                {
                    const double fOne(1.0);

                    if(!::basegfx::numeric::fTools::equal(fOne, fLenNow))
                    {
                        fLen /= sqrt(fLenNow);
                    }

                    mfX *= fLen;
                    mfY *= fLen;
                    mfZ *= fLen;
                }

                return *this;
            }

            /** Normalize this 3D Vector

                The length of the 3D Vector is set to 1.0
            */
            B3DVector& normalize();

            /** Test if this 3D Vector is normalized

                @return
                sal_True if lenth of vector is equal to 1.0
                sal_False else
            */
            sal_Bool isNormalized() const
            {
                const double fOne(1.0);
                const double fScalar(scalar(*this));

                return (::basegfx::numeric::fTools::equal(fOne, fScalar));
            }

            /** get a 3D Vector which is perpendicular to this and a given 3D Vector

                @attention This only works if this and the given 3D Vector are
                both normalized.

                @param rNormalizedVec
                A normalized 3D Vector.

                @return
                A 3D Vector perpendicular to this and the given one
            */
            B3DVector getPerpendicular(const B3DVector& rNormalizedVec) const;

            /** get the projection of this Vector on the given Plane

                @attention This only works if the given 3D Vector defining
                the Plane is normalized.

                @param rNormalizedPlane
                A normalized 3D Vector defining a Plane.

                @return
                The projected 3D Vector
            */
            B3DVector getProjectionOnPlane(const B3DVector& rNormalizedPlane) const;

            /** Calculate the Scalar product

                This method calculates the Scalar product between this
                and the given 3D Vector.

                @param rVec
                A second 3D Vector.

                @return
                The Scalar Product of two 3D Vectors
            */
            double scalar(const B3DVector& rVec) const
            {
                return ((mfX * rVec.mfX) + (mfY * rVec.mfY) + (mfZ * rVec.mfZ));
            }

            /** Transform vector by given transformation matrix.

                Since this is a vector, translational components of the
                matrix are disregarded.
            */
            B3DVector& operator*=( const matrix::B3DHomMatrix& rMat );

            static const B3DVector& getEmptyVector()
            {
                return (const B3DVector&) ::basegfx::tuple::B3DTuple::getEmptyTuple();
            }
        };

        // external operators
        //////////////////////////////////////////////////////////////////////////

        /** get a 3D Vector which is in 2D (ignoring
            the Z-Coordinate) perpendicular to a given 3D Vector

            @attention This only works if the given 3D Vector is normalized.

            @param rNormalizedVec
            A normalized 3D Vector.

            @return
            A 3D Vector perpendicular to the given one in X,Y (2D).
        */
        inline B3DVector getPerpendicular2D( const B3DVector& rNormalizedVec )
        {
            B3DVector aPerpendicular(-rNormalizedVec.getY(), rNormalizedVec.getX(), rNormalizedVec.getZ());
            return aPerpendicular;
        }

        /** Transform vector by given transformation matrix.

            Since this is a vector, translational components of the
            matrix are disregarded.
        */
        B3DVector operator*( const matrix::B3DHomMatrix& rMat, const B3DVector& rVec );

        /** Calculate the Cross Product of two 3D Vectors

            @param rVecA
            A first 3D Vector.

            @param rVecB
            A second 3D Vector.

            @return
            The Cross Product of both 3D Vectors
        */
        inline B3DVector cross(const B3DVector& rVecA, const B3DVector& rVecB)
        {
            B3DVector aVec(
                rVecA.getY() * rVecB.getZ() - rVecA.getZ() * rVecB.getY(),
                rVecA.getZ() * rVecB.getX() - rVecA.getX() * rVecB.getZ(),
                rVecA.getX() * rVecB.getY() - rVecA.getY() * rVecB.getX());
            return aVec;
        }
    } // end of namespace vector
} // end of namespace basegfx

#endif // _BGFX_VECTOR_B3DVECTOR_HXX