LibreOffice Module vcl (master)  1
dxfvec.cxx
Go to the documentation of this file.
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 #include <tools/gen.hxx>
24 
25 
26 //---------------------------- DXFVector ---------------------------------------
27 
28 
29 double DXFVector::Abs() const
30 {
31  return sqrt(SProd(*this));
32 }
33 
34 
36 {
37  double flen;
38 
39  flen=Abs();
40  if (flen!=0) return (*this)*(1.0/flen);
41  else return DXFVector(1.0,0.0,0.0);
42 }
43 
44 
45 //---------------------------- DXFTransform ------------------------------------
46 
47 
49  aMX(1.0, 0.0, 0.0),
50  aMY(0.0, 1.0, 0.0),
51  aMZ(0.0, 0.0, 1.0),
52  aMP(0.0, 0.0, 0.0)
53 {
54 }
55 
56 
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),
62  aMP(rShift)
63 {
64 }
65 
66 
67 DXFTransform::DXFTransform(double fScaleX, double fScaleY, double fScaleZ,
68  double fRotAngle,
69  const DXFVector & rShift) :
70  aMX(0.0, 0.0, 0.0),
71  aMY(0.0, 0.0, 0.0),
72  aMZ(0.0, 0.0, fScaleZ),
73  aMP(rShift)
74 {
75  aMX.fx=cos(3.14159265359/180.0*fRotAngle);
76  aMX.fy=sin(3.14159265359/180.0*fRotAngle);
77  aMY.fx=-aMX.fy;
78  aMY.fy=aMX.fx;
79  aMX*=fScaleX;
80  aMY*=fScaleY;
81 }
82 
83 
85  aMX(), aMY(), aMZ(), aMP(0.0, 0.0, 0.0)
86 {
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;
90  }
91  else {
92  aMX = DXFVector(0.0, 0.0, 1.0) * rExtrusion;
93  }
94  aMX=aMX.Unit();
95  aMY=(rExtrusion*aMX).Unit();
96  aMZ=rExtrusion.Unit();
97 }
98 
99 
100 DXFTransform::DXFTransform(const DXFVector & rViewDir, const DXFVector & rViewTarget) :
101  aMX(), aMY(), aMZ(), aMP()
102 {
103  DXFVector aV;
104 
105  aV=rViewDir.Unit();
106  aMX.fz=aV.fx;
107  aMY.fz=aV.fy;
108  aMZ.fz=aV.fz;
109 
110  aMZ.fx=0;
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;
114 
115  aV=aV*DXFVector(aMX.fx,aMY.fx,aMZ.fx);
116  aMX.fy=aV.fx;
117  aMY.fy=aV.fy;
118  aMZ.fy=aV.fz;
119 
120  if (aMZ.fy<0) {
121  aMX.fy=-aMX.fy;
122  aMY.fy=-aMY.fy;
123  aMZ.fy=-aMZ.fy;
124  aMX.fx=-aMX.fx;
125  aMY.fx=-aMY.fx;
126  }
127 
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;
132 }
133 
134 
136  aMX(),aMY(),aMZ(),aMP()
137 {
138  rT2.TransDir(rT1.aMX,aMX);
139  rT2.TransDir(rT1.aMY,aMY);
140  rT2.TransDir(rT1.aMZ,aMZ);
141  rT2.Transform(rT1.aMP,aMP);
142 }
143 
144 
145 void DXFTransform::Transform(const DXFVector & rSrc, DXFVector & rTgt) const
146 {
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;
150 }
151 
152 
153 void DXFTransform::Transform(const DXFVector & rSrc, Point & rTgt) const
154 {
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 ) );
157 }
158 
159 
160 void DXFTransform::TransDir(const DXFVector & rSrc, DXFVector & rTgt) const
161 {
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;
165 }
166 
167 
168 bool DXFTransform::TransCircleToEllipse(double fRadius, double & rEx, double & rEy) const
169 {
170  double fMXAbs=aMX.Abs();
171  double fMYAbs=aMY.Abs();
172  double fNearNull=(fMXAbs+fMYAbs)*0.001;
173 
174  if (fabs(aMX.fy)<=fNearNull && fabs(aMX.fz)<=fNearNull &&
175  fabs(aMY.fx)<=fNearNull && fabs(aMY.fz)<=fNearNull)
176  {
177  rEx=fabs(aMX.fx*fRadius);
178  rEy=fabs(aMY.fy*fRadius);
179  return true;
180  }
181  else if (fabs(aMX.fx)<=fNearNull && fabs(aMX.fz)<=fNearNull &&
182  fabs(aMY.fy)<=fNearNull && fabs(aMY.fz)<=fNearNull)
183  {
184  rEx=fabs(aMY.fx*fRadius);
185  rEy=fabs(aMX.fy*fRadius);
186  return true;
187  }
188  else if (fabs(fMXAbs-fMYAbs)<=fNearNull &&
189  fabs(aMX.fz)<=fNearNull && fabs(aMY.fz)<=fNearNull)
190  {
191  rEx=rEy=fabs(((fMXAbs+fMYAbs)/2)*fRadius);
192  return true;
193  }
194  else return false;
195 }
196 
197 LineInfo DXFTransform::Transform(const DXFLineInfo& aDXFLineInfo) const
198 {
199  double fex,fey,scale;
200 
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;
204 
205  LineInfo aLineInfo;
206 
207  aLineInfo.SetStyle( aDXFLineInfo.eStyle );
208  aLineInfo.SetWidth( 0 );
209  aLineInfo.SetDashCount( static_cast< sal_uInt16 >( aDXFLineInfo.nDashCount ) );
210  aLineInfo.SetDashLen( static_cast<sal_Int32>(aDXFLineInfo.fDashLen * scale + 0.5) );
211  aLineInfo.SetDotCount( static_cast< sal_uInt16 >( aDXFLineInfo.nDotCount ) );
212  aLineInfo.SetDotLen( static_cast<sal_Int32>(aDXFLineInfo.fDotLen * scale + 0.5) );
213  aLineInfo.SetDistance( static_cast<sal_Int32>(aDXFLineInfo.fDistance * scale + 0.5) );
214 
215  if ( aLineInfo.GetDashCount() > 0 && aLineInfo.GetDashLen() == 0 )
216  aLineInfo.SetDashLen(1);
217 
218  if ( aLineInfo.GetDotCount() > 0 && aLineInfo.GetDotLen() == 0 )
219  aLineInfo.SetDotLen(1);
220 
221  return aLineInfo;
222 }
223 
225 {
226  return atan2(aMX.fy,aMX.fx)/3.14159265359*180.0;
227 }
228 
230 {
231  return aMZ.SProd(aMX*aMY)<0;
232 }
233 
234 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
double fx
Definition: dxfvec.hxx:55
void Transform(const DXFVector &rSrc, DXFVector &rTgt) const
Definition: dxfvec.cxx:145
double fDashLen
Definition: dxfvec.hxx:32
double fz
Definition: dxfvec.hxx:55
DXFVector Unit() const
Definition: dxfvec.cxx:35
sal_Int32 nDashCount
Definition: dxfvec.hxx:31
sal_Int32 nDotCount
Definition: dxfvec.hxx:33
double fDotLen
Definition: dxfvec.hxx:34
double fDistance
Definition: dxfvec.hxx:35
Unit
double CalcRotAngle() const
Definition: dxfvec.cxx:224
DXFVector aMP
Definition: dxfvec.hxx:148
void TransDir(const DXFVector &rSrc, DXFVector &rTgt) const
Definition: dxfvec.cxx:160
sal_Int32 scale
double fy
Definition: dxfvec.hxx:55
DXFVector aMZ
Definition: dxfvec.hxx:147
DXFVector(double fX=0.0, double fY=0.0, double fZ=0.0)
Definition: dxfvec.hxx:155
double Abs() const
Definition: dxfvec.cxx:29
double SProd(const DXFVector &rV) const
Definition: dxfvec.hxx:190
DXFVector aMX
Definition: dxfvec.hxx:145
LineStyle eStyle
Definition: dxfvec.hxx:30
bool TransCircleToEllipse(double fRadius, double &rEx, double &rEy) const
Definition: dxfvec.cxx:168
DXFTransform()
Definition: dxfvec.cxx:48
bool Mirror() const
Definition: dxfvec.cxx:229
DXFVector aMY
Definition: dxfvec.hxx:146