1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: dxfvec.cxx,v $
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"
38 //---------------------------- DXFVector ---------------------------------------
41 double DXFVector::Abs() const
43 return sqrt(SProd(*this));
47 DXFVector
DXFVector::Unit() const
52 if (flen
!=0) return (*this)*(1.0/flen
);
53 else return DXFVector(1.0,0.0,0.0);
57 //---------------------------- DXFTransform ------------------------------------
60 DXFTransform::DXFTransform() :
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
),
79 DXFTransform::DXFTransform(double fScaleX
, double fScaleY
, double fScaleZ
,
81 const DXFVector
& rShift
) :
84 aMZ(0.0, 0.0, fScaleZ
),
87 aMX
.fx
=cos(3.14159265359/180.0*fRotAngle
);
88 aMX
.fy
=sin(3.14159265359/180.0*fRotAngle
);
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
;
104 aMX
= DXFVector(0.0, 0.0, 1.0) * rExtrusion
;
107 aMY
=(rExtrusion
*aMX
).Unit();
108 aMZ
=rExtrusion
.Unit();
112 DXFTransform::DXFTransform(const DXFVector
& rViewDir
, const DXFVector
& rViewTarget
) :
113 aMX(), aMY(), aMZ(), aMP()
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
);
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
);
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
);
200 else if (fabs(fMXAbs
-fMYAbs
)<=fNearNull
&&
201 fabs(aMX
.fz
)<=fNearNull
&& fabs(aMY
.fz
)<=fNearNull
)
203 rEx
=rEy
=fabs(((fMXAbs
+fMYAbs
)/2)*fRadius
);
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;
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);
236 ULONG
DXFTransform::TransLineWidth(double fW
) const
240 fex
=sqrt(aMX
.fx
*aMX
.fx
+ aMX
.fy
*aMX
.fy
);
241 fey
=sqrt(aMY
.fx
*aMY
.fx
+ aMY
.fy
*aMY
.fy
);
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
;