b311480e |
1 | // Copyright (c) 1995-1999 Matra Datavision |
973c2be1 |
2 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e |
3 | // |
973c2be1 |
4 | // This file is part of Open CASCADE Technology software library. |
b311480e |
5 | // |
d5f74e42 |
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 |
973c2be1 |
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. |
b311480e |
11 | // |
973c2be1 |
12 | // Alternatively, this file may be used under the terms of Open CASCADE |
13 | // commercial license or contractual agreement. |
b311480e |
14 | |
7fd59977 |
15 | // 10/09/97 : PMN : Correction BUC40192 (pb avec les matrices negatives) |
16 | |
0797d9d3 |
17 | #ifndef OCCT_DEBUG |
7fd59977 |
18 | #define No_Standard_OutOfRange |
19 | #define No_Standard_ConstructionError |
20 | #endif |
21 | |
42cf5bc1 |
22 | |
23 | #include <gp_GTrsf2d.hxx> |
24 | #include <gp_Mat2d.hxx> |
25 | #include <gp_Trsf2d.hxx> |
26 | #include <gp_XY.hxx> |
7fd59977 |
27 | #include <Standard_ConstructionError.hxx> |
42cf5bc1 |
28 | #include <Standard_OutOfRange.hxx> |
7fd59977 |
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 | { |
2d2b3d53 |
50 | Standard_OutOfRange_Raise_if (Col < 1 || Col > 2, "gp_Mat2d::SetCol() - invalid index"); |
7fd59977 |
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 | { |
2d2b3d53 |
72 | Standard_OutOfRange_Raise_if (Row < 1 || Row > 2, "gp_Mat2d::SetRow() - invalid index"); |
7fd59977 |
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 | { |
2d2b3d53 |
93 | Standard_OutOfRange_Raise_if (Col < 1 || Col > 2, "gp_Mat2d::Column() - invalid index"); |
7fd59977 |
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 | { |
2d2b3d53 |
107 | Standard_OutOfRange_Raise_if (Row < 1 || Row > 2, "gp_Mat2d::Row() - invalid index"); |
7fd59977 |
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; |
2d2b3d53 |
126 | Standard_ConstructionError_Raise_if (val <= gp::Resolution(), "gp_Mat2d::Invert() - matrix has zero determinant"); |
7fd59977 |
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; |
302f96fb |
145 | for(;;) { |
7fd59977 |
146 | if (IsOdd(Npower)) Multiply (Temp); |
147 | if (Npower == 1) break; |
148 | Temp.Multiply (Temp); |
149 | Npower = Npower/2; |
150 | } |
151 | } |
152 | } |
153 | |