Commit | Line | Data |
---|---|---|
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 | // JCV 08/01/90 Modifs suite a l'introduction des classes XY et Mat2d dans gp |
16 | ||
17 | #define No_Standard_OutOfRange | |
18 | ||
42cf5bc1 | 19 | |
7fd59977 | 20 | #include <gp.hxx> |
42cf5bc1 | 21 | #include <gp_Ax2d.hxx> |
22 | #include <gp_Dir2d.hxx> | |
23 | #include <gp_Pnt2d.hxx> | |
24 | #include <gp_Trsf2d.hxx> | |
25 | #include <gp_Vec2d.hxx> | |
7fd59977 | 26 | #include <gp_VectorWithNullMagnitude.hxx> |
42cf5bc1 | 27 | #include <gp_XY.hxx> |
28 | #include <Standard_ConstructionError.hxx> | |
29 | #include <Standard_OutOfRange.hxx> | |
7fd59977 | 30 | |
31 | Standard_Boolean gp_Vec2d::IsEqual | |
32 | (const gp_Vec2d& Other, | |
33 | const Standard_Real LinearTolerance, | |
34 | const Standard_Real AngularTolerance) const | |
35 | { | |
36 | const Standard_Real theNorm = Magnitude(); | |
37 | const Standard_Real theOtherNorm = Other.Magnitude(); | |
38 | Standard_Real val = theNorm - theOtherNorm; | |
39 | if (val < 0.0) val = -val; | |
40 | // Check for equal lengths | |
41 | const Standard_Boolean isEqualLength = (val <= LinearTolerance); | |
42 | // Check for small vectors | |
43 | if (theNorm > LinearTolerance && theOtherNorm > LinearTolerance) | |
44 | { | |
45 | Standard_Real Ang = Angle(Other); | |
46 | if (Ang < 0.0) Ang = -Ang; | |
47 | // Check for zero angle | |
48 | return isEqualLength && (Ang <= AngularTolerance); | |
49 | } | |
50 | return isEqualLength; | |
51 | } | |
52 | ||
53 | Standard_Real gp_Vec2d::Angle (const gp_Vec2d& Other) const | |
54 | { | |
55 | // Commentaires : | |
56 | // Au dessus de 45 degres l'arccos donne la meilleur precision pour le | |
57 | // calcul de l'angle. Sinon il vaut mieux utiliser l'arcsin. | |
58 | // Les erreurs commises sont loin d'etre negligeables lorsque l'on est | |
59 | // proche de zero ou de 90 degres. | |
60 | // En 2D les valeurs angulaires sont comprises entre -PI et PI | |
61 | const Standard_Real theNorm = Magnitude(); | |
62 | const Standard_Real theOtherNorm = Other.Magnitude(); | |
63 | if (theNorm <= gp::Resolution() || theOtherNorm <= gp::Resolution()) | |
9775fa61 | 64 | throw gp_VectorWithNullMagnitude(); |
7fd59977 | 65 | |
66 | const Standard_Real D = theNorm * theOtherNorm; | |
67 | const Standard_Real Cosinus = coord.Dot (Other.coord) / D; | |
68 | const Standard_Real Sinus = coord.Crossed (Other.coord) / D; | |
69 | if (Cosinus > -0.70710678118655 && Cosinus < 0.70710678118655) | |
70 | { | |
71 | if (Sinus > 0.0) return acos (Cosinus); | |
72 | else return -acos (Cosinus); | |
73 | } | |
74 | else | |
75 | { | |
76 | if (Cosinus > 0.0) return asin (Sinus); | |
77 | else | |
78 | { | |
c6541a0c D |
79 | if (Sinus > 0.0) return M_PI - asin (Sinus); |
80 | else return - M_PI - asin (Sinus); | |
7fd59977 | 81 | } |
82 | } | |
83 | } | |
84 | ||
85 | void gp_Vec2d::Mirror (const gp_Ax2d& A1) | |
86 | { | |
87 | const gp_XY& XY = A1.Direction().XY(); | |
88 | Standard_Real X = coord.X(); | |
89 | Standard_Real Y = coord.Y(); | |
90 | Standard_Real A = XY.X(); | |
91 | Standard_Real B = XY.Y(); | |
92 | Standard_Real M1 = 2.0 * A * B; | |
93 | coord.SetX(((2.0 * A * A) - 1.) * X + M1 * Y); | |
94 | coord.SetY(M1 * X + ((2. * B * B) - 1.0) * Y); | |
95 | } | |
96 | ||
97 | gp_Vec2d gp_Vec2d::Mirrored (const gp_Ax2d& A1) const | |
98 | { | |
99 | gp_Vec2d Vres = *this; | |
100 | Vres.Mirror(A1); | |
101 | return Vres; | |
102 | } | |
103 | ||
104 | void gp_Vec2d::Transform (const gp_Trsf2d& T) | |
105 | { | |
106 | if (T.Form() == gp_Identity || T.Form() == gp_Translation) { } | |
107 | else if (T.Form() == gp_PntMirror) coord.Reverse (); | |
108 | else if (T.Form() == gp_Scale) coord.Multiply (T.ScaleFactor ()); | |
109 | else coord.Multiply (T.VectorialPart ()); | |
110 | } | |
111 | ||
112 | void gp_Vec2d::Mirror (const gp_Vec2d& V) | |
113 | { | |
114 | const Standard_Real D = V.coord.Modulus(); | |
115 | if (D > gp::Resolution()) | |
116 | { | |
117 | const gp_XY& XY = V.coord; | |
118 | Standard_Real X = XY.X(); | |
119 | Standard_Real Y = XY.Y(); | |
120 | Standard_Real A = X / D; | |
121 | Standard_Real B = Y / D; | |
122 | Standard_Real M1 = 2.0 * A * B; | |
123 | coord.SetX(((2.0 * A * A) - 1.0) * X + M1 * Y); | |
124 | coord.SetY(M1 * X + ((2.0 * B * B) - 1.0) * Y); | |
125 | } | |
126 | } | |
127 | ||
128 | gp_Vec2d gp_Vec2d::Mirrored (const gp_Vec2d& V) const | |
129 | { | |
130 | gp_Vec2d Vres = *this; | |
131 | Vres.Mirror(V); | |
132 | return Vres; | |
133 | } |