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
29double 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
57DXFTransform::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
67DXFTransform::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(basegfx::deg2rad(fRotAngle));
76 aMX.fy=sin(basegfx::deg2rad(fRotAngle));
77 aMY.fx=-aMX.fy;
78 aMY.fy=aMX.fx;
79 aMX*=fScaleX;
80 aMY*=fScaleY;
81}
82
83
85 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
100DXFTransform::DXFTransform(const DXFVector & rViewDir, const DXFVector & rViewTarget)
101{
102 DXFVector aV;
103
104 aV=rViewDir.Unit();
105 aMX.fz=aV.fx;
106 aMY.fz=aV.fy;
107 aMZ.fz=aV.fz;
108
109 aMZ.fx=0;
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;
113
114 aV=aV*DXFVector(aMX.fx,aMY.fx,aMZ.fx);
115 aMX.fy=aV.fx;
116 aMY.fy=aV.fy;
117 aMZ.fy=aV.fz;
118
119 if (aMZ.fy<0) {
120 aMX.fy=-aMX.fy;
121 aMY.fy=-aMY.fy;
122 aMZ.fy=-aMZ.fy;
123 aMX.fx=-aMX.fx;
124 aMY.fx=-aMY.fx;
125 }
126
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;
131}
132
133
135{
136 rT2.TransDir(rT1.aMX,aMX);
137 rT2.TransDir(rT1.aMY,aMY);
138 rT2.TransDir(rT1.aMZ,aMZ);
139 rT2.Transform(rT1.aMP,aMP);
140}
141
142
143void DXFTransform::Transform(const DXFVector & rSrc, DXFVector & rTgt) const
144{
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;
148}
149
150
151void DXFTransform::Transform(const DXFVector & rSrc, Point & rTgt) const
152{
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 ) );
155}
156
157
158void DXFTransform::TransDir(const DXFVector & rSrc, DXFVector & rTgt) const
159{
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;
163}
164
165
166bool DXFTransform::TransCircleToEllipse(double fRadius, double & rEx, double & rEy) const
167{
168 double fMXAbs=aMX.Abs();
169 double fMYAbs=aMY.Abs();
170 double fNearNull=(fMXAbs+fMYAbs)*0.001;
171
172 if (fabs(aMX.fy)<=fNearNull && fabs(aMX.fz)<=fNearNull &&
173 fabs(aMY.fx)<=fNearNull && fabs(aMY.fz)<=fNearNull)
174 {
175 rEx=fabs(aMX.fx*fRadius);
176 rEy=fabs(aMY.fy*fRadius);
177 return true;
178 }
179 else if (fabs(aMX.fx)<=fNearNull && fabs(aMX.fz)<=fNearNull &&
180 fabs(aMY.fy)<=fNearNull && fabs(aMY.fz)<=fNearNull)
181 {
182 rEx=fabs(aMY.fx*fRadius);
183 rEy=fabs(aMX.fy*fRadius);
184 return true;
185 }
186 else if (fabs(fMXAbs-fMYAbs)<=fNearNull &&
187 fabs(aMX.fz)<=fNearNull && fabs(aMY.fz)<=fNearNull)
188 {
189 rEx=rEy=fabs(((fMXAbs+fMYAbs)/2)*fRadius);
190 return true;
191 }
192 else return false;
193}
194
196{
197 double fex,fey,scale;
198
199 fex=std::hypot(aMX.fx, aMX.fy);
200 fey=std::hypot(aMY.fx, aMY.fy);
201 scale = (fex+fey)/2.0;
202
203 LineInfo aLineInfo;
204
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 );
212
213 if ( aLineInfo.GetDashCount() > 0 && aLineInfo.GetDashLen() == 0 )
214 aLineInfo.SetDashLen(1);
215
216 if ( aLineInfo.GetDotCount() > 0 && aLineInfo.GetDotLen() == 0 )
217 aLineInfo.SetDotLen(1);
218
219 return aLineInfo;
220}
221
223{
224 return basegfx::rad2deg(atan2(aMX.fy,aMX.fx));
225}
226
228{
229 return aMZ.SProd(aMX*aMY)<0;
230}
231
232/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
sal_Int32 nDashCount
Definition: dxfvec.hxx:30
double fDashLen
Definition: dxfvec.hxx:31
LineStyle eStyle
Definition: dxfvec.hxx:29
sal_Int32 nDotCount
Definition: dxfvec.hxx:32
double fDistance
Definition: dxfvec.hxx:34
double fDotLen
Definition: dxfvec.hxx:33
DXFVector aMX
Definition: dxfvec.hxx:144
void TransDir(const DXFVector &rSrc, DXFVector &rTgt) const
Definition: dxfvec.cxx:158
DXFVector aMY
Definition: dxfvec.hxx:145
DXFVector aMZ
Definition: dxfvec.hxx:146
DXFVector aMP
Definition: dxfvec.hxx:147
void Transform(const DXFVector &rSrc, DXFVector &rTgt) const
Definition: dxfvec.cxx:143
DXFTransform()
Definition: dxfvec.cxx:48
bool Mirror() const
Definition: dxfvec.cxx:227
double CalcRotAngle() const
Definition: dxfvec.cxx:222
bool TransCircleToEllipse(double fRadius, double &rEx, double &rEy) const
Definition: dxfvec.cxx:166
DXFVector Unit() const
Definition: dxfvec.cxx:35
double fx
Definition: dxfvec.hxx:54
double SProd(const DXFVector &rV) const
Definition: dxfvec.hxx:189
double Abs() const
Definition: dxfvec.cxx:29
double fz
Definition: dxfvec.hxx:54
double fy
Definition: dxfvec.hxx:54
DXFVector(double fX=0.0, double fY=0.0, double fZ=0.0)
Definition: dxfvec.hxx:154
void setX(tools::Long nX)
void setY(tools::Long nY)
constexpr double rad2deg(double v)
constexpr double deg2rad(double v)
Unit
long Long
sal_Int32 scale