b311480e |
1 | // Copyright (c) 1995-1999 Matra Datavision |
2 | // Copyright (c) 1999-2012 OPEN CASCADE SAS |
3 | // |
4 | // The content of this file is subject to the Open CASCADE Technology Public |
5 | // License Version 6.5 (the "License"). You may not use the content of this file |
6 | // except in compliance with the License. Please obtain a copy of the License |
7 | // at http://www.opencascade.org and read it completely before using this file. |
8 | // |
9 | // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its |
10 | // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. |
11 | // |
12 | // The Original Code and all software distributed under the License is |
13 | // distributed on an "AS IS" basis, without warranty of any kind, and the |
14 | // Initial Developer hereby disclaims all such warranties, including without |
15 | // limitation, any warranties of merchantability, fitness for a particular |
16 | // purpose or non-infringement. Please see the License for the specific terms |
17 | // and conditions governing the rights and limitations under the License. |
18 | |
7fd59977 |
19 | // 10/09/97 : PMN : Correction BUC40192 (pb avec les matrices negatives) |
20 | |
21 | #ifndef DEB |
22 | #define No_Standard_OutOfRange |
23 | #define No_Standard_ConstructionError |
24 | #endif |
25 | |
26 | #include <gp_Mat2d.ixx> |
27 | #include <Standard_ConstructionError.hxx> |
28 | |
29 | #define M00 ((Standard_Real*)M)[0] |
30 | #define M01 ((Standard_Real*)M)[1] |
31 | #define M10 ((Standard_Real*)M)[2] |
32 | #define M11 ((Standard_Real*)M)[3] |
33 | |
34 | #define N00 ((Standard_Real*)N)[0] |
35 | #define N01 ((Standard_Real*)N)[1] |
36 | #define N10 ((Standard_Real*)N)[2] |
37 | #define N11 ((Standard_Real*)N)[3] |
38 | |
39 | gp_Mat2d::gp_Mat2d (const gp_XY& Col1, const gp_XY& Col2) |
40 | { |
41 | const Standard_Address M = (Standard_Address)&(matrix[0][0]); |
42 | M00 = Col1.X(); M10 = Col1.Y(); |
43 | M01 = Col2.X(); M11 = Col2.Y(); |
44 | } |
45 | |
46 | void gp_Mat2d::SetCol (const Standard_Integer Col, |
47 | const gp_XY& Value) |
48 | { |
49 | Standard_OutOfRange_Raise_if (Col < 1 || Col > 2,""); |
50 | const Standard_Address M = (Standard_Address)&(matrix[0][0]); |
51 | if (Col == 1) { |
52 | M00 = Value.X(); |
53 | M10 = Value.Y(); |
54 | } |
55 | else { |
56 | M01 = Value.X(); |
57 | M11 = Value.Y(); |
58 | } |
59 | } |
60 | |
61 | void gp_Mat2d::SetCols (const gp_XY& Col1, |
62 | const gp_XY& Col2) |
63 | { |
64 | const Standard_Address M = (Standard_Address)&(matrix[0][0]); |
65 | M00 = Col1.X(); M10 = Col1.Y(); |
66 | M01 = Col2.X(); M11 = Col2.Y(); |
67 | } |
68 | |
69 | void gp_Mat2d::SetRow (const Standard_Integer Row, const gp_XY& Value) |
70 | { |
71 | Standard_OutOfRange_Raise_if (Row < 1 || Row > 2,""); |
72 | const Standard_Address M = (Standard_Address)&(matrix[0][0]); |
73 | if (Row == 1) { |
74 | M00 = Value.X(); |
75 | M01 = Value.Y(); |
76 | } |
77 | else { |
78 | M10 = Value.X(); |
79 | M11 = Value.Y(); |
80 | } |
81 | } |
82 | |
83 | void gp_Mat2d::SetRows (const gp_XY& Row1, const gp_XY& Row2) |
84 | { |
85 | const Standard_Address M = (Standard_Address)&(matrix[0][0]); |
86 | M00 = Row1.X(); M01 = Row1.Y(); |
87 | M10 = Row2.X(); M11 = Row2.Y(); |
88 | } |
89 | |
90 | gp_XY gp_Mat2d::Column (const Standard_Integer Col) const |
91 | { |
92 | Standard_OutOfRange_Raise_if (Col < 1 || Col > 2,""); |
93 | const Standard_Address M = (Standard_Address)&(matrix[0][0]); |
94 | if (Col == 1) return gp_XY (M00,M10); |
95 | return gp_XY (M01,M11); |
96 | } |
97 | |
98 | gp_XY gp_Mat2d::Diagonal () const |
99 | { |
100 | const Standard_Address M = (Standard_Address)&(matrix[0][0]); |
101 | return gp_XY (M00,M11); |
102 | } |
103 | |
104 | gp_XY gp_Mat2d::Row (const Standard_Integer Row) const |
105 | { |
106 | Standard_OutOfRange_Raise_if (Row < 1 || Row > 2,""); |
107 | const Standard_Address M = (Standard_Address)&(matrix[0][0]); |
108 | if (Row == 1) return gp_XY (M00,M01); |
109 | return gp_XY (M10,M11); |
110 | } |
111 | |
112 | void gp_Mat2d::Invert () |
113 | { |
114 | Standard_Real new_matrix[2][2], |
115 | det ; |
116 | const Standard_Address N = (Standard_Address)&(new_matrix[0][0]); |
117 | const Standard_Address M = (Standard_Address)&( matrix[0][0]); |
118 | N00 = M11 ; |
119 | N01 = -M01 ; |
120 | N10 = -M10 ; |
121 | N11 = M00 ; |
122 | det = N00 * N11 - N01 * N10 ; |
123 | Standard_Real val = det; |
124 | if (val < 0) val = - val; |
125 | Standard_ConstructionError_Raise_if (val <= gp::Resolution(),""); |
126 | det = 1.0 / det ; |
127 | M00 = N00 * det ; |
128 | M10 = N10 * det ; |
129 | M01 = N01 * det ; |
130 | M11 = N11 * det ; |
131 | } |
132 | |
133 | void gp_Mat2d::Power (const Standard_Integer N) |
134 | { |
135 | if (N == 1) { } |
136 | else if (N == 0) { SetIdentity (); } |
137 | else if (N == -1) { Invert(); } |
138 | else { |
139 | if (N < 0) Invert(); |
140 | Standard_Integer Npower = N; |
141 | if (Npower < 0) Npower = - Npower; |
142 | Npower--; |
143 | gp_Mat2d Temp = *this; |
302f96fb |
144 | for(;;) { |
7fd59977 |
145 | if (IsOdd(Npower)) Multiply (Temp); |
146 | if (Npower == 1) break; |
147 | Temp.Multiply (Temp); |
148 | Npower = Npower/2; |
149 | } |
150 | } |
151 | } |
152 | |