c97a6f28b8a7fe7a0c24a1d5efe9c0324e9b45c2
[occt.git] / src / gp / gp_Mat2d.cxx
1 // Copyright (c) 1995-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 //
4 // This file is part of Open CASCADE Technology software library.
5 //
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
11 //
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
14
15 //  10/09/97 : PMN : Correction BUC40192 (pb avec les matrices negatives)
16
17 #ifndef OCCT_DEBUG
18 #define No_Standard_OutOfRange
19 #define No_Standard_ConstructionError
20 #endif
21
22
23 #include <gp_GTrsf2d.hxx>
24 #include <gp_Mat2d.hxx>
25 #include <gp_Trsf2d.hxx>
26 #include <gp_XY.hxx>
27 #include <Standard_ConstructionError.hxx>
28 #include <Standard_OutOfRange.hxx>
29
30 #define M00 ((Standard_Real*)M)[0]
31 #define M01 ((Standard_Real*)M)[1]
32 #define M10 ((Standard_Real*)M)[2]
33 #define M11 ((Standard_Real*)M)[3]
34
35 #define N00 ((Standard_Real*)N)[0]
36 #define N01 ((Standard_Real*)N)[1]
37 #define N10 ((Standard_Real*)N)[2]
38 #define N11 ((Standard_Real*)N)[3]
39
40 gp_Mat2d::gp_Mat2d (const gp_XY& Col1, const gp_XY& Col2)
41 {
42   const Standard_Address M = (Standard_Address)&(matrix[0][0]);
43   M00 = Col1.X(); M10 = Col1.Y();
44   M01 = Col2.X(); M11 = Col2.Y();
45 }
46
47 void gp_Mat2d::SetCol (const Standard_Integer Col,
48                        const gp_XY& Value)
49 {
50   Standard_OutOfRange_Raise_if (Col < 1 || Col > 2,"");
51   const Standard_Address M = (Standard_Address)&(matrix[0][0]);
52   if  (Col == 1) {
53     M00 = Value.X();
54     M10 = Value.Y();
55   }
56   else {
57     M01 = Value.X();
58     M11 = Value.Y();
59   }
60 }
61
62 void gp_Mat2d::SetCols (const gp_XY& Col1,
63                         const gp_XY& Col2)
64 {
65   const Standard_Address M = (Standard_Address)&(matrix[0][0]);
66   M00 = Col1.X(); M10 = Col1.Y();
67   M01 = Col2.X(); M11 = Col2.Y();
68 }
69
70 void gp_Mat2d::SetRow (const Standard_Integer Row, const gp_XY& Value)
71 {
72   Standard_OutOfRange_Raise_if (Row < 1 || Row > 2,"");
73   const Standard_Address M = (Standard_Address)&(matrix[0][0]);
74   if (Row == 1) {
75     M00 = Value.X();
76     M01 = Value.Y();
77   }
78   else {
79     M10 = Value.X();
80     M11 = Value.Y();
81   }
82 }
83
84 void gp_Mat2d::SetRows (const gp_XY& Row1, const gp_XY& Row2)
85 {
86   const Standard_Address M = (Standard_Address)&(matrix[0][0]);
87   M00 = Row1.X(); M01 = Row1.Y();
88   M10 = Row2.X(); M11 = Row2.Y();
89 }
90
91 gp_XY gp_Mat2d::Column (const Standard_Integer Col) const
92 {
93   Standard_OutOfRange_Raise_if (Col < 1 || Col > 2,"");
94   const Standard_Address M = (Standard_Address)&(matrix[0][0]);
95   if (Col == 1) return gp_XY (M00,M10);
96   return gp_XY (M01,M11);
97 }
98
99 gp_XY gp_Mat2d::Diagonal () const
100
101   const Standard_Address M = (Standard_Address)&(matrix[0][0]);
102   return gp_XY (M00,M11);
103 }
104
105 gp_XY gp_Mat2d::Row (const Standard_Integer Row) const
106 {
107   Standard_OutOfRange_Raise_if (Row < 1 || Row > 2,"");
108   const Standard_Address M = (Standard_Address)&(matrix[0][0]);
109   if (Row == 1) return gp_XY (M00,M01);
110   return gp_XY (M10,M11);
111 }
112
113 void gp_Mat2d::Invert ()
114 {
115   Standard_Real new_matrix[2][2],
116   det ;
117   const Standard_Address N = (Standard_Address)&(new_matrix[0][0]);
118   const Standard_Address M = (Standard_Address)&(    matrix[0][0]);
119   N00 = M11 ;
120   N01 = -M01 ;
121   N10 = -M10 ;
122   N11 = M00  ;
123   det = N00 * N11 - N01 * N10 ;
124   Standard_Real val = det;
125   if (val < 0) val = - val;
126   Standard_ConstructionError_Raise_if (val <= gp::Resolution(),"");
127   det = 1.0 / det ;
128   M00 = N00 * det ;
129   M10 = N10 * det ;
130   M01 = N01 * det ;
131   M11 = N11 * det ;
132 }
133
134 void gp_Mat2d::Power (const Standard_Integer N)
135 {
136   if      (N ==  1) { }
137   else if (N ==  0) { SetIdentity (); }
138   else if (N == -1) { Invert(); }
139   else {
140     if (N < 0) Invert();
141     Standard_Integer Npower = N;
142     if (Npower < 0) Npower = - Npower;
143     Npower--;
144     gp_Mat2d Temp = *this;
145     for(;;) {
146       if (IsOdd(Npower)) Multiply (Temp);
147       if (Npower == 1)   break;
148       Temp.Multiply (Temp);
149       Npower = Npower/2;
150     }
151   }
152 }
153