xref: /AOO41X/main/filter/source/graphicfilter/idxf/dxfvec.cxx (revision 9e0fc027f109ec4ffcb6033aeec742a099701108)
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