Update ooo320-m1
[ooovba.git] / goodies / source / filter.vcl / idxf / dxfvec.cxx
blobc9b236eef0e010dcaf9a0627093fc0e6215c9a99
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: dxfvec.cxx,v $
10 * $Revision: 1.4 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_goodies.hxx"
34 #include <math.h>
35 #include <dxfvec.hxx>
38 //---------------------------- DXFVector ---------------------------------------
41 double DXFVector::Abs() const
43 return sqrt(SProd(*this));
47 DXFVector DXFVector::Unit() const
49 double flen;
51 flen=Abs();
52 if (flen!=0) return (*this)*(1.0/flen);
53 else return DXFVector(1.0,0.0,0.0);
57 //---------------------------- DXFTransform ------------------------------------
60 DXFTransform::DXFTransform() :
61 aMX(1.0, 0.0, 0.0),
62 aMY(0.0, 1.0, 0.0),
63 aMZ(0.0, 0.0, 1.0),
64 aMP(0.0, 0.0, 0.0)
69 DXFTransform::DXFTransform(double fScaleX, double fScaleY, double fScaleZ,
70 const DXFVector & rShift) :
71 aMX(fScaleX, 0.0, 0.0),
72 aMY(0.0, fScaleY, 0.0),
73 aMZ(0.0, 0.0, fScaleZ),
74 aMP(rShift)
79 DXFTransform::DXFTransform(double fScaleX, double fScaleY, double fScaleZ,
80 double fRotAngle,
81 const DXFVector & rShift) :
82 aMX(0.0, 0.0, 0.0),
83 aMY(0.0, 0.0, 0.0),
84 aMZ(0.0, 0.0, fScaleZ),
85 aMP(rShift)
87 aMX.fx=cos(3.14159265359/180.0*fRotAngle);
88 aMX.fy=sin(3.14159265359/180.0*fRotAngle);
89 aMY.fx=-aMX.fy;
90 aMY.fy=aMX.fx;
91 aMX*=fScaleX;
92 aMY*=fScaleY;
96 DXFTransform::DXFTransform(const DXFVector & rExtrusion) :
97 aMX(), aMY(), aMZ(), aMP(0.0, 0.0, 0.0)
99 // 'Arbitrary Axis Algorithm' (siehe DXF-Doku von Autodesk)
100 if ( fabs(rExtrusion.fx) < 1.0/64.0 && fabs(rExtrusion.fy) < 1.0/64.0) {
101 aMX = DXFVector(0.0, 1.0, 0.0) * rExtrusion;
103 else {
104 aMX = DXFVector(0.0, 0.0, 1.0) * rExtrusion;
106 aMX=aMX.Unit();
107 aMY=(rExtrusion*aMX).Unit();
108 aMZ=rExtrusion.Unit();
112 DXFTransform::DXFTransform(const DXFVector & rViewDir, const DXFVector & rViewTarget) :
113 aMX(), aMY(), aMZ(), aMP()
115 DXFVector aV;
117 aV=rViewDir.Unit();
118 aMX.fz=aV.fx;
119 aMY.fz=aV.fy;
120 aMZ.fz=aV.fz;
122 aMZ.fx=0;
123 if (aV.fx==0) aMY.fx=0; else aMY.fx=sqrt(1/(1+aV.fy*aV.fy/(aV.fx*aV.fx)));
124 aMX.fx=sqrt(1-aMY.fx*aMY.fx);
125 if (aV.fx*aV.fy*aMY.fx>0) aMX.fx=-aMX.fx;
127 aV=aV*DXFVector(aMX.fx,aMY.fx,aMZ.fx);
128 aMX.fy=aV.fx;
129 aMY.fy=aV.fy;
130 aMZ.fy=aV.fz;
132 if (aMZ.fy<0) {
133 aMX.fy=-aMX.fy;
134 aMY.fy=-aMY.fy;
135 aMZ.fy=-aMZ.fy;
136 aMX.fx=-aMX.fx;
137 aMY.fx=-aMY.fx;
140 aV=DXFVector(0,0,0)-rViewTarget;
141 aMP.fx = aV.fx * aMX.fx + aV.fy * aMY.fx + aV.fz * aMZ.fx;
142 aMP.fy = aV.fx * aMX.fy + aV.fy * aMY.fy + aV.fz * aMZ.fy;
143 aMP.fz = aV.fx * aMX.fz + aV.fy * aMY.fz + aV.fz * aMZ.fz;
147 DXFTransform::DXFTransform(const DXFTransform & rT1, const DXFTransform & rT2) :
148 aMX(),aMY(),aMZ(),aMP()
150 rT2.TransDir(rT1.aMX,aMX);
151 rT2.TransDir(rT1.aMY,aMY);
152 rT2.TransDir(rT1.aMZ,aMZ);
153 rT2.Transform(rT1.aMP,aMP);
157 void DXFTransform::Transform(const DXFVector & rSrc, DXFVector & rTgt) const
159 rTgt.fx = rSrc.fx * aMX.fx + rSrc.fy * aMY.fx + rSrc.fz * aMZ.fx + aMP.fx;
160 rTgt.fy = rSrc.fx * aMX.fy + rSrc.fy * aMY.fy + rSrc.fz * aMZ.fy + aMP.fy;
161 rTgt.fz = rSrc.fx * aMX.fz + rSrc.fy * aMY.fz + rSrc.fz * aMZ.fz + aMP.fz;
165 void DXFTransform::Transform(const DXFVector & rSrc, Point & rTgt) const
167 rTgt.X()=(long)( rSrc.fx * aMX.fx + rSrc.fy * aMY.fx + rSrc.fz * aMZ.fx + aMP.fx + 0.5 );
168 rTgt.Y()=(long)( rSrc.fx * aMX.fy + rSrc.fy * aMY.fy + rSrc.fz * aMZ.fy + aMP.fy + 0.5 );
172 void DXFTransform::TransDir(const DXFVector & rSrc, DXFVector & rTgt) const
174 rTgt.fx = rSrc.fx * aMX.fx + rSrc.fy * aMY.fx + rSrc.fz * aMZ.fx;
175 rTgt.fy = rSrc.fx * aMX.fy + rSrc.fy * aMY.fy + rSrc.fz * aMZ.fy;
176 rTgt.fz = rSrc.fx * aMX.fz + rSrc.fy * aMY.fz + rSrc.fz * aMZ.fz;
180 BOOL DXFTransform::TransCircleToEllipse(double fRadius, double & rEx, double & rEy) const
182 double fMXAbs=aMX.Abs();
183 double fMYAbs=aMY.Abs();
184 double fNearNull=(fMXAbs+fMYAbs)*0.001;
186 if (fabs(aMX.fy)<=fNearNull && fabs(aMX.fz)<=fNearNull &&
187 fabs(aMY.fx)<=fNearNull && fabs(aMY.fz)<=fNearNull)
189 rEx=fabs(aMX.fx*fRadius);
190 rEy=fabs(aMY.fy*fRadius);
191 return TRUE;
193 else if (fabs(aMX.fx)<=fNearNull && fabs(aMX.fz)<=fNearNull &&
194 fabs(aMY.fy)<=fNearNull && fabs(aMY.fz)<=fNearNull)
196 rEx=fabs(aMY.fx*fRadius);
197 rEy=fabs(aMX.fy*fRadius);
198 return TRUE;
200 else if (fabs(fMXAbs-fMYAbs)<=fNearNull &&
201 fabs(aMX.fz)<=fNearNull && fabs(aMY.fz)<=fNearNull)
203 rEx=rEy=fabs(((fMXAbs+fMYAbs)/2)*fRadius);
204 return TRUE;
206 else return FALSE;
209 LineInfo DXFTransform::Transform(const DXFLineInfo& aDXFLineInfo) const
211 double fex,fey,scale;
213 fex=sqrt(aMX.fx*aMX.fx + aMX.fy*aMX.fy);
214 fey=sqrt(aMY.fx*aMY.fx + aMY.fy*aMY.fy);
215 scale = (fex+fey)/2.0;
217 LineInfo aLineInfo;
219 aLineInfo.SetStyle( aDXFLineInfo.eStyle );
220 aLineInfo.SetWidth( (sal_Int32) (aDXFLineInfo.fWidth * scale + 0.5) );
221 aLineInfo.SetDashCount( static_cast< USHORT >( aDXFLineInfo.nDashCount ) );
222 aLineInfo.SetDashLen( (sal_Int32) (aDXFLineInfo.fDashLen * scale + 0.5) );
223 aLineInfo.SetDotCount( static_cast< USHORT >( aDXFLineInfo.nDotCount ) );
224 aLineInfo.SetDotLen( (sal_Int32) (aDXFLineInfo.fDotLen * scale + 0.5) );
225 aLineInfo.SetDistance( (sal_Int32) (aDXFLineInfo.fDistance * scale + 0.5) );
227 if ( aLineInfo.GetDashCount() > 0 && aLineInfo.GetDashLen() == 0 )
228 aLineInfo.SetDashLen(1);
230 if ( aLineInfo.GetDotCount() > 0 && aLineInfo.GetDotLen() == 0 )
231 aLineInfo.SetDotLen(1);
233 return aLineInfo;
236 ULONG DXFTransform::TransLineWidth(double fW) const
238 double fex,fey;
240 fex=sqrt(aMX.fx*aMX.fx + aMX.fy*aMX.fy);
241 fey=sqrt(aMY.fx*aMY.fx + aMY.fy*aMY.fy);
242 // ###
243 // printf("fex=%f fey=%f\n", fex, fey);
244 return (ULONG)(fabs(fW)*(fex+fey)/2.0+0.5);
248 double DXFTransform::CalcRotAngle() const
250 return atan2(aMX.fy,aMX.fx)/3.14159265359*180.0;
253 BOOL DXFTransform::Mirror() const
255 if (aMZ.SProd(aMX*aMY)<0) return TRUE; else return FALSE;