1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
23 #include <tools/gen.hxx>
26 //---------------------------- DXFVector ---------------------------------------
29 double DXFVector::Abs() const
31 return sqrt(SProd(*this));
35 DXFVector
DXFVector::Unit() const
40 if (flen
!=0) return (*this)*(1.0/flen
);
41 else return DXFVector(1.0,0.0,0.0);
45 //---------------------------- DXFTransform ------------------------------------
48 DXFTransform::DXFTransform() :
57 DXFTransform::DXFTransform(double fScaleX
, double fScaleY
, double fScaleZ
,
58 const DXFVector
& rShift
) :
59 aMX(fScaleX
, 0.0, 0.0),
60 aMY(0.0, fScaleY
, 0.0),
61 aMZ(0.0, 0.0, fScaleZ
),
67 DXFTransform::DXFTransform(double fScaleX
, double fScaleY
, double fScaleZ
,
69 const DXFVector
& rShift
) :
72 aMZ(0.0, 0.0, fScaleZ
),
75 aMX
.fx
=cos(3.14159265359/180.0*fRotAngle
);
76 aMX
.fy
=sin(3.14159265359/180.0*fRotAngle
);
84 DXFTransform::DXFTransform(const DXFVector
& rExtrusion
) :
85 aMX(), aMY(), aMZ(), aMP(0.0, 0.0, 0.0)
87 // 'Arbitrary Axis Algorithm' (cf. DXF documentation by Autodesk)
88 if ( fabs(rExtrusion
.fx
) < 1.0/64.0 && fabs(rExtrusion
.fy
) < 1.0/64.0) {
89 aMX
= DXFVector(0.0, 1.0, 0.0) * rExtrusion
;
92 aMX
= DXFVector(0.0, 0.0, 1.0) * rExtrusion
;
95 aMY
=(rExtrusion
*aMX
).Unit();
96 aMZ
=rExtrusion
.Unit();
100 DXFTransform::DXFTransform(const DXFVector
& rViewDir
, const DXFVector
& rViewTarget
) :
101 aMX(), aMY(), aMZ(), aMP()
111 if (aV
.fx
==0) aMY
.fx
=0; else aMY
.fx
=sqrt(1/(1+aV
.fy
*aV
.fy
/(aV
.fx
*aV
.fx
)));
112 aMX
.fx
=sqrt(1-aMY
.fx
*aMY
.fx
);
113 if (aV
.fx
*aV
.fy
*aMY
.fx
>0) aMX
.fx
=-aMX
.fx
;
115 aV
=aV
*DXFVector(aMX
.fx
,aMY
.fx
,aMZ
.fx
);
128 aV
=DXFVector(0,0,0)-rViewTarget
;
129 aMP
.fx
= aV
.fx
* aMX
.fx
+ aV
.fy
* aMY
.fx
+ aV
.fz
* aMZ
.fx
;
130 aMP
.fy
= aV
.fx
* aMX
.fy
+ aV
.fy
* aMY
.fy
+ aV
.fz
* aMZ
.fy
;
131 aMP
.fz
= aV
.fx
* aMX
.fz
+ aV
.fy
* aMY
.fz
+ aV
.fz
* aMZ
.fz
;
135 DXFTransform::DXFTransform(const DXFTransform
& rT1
, const DXFTransform
& rT2
) :
136 aMX(),aMY(),aMZ(),aMP()
138 rT2
.TransDir(rT1
.aMX
,aMX
);
139 rT2
.TransDir(rT1
.aMY
,aMY
);
140 rT2
.TransDir(rT1
.aMZ
,aMZ
);
141 rT2
.Transform(rT1
.aMP
,aMP
);
145 void DXFTransform::Transform(const DXFVector
& rSrc
, DXFVector
& rTgt
) const
147 rTgt
.fx
= rSrc
.fx
* aMX
.fx
+ rSrc
.fy
* aMY
.fx
+ rSrc
.fz
* aMZ
.fx
+ aMP
.fx
;
148 rTgt
.fy
= rSrc
.fx
* aMX
.fy
+ rSrc
.fy
* aMY
.fy
+ rSrc
.fz
* aMZ
.fy
+ aMP
.fy
;
149 rTgt
.fz
= rSrc
.fx
* aMX
.fz
+ rSrc
.fy
* aMY
.fz
+ rSrc
.fz
* aMZ
.fz
+ aMP
.fz
;
153 void DXFTransform::Transform(const DXFVector
& rSrc
, Point
& rTgt
) const
155 rTgt
.setX(static_cast<tools::Long
>( rSrc
.fx
* aMX
.fx
+ rSrc
.fy
* aMY
.fx
+ rSrc
.fz
* aMZ
.fx
+ aMP
.fx
+ 0.5 ) );
156 rTgt
.setY(static_cast<tools::Long
>( rSrc
.fx
* aMX
.fy
+ rSrc
.fy
* aMY
.fy
+ rSrc
.fz
* aMZ
.fy
+ aMP
.fy
+ 0.5 ) );
160 void DXFTransform::TransDir(const DXFVector
& rSrc
, DXFVector
& rTgt
) const
162 rTgt
.fx
= rSrc
.fx
* aMX
.fx
+ rSrc
.fy
* aMY
.fx
+ rSrc
.fz
* aMZ
.fx
;
163 rTgt
.fy
= rSrc
.fx
* aMX
.fy
+ rSrc
.fy
* aMY
.fy
+ rSrc
.fz
* aMZ
.fy
;
164 rTgt
.fz
= rSrc
.fx
* aMX
.fz
+ rSrc
.fy
* aMY
.fz
+ rSrc
.fz
* aMZ
.fz
;
168 bool DXFTransform::TransCircleToEllipse(double fRadius
, double & rEx
, double & rEy
) const
170 double fMXAbs
=aMX
.Abs();
171 double fMYAbs
=aMY
.Abs();
172 double fNearNull
=(fMXAbs
+fMYAbs
)*0.001;
174 if (fabs(aMX
.fy
)<=fNearNull
&& fabs(aMX
.fz
)<=fNearNull
&&
175 fabs(aMY
.fx
)<=fNearNull
&& fabs(aMY
.fz
)<=fNearNull
)
177 rEx
=fabs(aMX
.fx
*fRadius
);
178 rEy
=fabs(aMY
.fy
*fRadius
);
181 else if (fabs(aMX
.fx
)<=fNearNull
&& fabs(aMX
.fz
)<=fNearNull
&&
182 fabs(aMY
.fy
)<=fNearNull
&& fabs(aMY
.fz
)<=fNearNull
)
184 rEx
=fabs(aMY
.fx
*fRadius
);
185 rEy
=fabs(aMX
.fy
*fRadius
);
188 else if (fabs(fMXAbs
-fMYAbs
)<=fNearNull
&&
189 fabs(aMX
.fz
)<=fNearNull
&& fabs(aMY
.fz
)<=fNearNull
)
191 rEx
=rEy
=fabs(((fMXAbs
+fMYAbs
)/2)*fRadius
);
197 LineInfo
DXFTransform::Transform(const DXFLineInfo
& aDXFLineInfo
) const
199 double fex
,fey
,scale
;
201 fex
=sqrt(aMX
.fx
*aMX
.fx
+ aMX
.fy
*aMX
.fy
);
202 fey
=sqrt(aMY
.fx
*aMY
.fx
+ aMY
.fy
*aMY
.fy
);
203 scale
= (fex
+fey
)/2.0;
207 aLineInfo
.SetStyle( aDXFLineInfo
.eStyle
);
208 aLineInfo
.SetWidth( 0 );
209 aLineInfo
.SetDashCount( static_cast< sal_uInt16
>( aDXFLineInfo
.nDashCount
) );
210 aLineInfo
.SetDashLen( aDXFLineInfo
.fDashLen
* scale
);
211 aLineInfo
.SetDotCount( static_cast< sal_uInt16
>( aDXFLineInfo
.nDotCount
) );
212 aLineInfo
.SetDotLen( aDXFLineInfo
.fDotLen
* scale
);
213 aLineInfo
.SetDistance( aDXFLineInfo
.fDistance
* scale
);
215 if ( aLineInfo
.GetDashCount() > 0 && aLineInfo
.GetDashLen() == 0 )
216 aLineInfo
.SetDashLen(1);
218 if ( aLineInfo
.GetDotCount() > 0 && aLineInfo
.GetDotLen() == 0 )
219 aLineInfo
.SetDotLen(1);
224 double DXFTransform::CalcRotAngle() const
226 return atan2(aMX
.fy
,aMX
.fx
)/3.14159265359*180.0;
229 bool DXFTransform::Mirror() const
231 return aMZ
.SProd(aMX
*aMY
)<0;
234 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */