blob: fb0db285314769ae9362784a11d4767832a9eb2b [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_filter.hxx"
#include <math.h>
#include <dxfvec.hxx>
//---------------------------- DXFVector ---------------------------------------
double DXFVector::Abs() const
{
return sqrt(SProd(*this));
}
DXFVector DXFVector::Unit() const
{
double flen;
flen=Abs();
if (flen!=0) return (*this)*(1.0/flen);
else return DXFVector(1.0,0.0,0.0);
}
//---------------------------- DXFTransform ------------------------------------
DXFTransform::DXFTransform() :
aMX(1.0, 0.0, 0.0),
aMY(0.0, 1.0, 0.0),
aMZ(0.0, 0.0, 1.0),
aMP(0.0, 0.0, 0.0)
{
}
DXFTransform::DXFTransform(double fScaleX, double fScaleY, double fScaleZ,
const DXFVector & rShift) :
aMX(fScaleX, 0.0, 0.0),
aMY(0.0, fScaleY, 0.0),
aMZ(0.0, 0.0, fScaleZ),
aMP(rShift)
{
}
DXFTransform::DXFTransform(double fScaleX, double fScaleY, double fScaleZ,
double fRotAngle,
const DXFVector & rShift) :
aMX(0.0, 0.0, 0.0),
aMY(0.0, 0.0, 0.0),
aMZ(0.0, 0.0, fScaleZ),
aMP(rShift)
{
aMX.fx=cos(3.14159265359/180.0*fRotAngle);
aMX.fy=sin(3.14159265359/180.0*fRotAngle);
aMY.fx=-aMX.fy;
aMY.fy=aMX.fx;
aMX*=fScaleX;
aMY*=fScaleY;
}
DXFTransform::DXFTransform(const DXFVector & rExtrusion) :
aMX(), aMY(), aMZ(), aMP(0.0, 0.0, 0.0)
{
// 'Arbitrary Axis Algorithm' (siehe DXF-Doku von Autodesk)
if ( fabs(rExtrusion.fx) < 1.0/64.0 && fabs(rExtrusion.fy) < 1.0/64.0) {
aMX = DXFVector(0.0, 1.0, 0.0) * rExtrusion;
}
else {
aMX = DXFVector(0.0, 0.0, 1.0) * rExtrusion;
}
aMX=aMX.Unit();
aMY=(rExtrusion*aMX).Unit();
aMZ=rExtrusion.Unit();
}
DXFTransform::DXFTransform(const DXFVector & rViewDir, const DXFVector & rViewTarget) :
aMX(), aMY(), aMZ(), aMP()
{
DXFVector aV;
aV=rViewDir.Unit();
aMX.fz=aV.fx;
aMY.fz=aV.fy;
aMZ.fz=aV.fz;
aMZ.fx=0;
if (aV.fx==0) aMY.fx=0; else aMY.fx=sqrt(1/(1+aV.fy*aV.fy/(aV.fx*aV.fx)));
aMX.fx=sqrt(1-aMY.fx*aMY.fx);
if (aV.fx*aV.fy*aMY.fx>0) aMX.fx=-aMX.fx;
aV=aV*DXFVector(aMX.fx,aMY.fx,aMZ.fx);
aMX.fy=aV.fx;
aMY.fy=aV.fy;
aMZ.fy=aV.fz;
if (aMZ.fy<0) {
aMX.fy=-aMX.fy;
aMY.fy=-aMY.fy;
aMZ.fy=-aMZ.fy;
aMX.fx=-aMX.fx;
aMY.fx=-aMY.fx;
}
aV=DXFVector(0,0,0)-rViewTarget;
aMP.fx = aV.fx * aMX.fx + aV.fy * aMY.fx + aV.fz * aMZ.fx;
aMP.fy = aV.fx * aMX.fy + aV.fy * aMY.fy + aV.fz * aMZ.fy;
aMP.fz = aV.fx * aMX.fz + aV.fy * aMY.fz + aV.fz * aMZ.fz;
}
DXFTransform::DXFTransform(const DXFTransform & rT1, const DXFTransform & rT2) :
aMX(),aMY(),aMZ(),aMP()
{
rT2.TransDir(rT1.aMX,aMX);
rT2.TransDir(rT1.aMY,aMY);
rT2.TransDir(rT1.aMZ,aMZ);
rT2.Transform(rT1.aMP,aMP);
}
void DXFTransform::Transform(const DXFVector & rSrc, DXFVector & rTgt) const
{
rTgt.fx = rSrc.fx * aMX.fx + rSrc.fy * aMY.fx + rSrc.fz * aMZ.fx + aMP.fx;
rTgt.fy = rSrc.fx * aMX.fy + rSrc.fy * aMY.fy + rSrc.fz * aMZ.fy + aMP.fy;
rTgt.fz = rSrc.fx * aMX.fz + rSrc.fy * aMY.fz + rSrc.fz * aMZ.fz + aMP.fz;
}
void DXFTransform::Transform(const DXFVector & rSrc, Point & rTgt) const
{
rTgt.X()=(long)( rSrc.fx * aMX.fx + rSrc.fy * aMY.fx + rSrc.fz * aMZ.fx + aMP.fx + 0.5 );
rTgt.Y()=(long)( rSrc.fx * aMX.fy + rSrc.fy * aMY.fy + rSrc.fz * aMZ.fy + aMP.fy + 0.5 );
}
void DXFTransform::TransDir(const DXFVector & rSrc, DXFVector & rTgt) const
{
rTgt.fx = rSrc.fx * aMX.fx + rSrc.fy * aMY.fx + rSrc.fz * aMZ.fx;
rTgt.fy = rSrc.fx * aMX.fy + rSrc.fy * aMY.fy + rSrc.fz * aMZ.fy;
rTgt.fz = rSrc.fx * aMX.fz + rSrc.fy * aMY.fz + rSrc.fz * aMZ.fz;
}
sal_Bool DXFTransform::TransCircleToEllipse(double fRadius, double & rEx, double & rEy) const
{
double fMXAbs=aMX.Abs();
double fMYAbs=aMY.Abs();
double fNearNull=(fMXAbs+fMYAbs)*0.001;
if (fabs(aMX.fy)<=fNearNull && fabs(aMX.fz)<=fNearNull &&
fabs(aMY.fx)<=fNearNull && fabs(aMY.fz)<=fNearNull)
{
rEx=fabs(aMX.fx*fRadius);
rEy=fabs(aMY.fy*fRadius);
return sal_True;
}
else if (fabs(aMX.fx)<=fNearNull && fabs(aMX.fz)<=fNearNull &&
fabs(aMY.fy)<=fNearNull && fabs(aMY.fz)<=fNearNull)
{
rEx=fabs(aMY.fx*fRadius);
rEy=fabs(aMX.fy*fRadius);
return sal_True;
}
else if (fabs(fMXAbs-fMYAbs)<=fNearNull &&
fabs(aMX.fz)<=fNearNull && fabs(aMY.fz)<=fNearNull)
{
rEx=rEy=fabs(((fMXAbs+fMYAbs)/2)*fRadius);
return sal_True;
}
else return sal_False;
}
LineInfo DXFTransform::Transform(const DXFLineInfo& aDXFLineInfo) const
{
double fex,fey,scale;
fex=sqrt(aMX.fx*aMX.fx + aMX.fy*aMX.fy);
fey=sqrt(aMY.fx*aMY.fx + aMY.fy*aMY.fy);
scale = (fex+fey)/2.0;
LineInfo aLineInfo;
aLineInfo.SetStyle( aDXFLineInfo.eStyle );
aLineInfo.SetWidth( (sal_Int32) (aDXFLineInfo.fWidth * scale + 0.5) );
aLineInfo.SetDashCount( static_cast< sal_uInt16 >( aDXFLineInfo.nDashCount ) );
aLineInfo.SetDashLen( (sal_Int32) (aDXFLineInfo.fDashLen * scale + 0.5) );
aLineInfo.SetDotCount( static_cast< sal_uInt16 >( aDXFLineInfo.nDotCount ) );
aLineInfo.SetDotLen( (sal_Int32) (aDXFLineInfo.fDotLen * scale + 0.5) );
aLineInfo.SetDistance( (sal_Int32) (aDXFLineInfo.fDistance * scale + 0.5) );
if ( aLineInfo.GetDashCount() > 0 && aLineInfo.GetDashLen() == 0 )
aLineInfo.SetDashLen(1);
if ( aLineInfo.GetDotCount() > 0 && aLineInfo.GetDotLen() == 0 )
aLineInfo.SetDotLen(1);
return aLineInfo;
}
sal_uLong DXFTransform::TransLineWidth(double fW) const
{
double fex,fey;
fex=sqrt(aMX.fx*aMX.fx + aMX.fy*aMX.fy);
fey=sqrt(aMY.fx*aMY.fx + aMY.fy*aMY.fy);
// ###
// printf("fex=%f fey=%f\n", fex, fey);
return (sal_uLong)(fabs(fW)*(fex+fey)/2.0+0.5);
}
double DXFTransform::CalcRotAngle() const
{
return atan2(aMX.fy,aMX.fx)/3.14159265359*180.0;
}
sal_Bool DXFTransform::Mirror() const
{
if (aMZ.SProd(aMX*aMY)<0) return sal_True; else return sal_False;
}