17 #endif //wxART2D_USE_CVGIO
31 #if defined(__VISUALC__)
36 #pragma warning(disable: 4660)
43 #pragma warning(default: 4660)
58 double c = cos( angle );
59 double s = sin( angle );
61 m_matrix[0][0] = c * scalex;
62 m_matrix[1][0] = -s * scaley;
64 m_matrix[0][1] = s * scalex;
65 m_matrix[1][1] = c * scaley;
71 m_matrix[0][0] = scalex;
75 m_matrix[1][1] = scaley;
79 m_isIdentity = IsIdentity1();
108 if ( row < 0 || row > 1 || col < 0 || col > 2 )
116 if ( row < 0 || row > 1 || col < 0 || col > 2 )
153 return ( ! ( a == b ) );
170 return ( ! ( *
this == a ) );
176 if ( row < 0 || row > 1 || col < 0 || col > 2 )
184 if ( row < 0 || row > 1 || col < 0 || col > 2 )
193 return a11 * a22 - a12 * a21;
202 double inverseMatrix[3][2];
208 inverseMatrix[0][0] = m_matrix[1][1];
209 inverseMatrix[0][1] = -m_matrix[0][1];
212 inverseMatrix[1][0] = -m_matrix[1][0];
213 inverseMatrix[1][1] = m_matrix[0][0];
215 inverseMatrix[2][0] = m_matrix[1][0] * m_matrix[2][1] - m_matrix[2][0] * m_matrix[1][1];
216 inverseMatrix[2][1] = -( m_matrix[0][0] * m_matrix[2][1] - m_matrix[2][0] * m_matrix[0][1] );
218 inverseMatrix[0][0] /= det; inverseMatrix[1][0] /= det; inverseMatrix[2][0] /= det;
219 inverseMatrix[0][1] /= det; inverseMatrix[1][1] /= det; inverseMatrix[2][1] /= det;
222 for ( i = 0; i < 3; i++ )
224 for ( j = 0; j < 2; j++ )
226 m_matrix[i][j] = inverseMatrix[i][j];
233 else if( m_matrix[0][0] && !m_matrix[1][0] && !m_matrix[0][1] && !m_matrix[1][1] )
236 m_matrix[0][0] = 1 / m_matrix[0][0];
237 m_matrix[2][0] = -m_matrix[0][0] * m_matrix[2][0];
238 m_matrix[2][1] = -m_matrix[2][1];
241 else if( !m_matrix[0][0] && !m_matrix[1][0] && !m_matrix[0][1] && m_matrix[1][1] )
244 m_matrix[1][1] = 1 / m_matrix[1][1];
245 m_matrix[2][1] = -m_matrix[1][1] * m_matrix[2][1];
246 m_matrix[2][0] = -m_matrix[2][0];
273 for ( i = 0; i < 3; i++ )
275 for ( j = 0; j < 2; j++ )
298 for ( i = 0; i < 2; i++ )
300 for ( j = 0; j < 2; j++ )
302 m_matrix[i][j] /= scale;
305 for ( j = 0; j < 2; j++ )
307 double scaleJ = sqrt( m_matrix[0][j] * m_matrix[0][j] + m_matrix[1][j] * m_matrix[1][j] );
308 wxASSERT_MSG( scaleJ != 0, wxT(
"matrix scaleJ == 0 !" ) );
309 m_matrix[0][j] /= scaleJ;
310 m_matrix[1][j] /= scaleJ;
316 wxASSERT_MSG( scale != 0, wxT(
"matrix determinant == 0 !" ) );
329 double r00, r10, r20, r01, r11, r21;
333 double tx = xc * ( 1 - xs );
334 double ty = yc * ( 1 - ys );
342 else if ( xc != 0 || yc != 0 )
344 double tx = xc * ( 1 - xs );
345 double ty = yc * ( 1 - ys );
347 r10 = xs * m_matrix[1][0];
348 r20 = xs * m_matrix[2][0] + tx;
349 r01 = ys * m_matrix[0][1];
350 r11 = ys * m_matrix[1][1];
351 r21 = ys * m_matrix[2][1] + ty;
356 r10 = xs * m_matrix[1][0];
357 r20 = xs * m_matrix[2][0];
358 r01 = ys * m_matrix[0][1];
359 r11 = ys * m_matrix[1][1];
360 r21 = ys * m_matrix[2][1];
410 *
this = temp * ( *this );
446 double angle = degrees *
wxPI / 180.0;
447 double t = tan( angle );
454 *
this = skew * ( *this );
465 double angle = degrees *
wxPI / 180.0;
466 double t = tan( angle );
473 *
this = skew * ( *this );
490 double c = cos( angle );
491 double s = sin( angle );
492 double r00, r10, r20, r01, r11, r21;
496 double tx = x * ( 1 - c ) + y * s;
497 double ty = y * ( 1 - c ) - x * s;
505 else if ( x != 0 || y != 0 )
507 double tx = x * ( 1 - c ) + y * s;
508 double ty = y * ( 1 - c ) - x * s;
510 r10 = c * m_matrix[1][0] - s * m_matrix[1][1];
511 r20 = c * m_matrix[2][0] - s * m_matrix[2][1] + tx;
512 r01 = c * m_matrix[0][1] + s * m_matrix[0][0];
513 r11 = c * m_matrix[1][1] + s * m_matrix[1][0];
514 r21 = c * m_matrix[2][1] + s * m_matrix[2][0] + ty;
519 r10 = c * m_matrix[1][0] - s * m_matrix[1][1];
520 r20 = c * m_matrix[2][0] - s * m_matrix[2][1];
521 r01 = c * m_matrix[0][1] + s * m_matrix[0][0];
522 r11 = c * m_matrix[1][1] + s * m_matrix[1][0];
523 r21 = c * m_matrix[2][1] + s * m_matrix[2][0];
563 tx = x; ty = y;
return;
567 ty = x * m_matrix[0][1] + y * m_matrix[1][1] + m_matrix[2][1];
577 ty = tx * m_matrix[0][1] + ty * m_matrix[1][1] + m_matrix[2][1];
586 point->m_y = point->m_x * m_matrix[0][1] + point->m_y * m_matrix[1][1] + m_matrix[2][1];
599 dest->m_y = src.m_x * m_matrix[0][1] + src.m_y * m_matrix[1][1] + m_matrix[2][1];
606 tdx = dx; tdy = dy;
return;
613 tdy = dx * m_matrix[0][1] + dy * m_matrix[1][1];
633 sqrt( m_matrix[1][0] * m_matrix[1][0] + m_matrix[1][1] * m_matrix[1][1] ) * distance );
650 double yt = dx * m_matrix[0][1] + dy * m_matrix[1][1];
667 for (
int i = 0; i < 2; i++ )
703 for (
int i = 0; i < 2; i++ )
771 if ( scale_factor < 0 )
772 scale_factor = -scale_factor;
793 if ( scale_factor < 0 )
794 scale_factor = -scale_factor;
808 double rot_angle = atan2( temp2, temp1 ) * 180 /
wxPI;
809 if ( rot_angle == -180.0 )
870 wxLogDebug( wxT(
"a00=%12.6lf, a01=%12.6lf" ),
m_matrix[0][0],
m_matrix[0][1] );
871 wxLogDebug( wxT(
"a10=%12.6lf, a11=%12.6lf" ),
m_matrix[1][0],
m_matrix[1][1] );
872 wxLogDebug( wxT(
"a20=%12.6lf. a21=%12.6lf" ),
m_matrix[2][0],
m_matrix[2][1] );
873 wxLogDebug( wxT(
"w =%12.6lf, h =%12.6lf" ), w, h );
874 wxLogDebug( wxT(
"cx =%12.6lf, cy =%12.6lf" ),
878 wxLogDebug( wxT(
"lx =%12.6lf, ly =%12.6lf" ),
880 h * sqrt( m_matrix[1][0] * m_matrix[1][0] + m_matrix[1][1] * m_matrix[1][1] )
882 wxLogDebug( wxT(
"\n" ) );
892 if ( str == wxT(
"" ) )
896 double matrixcoef[12];
901 for ( i = 0; i < str.Len(); i++ )
904 while ( wxIsspace( str[i] ) ) i++;
909 while ( i < str.Len() && isalpha ( str[i] ) )
911 keywstr += str.GetChar( i );
916 while ( wxIsspace( str[i] ) ) i++;
918 if ( str[i] != wxT(
'(' ) )
920 error = _(
"CVG parsing error: missing" );
925 while ( wxIsspace( str[i] ) ) i++;
927 while ( i < str.Len() && str[i] != wxT(
')' ) )
930 while ( i < str.Len() && ( isdigit( str[i] ) || str[i] == wxT(
'+' ) || str[i] == wxT(
'-' ) || str[i] == wxT(
'.' ) || str[i] == wxT(
'e' ) || str[i] == wxT(
'E' ) ) )
932 numstr += str.GetChar( i );
935 numstr.ToDouble( &matrixcoef[nr_matrixcoef] );
937 while ( i < str.Len() && ( wxIsspace( str[i] ) || str[i] == wxT(
',' ) ) ) i++;
940 if ( str[i] != wxT(
')' ) )
942 error = _(
"CVG parsing error: missing" );
947 if ( keywstr == wxT(
"matrix" ) )
949 if ( nr_matrixcoef != 6 )
951 error.Printf( _(
"CVG : wrong number of arguments %s " ), keywstr.c_str() );
954 matrix.
SetValue( 0, 0, matrixcoef[0] );
955 matrix.
SetValue( 0, 1, matrixcoef[1] );
956 matrix.
SetValue( 1, 0, matrixcoef[2] );
957 matrix.
SetValue( 1, 1, matrixcoef[3] );
958 matrix.
SetValue( 2, 0, matrixcoef[4] );
959 matrix.
SetValue( 2, 1, matrixcoef[5] );
961 else if ( keywstr == wxT(
"translate" ) )
963 if ( nr_matrixcoef == 1 )
965 else if ( nr_matrixcoef != 2 )
967 error.Printf( _(
"CVG : wrong number of arguments %s " ), keywstr.c_str() );
971 matrix.
Translate( matrixcoef[0] , matrixcoef[1] );
973 else if ( keywstr == wxT(
"scale" ) )
975 if ( nr_matrixcoef == 1 )
977 else if ( nr_matrixcoef != 2 )
979 error.Printf( _(
"CVG : wrong number of arguments %s " ), keywstr.c_str() );
985 else if ( keywstr == wxT(
"rotate" ) )
987 if ( nr_matrixcoef != 1 )
989 error.Printf( _(
"CVG : wrong number of arguments %s " ), keywstr.c_str() );
992 matrix.
Rotate( matrixcoef[0] );
994 else if ( keywstr == wxT(
"skewX" ) )
996 if ( nr_matrixcoef != 1 )
998 error.Printf( _(
"CVG : wrong number of arguments %s " ), keywstr.c_str() );
1001 matrix.
SkewX( matrixcoef[0] );
1003 else if ( keywstr == wxT(
"skewY" ) )
1005 if ( nr_matrixcoef != 1 )
1007 error.Printf( _(
"CVG : wrong number of arguments %s " ), keywstr.c_str() );
1010 matrix.
SkewY( matrixcoef[0] );
1012 else if ( keywstr == wxT(
"flipX" ) )
1014 if ( nr_matrixcoef != 0 )
1016 error.Printf( _(
"CVG : wrong number of arguments %s " ), keywstr.c_str() );
1019 matrix.
Mirror(
true,
false );
1021 else if ( keywstr == wxT(
"flipY" ) )
1023 if ( nr_matrixcoef != 0 )
1025 error.Printf( _(
"CVG : wrong number of arguments %s " ), keywstr.c_str() );
1028 matrix.
Mirror(
false,
true );
1032 error.Printf( _(
"CVG : invalid transform %s " ), keywstr.c_str() );
1055 m_value = ori->m_value;
1058 a2dMatrixProperty::~a2dMatrixProperty()
1064 m_value = other.m_value;
1075 m_value = propcast->m_value;
1078 #if wxART2D_USE_CVGIO
1081 a2dNamedProperty::DoSave( parent, out, xmlparts, towrite );
1082 if ( xmlparts == a2dXmlSer_attrib )
1085 s.Printf ( _T(
"matrix( %g %g %g %g %g %g )" ),
1090 out.WriteAttribute( wxT(
"transform" ), s );
1096 void a2dMatrixProperty::DoLoad( wxObject* parent,
a2dIOHandlerXmlSerIn& parser, a2dXmlSer_flag xmlparts )
1098 a2dNamedProperty::DoLoad( parent, parser, xmlparts );
1099 if ( xmlparts == a2dXmlSer_attrib )
1111 #endif //wxART2D_USE_CVGIO
1121 s.Printf ( wxT(
"%s = matrix( %g %g %g %g %g %g )" ),
m_id->
GetName().c_str(),
1133 s.Printf ( _T(
"matrix( %g %g %g %g %g %g )" ),
1204 #if wxART2D_USE_CVGIO
1207 a2dNamedProperty::DoSave( parent, out, xmlparts, towrite );
1208 if ( xmlparts == a2dXmlSer_attrib )
1218 a2dNamedProperty::DoLoad( parent, parser, xmlparts );
1219 if ( xmlparts == a2dXmlSer_attrib )
1223 if ( !str.IsEmpty() )
1231 #endif //wxART2D_USE_CVGIO
1256 s << wxT(
"false" );
1269 s << wxT(
"false" );
wxPoint2DDouble a2dPoint2D
this to define if coordinate numbers are integer or doubles
a2dPoint2DProperty()
constructor
a2dAffineMatrix & Mirror(bool y=true, bool x=false)
mirror a matrix in x, y
(In) Visible property that can be added to Docview Objects.
double m_matrix[3][2]
array store the six double for the affine matrix
property to hold a a2dAffineMatrix
bool RemoveScale()
Remove Scale:
virtual wxString StringRepresentation() const
a string form presentation for this property
bool IsIdentity1(void) const
This does an actual check.
virtual wxString GetName() const
Get the ids print and serialization name.
virtual void Assign(const a2dNamedProperty &other)
Virtual assignment operator.
static a2dPoint2DProperty * CreatePropertyFromString(const a2dPropertyIdPoint2D *id, const wxString &value)
const a2dPropertyId * m_id
The property id object identifying this property.
bool Rotate(double angle)
Rotate clockwise by the given number of degrees:
double wxDegToRad(double deg)
conversion from degrees to radians
virtual int GetCurrentLineNumber()
where in the input was line the current tag
bool IsIdentity(void) const
Is the matrix the identity matrix?
Input and output handler for the XmlSer format.
void TransformVector(double dx, double dy, double &tdx, double &tdy) const
Transform a vector.
double GetValue(int col, int row) const
get the value in the matrix at col,row
bool ParseCvgTransForm(a2dAffineMatrix &matrix, const wxString &str, wxString &error)
function to parse a string in SVG/CVG format and return the resulting matrix
a2dAffineMatrix operator-(const a2dAffineMatrix &a)
subtract two matrices
bool SkewX(double degrees)
Skew Xaxis:
void operator=(const a2dAffineMatrix &mat)
make the same
friend bool operator==(const a2dAffineMatrix &a, const a2dAffineMatrix &b)
are they eqaul
a2dAffineMatrix a2dIDENTITY_MATRIX
global a2dAffineMatrix to set/pass the identity matrix.
property to hold a a2dPoint2D plus an index in e.g a polygon.
static a2dMatrixProperty * CreatePropertyFromString(const a2dPropertyIdMatrix *id, const wxString &value)
double GetDeterminant2() const
Calculate the determinat of the transformed x-axis vector and the shift vector.
void TransformPoint(double x, double y, double &tx, double &ty) const
Transform a point.
bool m_isIdentity
true if identity matrix
virtual void Assign(const a2dNamedProperty &other)
Virtual assignment operator.
double GetRotation() const
return rotation
double TransformDistance(double distance) const
Transform a distance.
static const a2dAffineMatrix sm_Identity
A static identity matrix in case an identity matrix is to be returned as reference.
XML I/O classes which is Pull parser based for reading XML files.
double wxCalculateDet(double a11, double a21, double a12, double a22)
Calculates the determinant of a 2 x 2 matrix.
a2dPoint2D m_value
the point that is held within this property
a2dAffineMatrix operator*(const a2dAffineMatrix &m) const
multiply this by matrix m and return result
virtual ~a2dPoint2DProperty()
destructor
a2dAffineMatrix & operator*=(const a2dAffineMatrix &m)
multiply matrix m with this
double GetMaximum2() const
Calculate the maximum absolute of the elemnts entering GetDeterminant2.
const a2dError a2dError_XMLparse
#define wxStaticCast(obj, className)
The wxWindows 2.4.2 wxStaticCast is buggy. It evaluates its argument twice.
A2DGENERALDLLEXP a2dSmrtPtr< a2dGeneralGlobal > a2dGeneralGlobals
a global pointer to get to global instance of important classes.
bool SkewY(double degrees)
Skew Yaxis:
Input and output handler for the XmlSer format.
virtual wxString StringRepresentation() const
bool Identity(void)
Make into identity matrix.
a2dAffineMatrix(void)
constructor (makes an identity matrix)
A 2x3 affine matrix class for 2D transformations.
virtual wxString StringValueRepresentation() const
a string value presentation for this property
void DebugDump(const wxChar *text, double w, double h) const
Dump the Matrix to a debug window.
double GetMaximum() const
Calculate the maximum absolute of the elemnts entering GetDeterminant.
virtual wxString StringValueRepresentation() const
double GetDeterminant1() const
Calculate the determinat of the shift vector and the transformed y-axis vector.
double GetMaximum1() const
Calculate the maximum absolute of the elemnts entering GetDeterminant1.
double Get_scaleX() const
return scaling in X
general modules header files all together.
wxString GetAttributeValue(const wxString &attrib, const wxString &defaultv=wxT(""))
Returns the value of an attribute.
virtual void DoLoad(wxObject *parent, a2dIOHandlerXmlSerIn &parser, a2dXmlSer_flag xmlparts)
bool Scale(double scale)
Scale by scale (isotropic scaling i.e. the same in x and y):
bool Translate(double x, double y)
Translate by dx, dy:
a2dAffineMatrix operator-(const a2dAffineMatrix &a, const a2dAffineMatrix &b)
matrixes subtract
bool Invert(void)
Invert matrix.
double GetDeterminant() const
Calculate the determinat of the linear transformation.
void SetValue(int col, int row, double value)
set the value in the matrix at col,row
double Get_scaleY() const
return scaling in Y
double & operator()(int col, int row)
This template class is for property ids with a known data type.
void SetValue(double x, double y, int index=0, bool afterinversion=false)
set the property information to this
void SetRotation(double rotation)
set rotation
CloneOptions
options for cloning
a2dNamedProperty * Clone(a2dObject::CloneOptions options) const
clone
wxInt32 m_index
Can be used as position to insert a point into a polygon.
const double wxPI
defines PI
friend bool operator!=(const a2dAffineMatrix &a, const a2dAffineMatrix &b)
are they NOT eqaul