1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_filter.hxx"
26
27 #include <math.h>
28 #include <dxfvec.hxx>
29
30
31 //---------------------------- DXFVector ---------------------------------------
32
33
Abs() const34 double DXFVector::Abs() const
35 {
36 return sqrt(SProd(*this));
37 }
38
39
Unit() const40 DXFVector DXFVector::Unit() const
41 {
42 double flen;
43
44 flen=Abs();
45 if (flen!=0) return (*this)*(1.0/flen);
46 else return DXFVector(1.0,0.0,0.0);
47 }
48
49
50 //---------------------------- DXFTransform ------------------------------------
51
52
DXFTransform()53 DXFTransform::DXFTransform() :
54 aMX(1.0, 0.0, 0.0),
55 aMY(0.0, 1.0, 0.0),
56 aMZ(0.0, 0.0, 1.0),
57 aMP(0.0, 0.0, 0.0)
58 {
59 }
60
61
DXFTransform(double fScaleX,double fScaleY,double fScaleZ,const DXFVector & rShift)62 DXFTransform::DXFTransform(double fScaleX, double fScaleY, double fScaleZ,
63 const DXFVector & rShift) :
64 aMX(fScaleX, 0.0, 0.0),
65 aMY(0.0, fScaleY, 0.0),
66 aMZ(0.0, 0.0, fScaleZ),
67 aMP(rShift)
68 {
69 }
70
71
DXFTransform(double fScaleX,double fScaleY,double fScaleZ,double fRotAngle,const DXFVector & rShift)72 DXFTransform::DXFTransform(double fScaleX, double fScaleY, double fScaleZ,
73 double fRotAngle,
74 const DXFVector & rShift) :
75 aMX(0.0, 0.0, 0.0),
76 aMY(0.0, 0.0, 0.0),
77 aMZ(0.0, 0.0, fScaleZ),
78 aMP(rShift)
79 {
80 aMX.fx=cos(3.14159265359/180.0*fRotAngle);
81 aMX.fy=sin(3.14159265359/180.0*fRotAngle);
82 aMY.fx=-aMX.fy;
83 aMY.fy=aMX.fx;
84 aMX*=fScaleX;
85 aMY*=fScaleY;
86 }
87
88
DXFTransform(const DXFVector & rExtrusion)89 DXFTransform::DXFTransform(const DXFVector & rExtrusion) :
90 aMX(), aMY(), aMZ(), aMP(0.0, 0.0, 0.0)
91 {
92 // 'Arbitrary Axis Algorithm' (siehe DXF-Doku von Autodesk)
93 if ( fabs(rExtrusion.fx) < 1.0/64.0 && fabs(rExtrusion.fy) < 1.0/64.0) {
94 aMX = DXFVector(0.0, 1.0, 0.0) * rExtrusion;
95 }
96 else {
97 aMX = DXFVector(0.0, 0.0, 1.0) * rExtrusion;
98 }
99 aMX=aMX.Unit();
100 aMY=(rExtrusion*aMX).Unit();
101 aMZ=rExtrusion.Unit();
102 }
103
104
DXFTransform(const DXFVector & rViewDir,const DXFVector & rViewTarget)105 DXFTransform::DXFTransform(const DXFVector & rViewDir, const DXFVector & rViewTarget) :
106 aMX(), aMY(), aMZ(), aMP()
107 {
108 DXFVector aV;
109
110 aV=rViewDir.Unit();
111 aMX.fz=aV.fx;
112 aMY.fz=aV.fy;
113 aMZ.fz=aV.fz;
114
115 aMZ.fx=0;
116 if (aV.fx==0) aMY.fx=0; else aMY.fx=sqrt(1/(1+aV.fy*aV.fy/(aV.fx*aV.fx)));
117 aMX.fx=sqrt(1-aMY.fx*aMY.fx);
118 if (aV.fx*aV.fy*aMY.fx>0) aMX.fx=-aMX.fx;
119
120 aV=aV*DXFVector(aMX.fx,aMY.fx,aMZ.fx);
121 aMX.fy=aV.fx;
122 aMY.fy=aV.fy;
123 aMZ.fy=aV.fz;
124
125 if (aMZ.fy<0) {
126 aMX.fy=-aMX.fy;
127 aMY.fy=-aMY.fy;
128 aMZ.fy=-aMZ.fy;
129 aMX.fx=-aMX.fx;
130 aMY.fx=-aMY.fx;
131 }
132
133 aV=DXFVector(0,0,0)-rViewTarget;
134 aMP.fx = aV.fx * aMX.fx + aV.fy * aMY.fx + aV.fz * aMZ.fx;
135 aMP.fy = aV.fx * aMX.fy + aV.fy * aMY.fy + aV.fz * aMZ.fy;
136 aMP.fz = aV.fx * aMX.fz + aV.fy * aMY.fz + aV.fz * aMZ.fz;
137 }
138
139
DXFTransform(const DXFTransform & rT1,const DXFTransform & rT2)140 DXFTransform::DXFTransform(const DXFTransform & rT1, const DXFTransform & rT2) :
141 aMX(),aMY(),aMZ(),aMP()
142 {
143 rT2.TransDir(rT1.aMX,aMX);
144 rT2.TransDir(rT1.aMY,aMY);
145 rT2.TransDir(rT1.aMZ,aMZ);
146 rT2.Transform(rT1.aMP,aMP);
147 }
148
149
Transform(const DXFVector & rSrc,DXFVector & rTgt) const150 void DXFTransform::Transform(const DXFVector & rSrc, DXFVector & rTgt) const
151 {
152 rTgt.fx = rSrc.fx * aMX.fx + rSrc.fy * aMY.fx + rSrc.fz * aMZ.fx + aMP.fx;
153 rTgt.fy = rSrc.fx * aMX.fy + rSrc.fy * aMY.fy + rSrc.fz * aMZ.fy + aMP.fy;
154 rTgt.fz = rSrc.fx * aMX.fz + rSrc.fy * aMY.fz + rSrc.fz * aMZ.fz + aMP.fz;
155 }
156
157
Transform(const DXFVector & rSrc,Point & rTgt) const158 void DXFTransform::Transform(const DXFVector & rSrc, Point & rTgt) const
159 {
160 rTgt.X()=(long)( rSrc.fx * aMX.fx + rSrc.fy * aMY.fx + rSrc.fz * aMZ.fx + aMP.fx + 0.5 );
161 rTgt.Y()=(long)( rSrc.fx * aMX.fy + rSrc.fy * aMY.fy + rSrc.fz * aMZ.fy + aMP.fy + 0.5 );
162 }
163
164
TransDir(const DXFVector & rSrc,DXFVector & rTgt) const165 void DXFTransform::TransDir(const DXFVector & rSrc, DXFVector & rTgt) const
166 {
167 rTgt.fx = rSrc.fx * aMX.fx + rSrc.fy * aMY.fx + rSrc.fz * aMZ.fx;
168 rTgt.fy = rSrc.fx * aMX.fy + rSrc.fy * aMY.fy + rSrc.fz * aMZ.fy;
169 rTgt.fz = rSrc.fx * aMX.fz + rSrc.fy * aMY.fz + rSrc.fz * aMZ.fz;
170 }
171
172
TransCircleToEllipse(double fRadius,double & rEx,double & rEy) const173 sal_Bool DXFTransform::TransCircleToEllipse(double fRadius, double & rEx, double & rEy) const
174 {
175 double fMXAbs=aMX.Abs();
176 double fMYAbs=aMY.Abs();
177 double fNearNull=(fMXAbs+fMYAbs)*0.001;
178
179 if (fabs(aMX.fy)<=fNearNull && fabs(aMX.fz)<=fNearNull &&
180 fabs(aMY.fx)<=fNearNull && fabs(aMY.fz)<=fNearNull)
181 {
182 rEx=fabs(aMX.fx*fRadius);
183 rEy=fabs(aMY.fy*fRadius);
184 return sal_True;
185 }
186 else if (fabs(aMX.fx)<=fNearNull && fabs(aMX.fz)<=fNearNull &&
187 fabs(aMY.fy)<=fNearNull && fabs(aMY.fz)<=fNearNull)
188 {
189 rEx=fabs(aMY.fx*fRadius);
190 rEy=fabs(aMX.fy*fRadius);
191 return sal_True;
192 }
193 else if (fabs(fMXAbs-fMYAbs)<=fNearNull &&
194 fabs(aMX.fz)<=fNearNull && fabs(aMY.fz)<=fNearNull)
195 {
196 rEx=rEy=fabs(((fMXAbs+fMYAbs)/2)*fRadius);
197 return sal_True;
198 }
199 else return sal_False;
200 }
201
Transform(const DXFLineInfo & aDXFLineInfo) const202 LineInfo DXFTransform::Transform(const DXFLineInfo& aDXFLineInfo) const
203 {
204 double fex,fey,scale;
205
206 fex=sqrt(aMX.fx*aMX.fx + aMX.fy*aMX.fy);
207 fey=sqrt(aMY.fx*aMY.fx + aMY.fy*aMY.fy);
208 scale = (fex+fey)/2.0;
209
210 LineInfo aLineInfo;
211
212 aLineInfo.SetStyle( aDXFLineInfo.eStyle );
213 aLineInfo.SetWidth( (sal_Int32) (aDXFLineInfo.fWidth * scale + 0.5) );
214 aLineInfo.SetDashCount( static_cast< sal_uInt16 >( aDXFLineInfo.nDashCount ) );
215 aLineInfo.SetDashLen( (sal_Int32) (aDXFLineInfo.fDashLen * scale + 0.5) );
216 aLineInfo.SetDotCount( static_cast< sal_uInt16 >( aDXFLineInfo.nDotCount ) );
217 aLineInfo.SetDotLen( (sal_Int32) (aDXFLineInfo.fDotLen * scale + 0.5) );
218 aLineInfo.SetDistance( (sal_Int32) (aDXFLineInfo.fDistance * scale + 0.5) );
219
220 if ( aLineInfo.GetDashCount() > 0 && aLineInfo.GetDashLen() == 0 )
221 aLineInfo.SetDashLen(1);
222
223 if ( aLineInfo.GetDotCount() > 0 && aLineInfo.GetDotLen() == 0 )
224 aLineInfo.SetDotLen(1);
225
226 return aLineInfo;
227 }
228
TransLineWidth(double fW) const229 sal_uLong DXFTransform::TransLineWidth(double fW) const
230 {
231 double fex,fey;
232
233 fex=sqrt(aMX.fx*aMX.fx + aMX.fy*aMX.fy);
234 fey=sqrt(aMY.fx*aMY.fx + aMY.fy*aMY.fy);
235 // ###
236 // printf("fex=%f fey=%f\n", fex, fey);
237 return (sal_uLong)(fabs(fW)*(fex+fey)/2.0+0.5);
238 }
239
240
CalcRotAngle() const241 double DXFTransform::CalcRotAngle() const
242 {
243 return atan2(aMX.fy,aMX.fx)/3.14159265359*180.0;
244 }
245
Mirror() const246 sal_Bool DXFTransform::Mirror() const
247 {
248 if (aMZ.SProd(aMX*aMY)<0) return sal_True; else return sal_False;
249 }
250
251