Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*
3 : : * This file is part of the LibreOffice project.
4 : : *
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/.
8 : : *
9 : : * This file incorporates work covered by the following license notice:
10 : : *
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 .
18 : : */
19 : :
20 : :
21 : : #include <math.h>
22 : : #include <dxfvec.hxx>
23 : :
24 : :
25 : : //---------------------------- DXFVector ---------------------------------------
26 : :
27 : :
28 : 0 : double DXFVector::Abs() const
29 : : {
30 : 0 : return sqrt(SProd(*this));
31 : : }
32 : :
33 : :
34 : 0 : DXFVector DXFVector::Unit() const
35 : : {
36 : : double flen;
37 : :
38 : 0 : flen=Abs();
39 : 0 : if (flen!=0) return (*this)*(1.0/flen);
40 : 0 : else return DXFVector(1.0,0.0,0.0);
41 : : }
42 : :
43 : :
44 : : //---------------------------- DXFTransform ------------------------------------
45 : :
46 : :
47 : 0 : DXFTransform::DXFTransform() :
48 : : aMX(1.0, 0.0, 0.0),
49 : : aMY(0.0, 1.0, 0.0),
50 : : aMZ(0.0, 0.0, 1.0),
51 : 0 : aMP(0.0, 0.0, 0.0)
52 : : {
53 : 0 : }
54 : :
55 : :
56 : 0 : DXFTransform::DXFTransform(double fScaleX, double fScaleY, double fScaleZ,
57 : : const DXFVector & rShift) :
58 : : aMX(fScaleX, 0.0, 0.0),
59 : : aMY(0.0, fScaleY, 0.0),
60 : : aMZ(0.0, 0.0, fScaleZ),
61 : 0 : aMP(rShift)
62 : : {
63 : 0 : }
64 : :
65 : :
66 : 0 : DXFTransform::DXFTransform(double fScaleX, double fScaleY, double fScaleZ,
67 : : double fRotAngle,
68 : : const DXFVector & rShift) :
69 : : aMX(0.0, 0.0, 0.0),
70 : : aMY(0.0, 0.0, 0.0),
71 : : aMZ(0.0, 0.0, fScaleZ),
72 : 0 : aMP(rShift)
73 : : {
74 : 0 : aMX.fx=cos(3.14159265359/180.0*fRotAngle);
75 : 0 : aMX.fy=sin(3.14159265359/180.0*fRotAngle);
76 : 0 : aMY.fx=-aMX.fy;
77 : 0 : aMY.fy=aMX.fx;
78 : 0 : aMX*=fScaleX;
79 : 0 : aMY*=fScaleY;
80 : 0 : }
81 : :
82 : :
83 : 0 : DXFTransform::DXFTransform(const DXFVector & rExtrusion) :
84 : 0 : aMX(), aMY(), aMZ(), aMP(0.0, 0.0, 0.0)
85 : : {
86 : : // 'Arbitrary Axis Algorithm' (cf. DXF documentation by Autodesk)
87 : 0 : if ( fabs(rExtrusion.fx) < 1.0/64.0 && fabs(rExtrusion.fy) < 1.0/64.0) {
88 : 0 : aMX = DXFVector(0.0, 1.0, 0.0) * rExtrusion;
89 : : }
90 : : else {
91 : 0 : aMX = DXFVector(0.0, 0.0, 1.0) * rExtrusion;
92 : : }
93 : 0 : aMX=aMX.Unit();
94 : 0 : aMY=(rExtrusion*aMX).Unit();
95 : 0 : aMZ=rExtrusion.Unit();
96 : 0 : }
97 : :
98 : :
99 : 0 : DXFTransform::DXFTransform(const DXFVector & rViewDir, const DXFVector & rViewTarget) :
100 : 0 : aMX(), aMY(), aMZ(), aMP()
101 : : {
102 : 0 : DXFVector aV;
103 : :
104 : 0 : aV=rViewDir.Unit();
105 : 0 : aMX.fz=aV.fx;
106 : 0 : aMY.fz=aV.fy;
107 : 0 : aMZ.fz=aV.fz;
108 : :
109 : 0 : aMZ.fx=0;
110 : 0 : if (aV.fx==0) aMY.fx=0; else aMY.fx=sqrt(1/(1+aV.fy*aV.fy/(aV.fx*aV.fx)));
111 : 0 : aMX.fx=sqrt(1-aMY.fx*aMY.fx);
112 : 0 : if (aV.fx*aV.fy*aMY.fx>0) aMX.fx=-aMX.fx;
113 : :
114 : 0 : aV=aV*DXFVector(aMX.fx,aMY.fx,aMZ.fx);
115 : 0 : aMX.fy=aV.fx;
116 : 0 : aMY.fy=aV.fy;
117 : 0 : aMZ.fy=aV.fz;
118 : :
119 : 0 : if (aMZ.fy<0) {
120 : 0 : aMX.fy=-aMX.fy;
121 : 0 : aMY.fy=-aMY.fy;
122 : 0 : aMZ.fy=-aMZ.fy;
123 : 0 : aMX.fx=-aMX.fx;
124 : 0 : aMY.fx=-aMY.fx;
125 : : }
126 : :
127 : 0 : aV=DXFVector(0,0,0)-rViewTarget;
128 : 0 : aMP.fx = aV.fx * aMX.fx + aV.fy * aMY.fx + aV.fz * aMZ.fx;
129 : 0 : aMP.fy = aV.fx * aMX.fy + aV.fy * aMY.fy + aV.fz * aMZ.fy;
130 : 0 : aMP.fz = aV.fx * aMX.fz + aV.fy * aMY.fz + aV.fz * aMZ.fz;
131 : 0 : }
132 : :
133 : :
134 : 0 : DXFTransform::DXFTransform(const DXFTransform & rT1, const DXFTransform & rT2) :
135 : 0 : aMX(),aMY(),aMZ(),aMP()
136 : : {
137 : 0 : rT2.TransDir(rT1.aMX,aMX);
138 : 0 : rT2.TransDir(rT1.aMY,aMY);
139 : 0 : rT2.TransDir(rT1.aMZ,aMZ);
140 : 0 : rT2.Transform(rT1.aMP,aMP);
141 : 0 : }
142 : :
143 : :
144 : 0 : void DXFTransform::Transform(const DXFVector & rSrc, DXFVector & rTgt) const
145 : : {
146 : 0 : rTgt.fx = rSrc.fx * aMX.fx + rSrc.fy * aMY.fx + rSrc.fz * aMZ.fx + aMP.fx;
147 : 0 : rTgt.fy = rSrc.fx * aMX.fy + rSrc.fy * aMY.fy + rSrc.fz * aMZ.fy + aMP.fy;
148 : 0 : rTgt.fz = rSrc.fx * aMX.fz + rSrc.fy * aMY.fz + rSrc.fz * aMZ.fz + aMP.fz;
149 : 0 : }
150 : :
151 : :
152 : 0 : void DXFTransform::Transform(const DXFVector & rSrc, Point & rTgt) const
153 : : {
154 : 0 : rTgt.X()=(long)( rSrc.fx * aMX.fx + rSrc.fy * aMY.fx + rSrc.fz * aMZ.fx + aMP.fx + 0.5 );
155 : 0 : rTgt.Y()=(long)( rSrc.fx * aMX.fy + rSrc.fy * aMY.fy + rSrc.fz * aMZ.fy + aMP.fy + 0.5 );
156 : 0 : }
157 : :
158 : :
159 : 0 : void DXFTransform::TransDir(const DXFVector & rSrc, DXFVector & rTgt) const
160 : : {
161 : 0 : rTgt.fx = rSrc.fx * aMX.fx + rSrc.fy * aMY.fx + rSrc.fz * aMZ.fx;
162 : 0 : rTgt.fy = rSrc.fx * aMX.fy + rSrc.fy * aMY.fy + rSrc.fz * aMZ.fy;
163 : 0 : rTgt.fz = rSrc.fx * aMX.fz + rSrc.fy * aMY.fz + rSrc.fz * aMZ.fz;
164 : 0 : }
165 : :
166 : :
167 : 0 : sal_Bool DXFTransform::TransCircleToEllipse(double fRadius, double & rEx, double & rEy) const
168 : : {
169 : 0 : double fMXAbs=aMX.Abs();
170 : 0 : double fMYAbs=aMY.Abs();
171 : 0 : double fNearNull=(fMXAbs+fMYAbs)*0.001;
172 : :
173 : 0 : if (fabs(aMX.fy)<=fNearNull && fabs(aMX.fz)<=fNearNull &&
174 : 0 : fabs(aMY.fx)<=fNearNull && fabs(aMY.fz)<=fNearNull)
175 : : {
176 : 0 : rEx=fabs(aMX.fx*fRadius);
177 : 0 : rEy=fabs(aMY.fy*fRadius);
178 : 0 : return sal_True;
179 : : }
180 : 0 : else if (fabs(aMX.fx)<=fNearNull && fabs(aMX.fz)<=fNearNull &&
181 : 0 : fabs(aMY.fy)<=fNearNull && fabs(aMY.fz)<=fNearNull)
182 : : {
183 : 0 : rEx=fabs(aMY.fx*fRadius);
184 : 0 : rEy=fabs(aMX.fy*fRadius);
185 : 0 : return sal_True;
186 : : }
187 : 0 : else if (fabs(fMXAbs-fMYAbs)<=fNearNull &&
188 : 0 : fabs(aMX.fz)<=fNearNull && fabs(aMY.fz)<=fNearNull)
189 : : {
190 : 0 : rEx=rEy=fabs(((fMXAbs+fMYAbs)/2)*fRadius);
191 : 0 : return sal_True;
192 : : }
193 : 0 : else return sal_False;
194 : : }
195 : :
196 : 0 : LineInfo DXFTransform::Transform(const DXFLineInfo& aDXFLineInfo) const
197 : : {
198 : : double fex,fey,scale;
199 : :
200 : 0 : fex=sqrt(aMX.fx*aMX.fx + aMX.fy*aMX.fy);
201 : 0 : fey=sqrt(aMY.fx*aMY.fx + aMY.fy*aMY.fy);
202 : 0 : scale = (fex+fey)/2.0;
203 : :
204 : 0 : LineInfo aLineInfo;
205 : :
206 : 0 : aLineInfo.SetStyle( aDXFLineInfo.eStyle );
207 : 0 : aLineInfo.SetWidth( (sal_Int32) (aDXFLineInfo.fWidth * scale + 0.5) );
208 : 0 : aLineInfo.SetDashCount( static_cast< sal_uInt16 >( aDXFLineInfo.nDashCount ) );
209 : 0 : aLineInfo.SetDashLen( (sal_Int32) (aDXFLineInfo.fDashLen * scale + 0.5) );
210 : 0 : aLineInfo.SetDotCount( static_cast< sal_uInt16 >( aDXFLineInfo.nDotCount ) );
211 : 0 : aLineInfo.SetDotLen( (sal_Int32) (aDXFLineInfo.fDotLen * scale + 0.5) );
212 : 0 : aLineInfo.SetDistance( (sal_Int32) (aDXFLineInfo.fDistance * scale + 0.5) );
213 : :
214 : 0 : if ( aLineInfo.GetDashCount() > 0 && aLineInfo.GetDashLen() == 0 )
215 : 0 : aLineInfo.SetDashLen(1);
216 : :
217 : 0 : if ( aLineInfo.GetDotCount() > 0 && aLineInfo.GetDotLen() == 0 )
218 : 0 : aLineInfo.SetDotLen(1);
219 : :
220 : 0 : return aLineInfo;
221 : : }
222 : :
223 : 0 : sal_uLong DXFTransform::TransLineWidth(double fW) const
224 : : {
225 : : double fex,fey;
226 : :
227 : 0 : fex=sqrt(aMX.fx*aMX.fx + aMX.fy*aMX.fy);
228 : 0 : fey=sqrt(aMY.fx*aMY.fx + aMY.fy*aMY.fy);
229 : : // ###
230 : : // printf("fex=%f fey=%f\n", fex, fey);
231 : 0 : return (sal_uLong)(fabs(fW)*(fex+fey)/2.0+0.5);
232 : : }
233 : :
234 : :
235 : 0 : double DXFTransform::CalcRotAngle() const
236 : : {
237 : 0 : return atan2(aMX.fy,aMX.fx)/3.14159265359*180.0;
238 : : }
239 : :
240 : 0 : sal_Bool DXFTransform::Mirror() const
241 : : {
242 : 0 : if (aMZ.SProd(aMX*aMY)<0) return sal_True; else return sal_False;
243 : : }
244 : :
245 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|