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 std::hypot(fx
, fy
, fz
);
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(basegfx::deg2rad(fRotAngle
));
76 aMX
.fy
=sin(basegfx::deg2rad(fRotAngle
));
84 DXFTransform::DXFTransform(const DXFVector
& rExtrusion
) :
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
)
110 if (aV
.fx
==0) aMY
.fx
=0; else aMY
.fx
=sqrt(1/(1+aV
.fy
*aV
.fy
/(aV
.fx
*aV
.fx
)));
111 aMX
.fx
=sqrt(1-aMY
.fx
*aMY
.fx
);
112 if (aV
.fx
*aV
.fy
*aMY
.fx
>0) aMX
.fx
=-aMX
.fx
;
114 aV
=aV
*DXFVector(aMX
.fx
,aMY
.fx
,aMZ
.fx
);
127 aV
=DXFVector(0,0,0)-rViewTarget
;
128 aMP
.fx
= aV
.fx
* aMX
.fx
+ aV
.fy
* aMY
.fx
+ aV
.fz
* aMZ
.fx
;
129 aMP
.fy
= aV
.fx
* aMX
.fy
+ aV
.fy
* aMY
.fy
+ aV
.fz
* aMZ
.fy
;
130 aMP
.fz
= aV
.fx
* aMX
.fz
+ aV
.fy
* aMY
.fz
+ aV
.fz
* aMZ
.fz
;
134 DXFTransform::DXFTransform(const DXFTransform
& rT1
, const DXFTransform
& rT2
)
136 rT2
.TransDir(rT1
.aMX
,aMX
);
137 rT2
.TransDir(rT1
.aMY
,aMY
);
138 rT2
.TransDir(rT1
.aMZ
,aMZ
);
139 rT2
.Transform(rT1
.aMP
,aMP
);
143 void DXFTransform::Transform(const DXFVector
& rSrc
, DXFVector
& rTgt
) const
145 rTgt
.fx
= rSrc
.fx
* aMX
.fx
+ rSrc
.fy
* aMY
.fx
+ rSrc
.fz
* aMZ
.fx
+ aMP
.fx
;
146 rTgt
.fy
= rSrc
.fx
* aMX
.fy
+ rSrc
.fy
* aMY
.fy
+ rSrc
.fz
* aMZ
.fy
+ aMP
.fy
;
147 rTgt
.fz
= rSrc
.fx
* aMX
.fz
+ rSrc
.fy
* aMY
.fz
+ rSrc
.fz
* aMZ
.fz
+ aMP
.fz
;
151 void DXFTransform::Transform(const DXFVector
& rSrc
, Point
& rTgt
) const
153 rTgt
.setX(static_cast<tools::Long
>( rSrc
.fx
* aMX
.fx
+ rSrc
.fy
* aMY
.fx
+ rSrc
.fz
* aMZ
.fx
+ aMP
.fx
+ 0.5 ) );
154 rTgt
.setY(static_cast<tools::Long
>( rSrc
.fx
* aMX
.fy
+ rSrc
.fy
* aMY
.fy
+ rSrc
.fz
* aMZ
.fy
+ aMP
.fy
+ 0.5 ) );
158 void DXFTransform::TransDir(const DXFVector
& rSrc
, DXFVector
& rTgt
) const
160 rTgt
.fx
= rSrc
.fx
* aMX
.fx
+ rSrc
.fy
* aMY
.fx
+ rSrc
.fz
* aMZ
.fx
;
161 rTgt
.fy
= rSrc
.fx
* aMX
.fy
+ rSrc
.fy
* aMY
.fy
+ rSrc
.fz
* aMZ
.fy
;
162 rTgt
.fz
= rSrc
.fx
* aMX
.fz
+ rSrc
.fy
* aMY
.fz
+ rSrc
.fz
* aMZ
.fz
;
166 bool DXFTransform::TransCircleToEllipse(double fRadius
, double & rEx
, double & rEy
) const
168 double fMXAbs
=aMX
.Abs();
169 double fMYAbs
=aMY
.Abs();
170 double fNearNull
=(fMXAbs
+fMYAbs
)*0.001;
172 if (fabs(aMX
.fy
)<=fNearNull
&& fabs(aMX
.fz
)<=fNearNull
&&
173 fabs(aMY
.fx
)<=fNearNull
&& fabs(aMY
.fz
)<=fNearNull
)
175 rEx
=fabs(aMX
.fx
*fRadius
);
176 rEy
=fabs(aMY
.fy
*fRadius
);
179 else if (fabs(aMX
.fx
)<=fNearNull
&& fabs(aMX
.fz
)<=fNearNull
&&
180 fabs(aMY
.fy
)<=fNearNull
&& fabs(aMY
.fz
)<=fNearNull
)
182 rEx
=fabs(aMY
.fx
*fRadius
);
183 rEy
=fabs(aMX
.fy
*fRadius
);
186 else if (fabs(fMXAbs
-fMYAbs
)<=fNearNull
&&
187 fabs(aMX
.fz
)<=fNearNull
&& fabs(aMY
.fz
)<=fNearNull
)
189 rEx
=rEy
=fabs(((fMXAbs
+fMYAbs
)/2)*fRadius
);
195 LineInfo
DXFTransform::Transform(const DXFLineInfo
& aDXFLineInfo
) const
197 double fex
,fey
,scale
;
199 fex
=std::hypot(aMX
.fx
, aMX
.fy
);
200 fey
=std::hypot(aMY
.fx
, aMY
.fy
);
201 scale
= (fex
+fey
)/2.0;
205 aLineInfo
.SetStyle( aDXFLineInfo
.eStyle
);
206 aLineInfo
.SetWidth( 0 );
207 aLineInfo
.SetDashCount( static_cast< sal_uInt16
>( aDXFLineInfo
.nDashCount
) );
208 aLineInfo
.SetDashLen( aDXFLineInfo
.fDashLen
* scale
);
209 aLineInfo
.SetDotCount( static_cast< sal_uInt16
>( aDXFLineInfo
.nDotCount
) );
210 aLineInfo
.SetDotLen( aDXFLineInfo
.fDotLen
* scale
);
211 aLineInfo
.SetDistance( aDXFLineInfo
.fDistance
* scale
);
213 if ( aLineInfo
.GetDashCount() > 0 && aLineInfo
.GetDashLen() == 0 )
214 aLineInfo
.SetDashLen(1);
216 if ( aLineInfo
.GetDotCount() > 0 && aLineInfo
.GetDotLen() == 0 )
217 aLineInfo
.SetDotLen(1);
222 double DXFTransform::CalcRotAngle() const
224 return basegfx::rad2deg(atan2(aMX
.fy
,aMX
.fx
));
227 bool DXFTransform::Mirror() const
229 return aMZ
.SProd(aMX
*aMY
)<0;
232 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */