1 // Created on: 1992-09-02
2 // Created by: Remi GILET
3 // Copyright (c) 1992-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
17 #include <gce_MakeCirc.ixx>
19 #include <StdFail_NotDone.hxx>
25 #include <gce_MakeDir.hxx>
27 #include <Extrema_POnCurv.hxx>
28 #include <Extrema_ExtElC.hxx>
29 //=======================================================================
30 //function : gce_MakeCirc
32 // Creation d un cercle 3d de gp passant par trois points. +
33 // Trois cas de figures : +
34 // 1/ Les trois points sont confondus. +
35 // ----------------------------------- +
36 // Le resultat est le cercle centre en Point1 de rayon zero. +
37 // 2/ Deux des trois points sont confondus. +
38 // ---------------------------------------- +
39 // Pas de solution (Erreur : Points confondus). +
40 // 3/ Les trois points sont distinct. +
41 // ---------------------------------- +
42 // On cree la mediatrice a P1P2 ainsi que la mediatrice a P1P3. +
43 // La solution a pour centre l intersection de ces deux droite et +
44 // pour rayon la distance entre ce centre et l un des trois points. +
45 //=========================================================================
46 gce_MakeCirc::gce_MakeCirc(const gp_Pnt& P1 ,
49 //=========================================================================
51 //=========================================================================
52 Standard_Real dist1, dist2, dist3, aResolution;
54 aResolution=gp::Resolution();
56 dist1 = P1.Distance(P2);
57 dist2 = P1.Distance(P3);
58 dist3 = P2.Distance(P3);
60 if ((dist1<aResolution) && (dist2<aResolution) && (dist3<aResolution)) {
61 gp_Dir Dirx(1.,0.,0.);
62 gp_Dir Dirz(0.,0.,1.);
63 TheCirc = gp_Circ(gp_Ax2(P1,Dirx,Dirz), 0.);
66 if (!(dist1 >= aResolution && dist2 >= aResolution)) {
67 TheError = gce_ConfusedPoints;
71 Standard_Real x1,y1,z1,x2,y2,z2,x3,y3,z3;
76 gp_Dir Dir1(x2-x1,y2-y1,z2-z1);
77 gp_Dir Dir2(x3-x2,y3-y2,z3-z2);
79 gp_Ax1 anAx1(P1, Dir1);
81 if (aL12.Distance(P3)<aResolution) {
82 TheError = gce_ColinearPoints;
86 gp_Dir Dir3 = Dir1.Crossed(Dir2);
88 gp_Dir dir = Dir1.Crossed(Dir3);
89 gp_Lin L1(gp_Pnt((P1.XYZ()+P2.XYZ())/2.),dir);
90 dir = Dir2.Crossed(Dir3);
91 gp_Lin L2(gp_Pnt((P3.XYZ()+P2.XYZ())/2.),dir);
93 Standard_Real Tol = 0.000000001;
94 Extrema_ExtElC distmin(L1,L2,Tol);
96 if (!distmin.IsDone()) {
97 TheError = gce_IntersectionError;
100 Standard_Integer nbext;
103 if (distmin.IsParallel()) {
104 TheError = gce_IntersectionError;
107 nbext = distmin.NbExt();
111 TheError = gce_IntersectionError;
114 Standard_Real TheDist = RealLast();
115 gp_Pnt pInt,pon1,pon2;
116 Standard_Integer i = 1;
117 Extrema_POnCurv Pon1,Pon2;
119 if (distmin.SquareDistance(i)<TheDist) {
120 TheDist = distmin.SquareDistance(i);
121 distmin.Points(i,Pon1,Pon2);
124 pInt = gp_Pnt((pon1.XYZ()+pon2.XYZ())/2.);
128 //modified by NIZNHY-PKV Thu Mar 3 11:30:34 2005f
130 //modified by NIZNHY-PKV Thu Mar 3 11:30:37 2005t
131 dist1 = P1.Distance(pInt);
132 dist2 = P2.Distance(pInt);
133 dist3 = P3.Distance(pInt);
134 pInt.Coord(x3,y3,z3);
135 Dir1 = gp_Dir(x1-x3,y1-y3,z1-z3);
136 //modified by NIZNHY-PKV Thu Mar 3 11:31:11 2005f
137 //Dir2 = gp_Dir(x2-x3,y2-y3,z2-z3);
138 //modified by NIZNHY-PKV Thu Mar 3 11:31:13 2005t
140 TheCirc = gp_Circ(gp_Ax2(pInt, Dir3, Dir1),(dist1+dist2+dist3)/3.);
145 //=======================================================================
146 //function : gce_MakeCirc
148 //=======================================================================
149 gce_MakeCirc::gce_MakeCirc(const gp_Ax2& A2 ,
150 const Standard_Real Radius ) {
152 TheError = gce_NegativeRadius;
156 TheCirc = gp_Circ(A2,Radius);
159 //=========================================================================
160 // Creation d un gp_Circ par son centre <Center>, son plan <Plane> et +
161 // son rayon <Radius>. +
162 //=========================================================================
163 gce_MakeCirc::gce_MakeCirc(const gp_Pnt& Center ,
164 const gp_Pln& Plane ,
165 const Standard_Real Radius ) {
166 gce_MakeCirc C = gce_MakeCirc(Center,Plane.Position().Direction(),Radius);
168 TheError = C.Status();
170 //=======================================================================
171 //function : gce_MakeCirc
172 //purpose : Creation d un gp_Circ par son centre <Center>,
173 //sa normale <Norm> et son rayon <Radius>.
174 //=======================================================================
175 gce_MakeCirc::gce_MakeCirc(const gp_Pnt& Center ,
177 const Standard_Real Radius ) {
179 TheError = gce_NegativeRadius;
182 Standard_Real A = Norm.X();
183 Standard_Real B = Norm.Y();
184 Standard_Real C = Norm.Z();
185 Standard_Real Aabs = Abs(A);
186 Standard_Real Babs = Abs(B);
187 Standard_Real Cabs = Abs(C);
190 //=========================================================================
191 // pour determiner l'axe X : +
192 // on dit que le produit scalaire Vx.Norm = 0. +
193 // et on recherche le max(A,B,C) pour faire la division. +
194 // l'une des coordonnees du vecteur est nulle. +
195 //=========================================================================
197 if( Babs <= Aabs && Babs <= Cabs) {
198 if(Aabs > Cabs) { Pos = gp_Ax2(Center,Norm,gp_Dir(-C,0.,A)); }
199 else { Pos = gp_Ax2(Center,Norm,gp_Dir(C,0.,-A)); }
201 else if( Aabs <= Babs && Aabs <= Cabs) {
202 if(Babs > Cabs) { Pos = gp_Ax2(Center,Norm,gp_Dir(0.,-C,B)); }
203 else { Pos = gp_Ax2(Center,Norm,gp_Dir(0.,C,-B)); }
206 if(Aabs > Babs) { Pos = gp_Ax2(Center,Norm,gp_Dir(-B,A,0.)); }
207 else { Pos = gp_Ax2(Center,Norm,gp_Dir(B,-A,0.)); }
209 TheCirc = gp_Circ(Pos,Radius);
213 //=======================================================================
214 //function : gce_MakeCirc
215 //purpose : Creation d un gp_Circ par son centre <Center>,
216 // sa normale <Ptaxis> et son rayon <Radius>
217 //=======================================================================
218 gce_MakeCirc::gce_MakeCirc(const gp_Pnt& Center ,
219 const gp_Pnt& Ptaxis ,
220 const Standard_Real Radius ) {
222 TheError = gce_NegativeRadius;
225 if (Center.Distance(Ptaxis) <= gp::Resolution()) {
226 TheError = gce_NullAxis;
229 Standard_Real A = Ptaxis.X()-Center.X();
230 Standard_Real B = Ptaxis.Y()-Center.Y();
231 Standard_Real C = Ptaxis.Z()-Center.Z();
232 Standard_Real Aabs = Abs(A);
233 Standard_Real Babs = Abs(B);
234 Standard_Real Cabs = Abs(C);
237 //=========================================================================
238 // pour determiner l'axe X : +
239 // on dit que le produit scalaire Vx.Norm = 0. +
240 // et on recherche le max(A,B,C) pour faire la division. +
241 // l'une des coordonnees du vecteur est nulle. +
242 //=========================================================================
244 gp_Dir Norm = gce_MakeDir(Center,Ptaxis);
245 if( Babs <= Aabs && Babs <= Cabs) {
246 if(Aabs > Cabs) { Pos = gp_Ax2(Center,Norm,gp_Dir(-C,0.,A)); }
247 else { Pos = gp_Ax2(Center,Norm,gp_Dir(C,0.,-A)); }
249 else if( Aabs <= Babs && Aabs <= Cabs) {
250 if(Babs > Cabs) { Pos = gp_Ax2(Center,Norm,gp_Dir(0.,-C,B)); }
251 else { Pos = gp_Ax2(Center,Norm,gp_Dir(0.,C,-B)); }
254 if(Aabs > Babs) { Pos = gp_Ax2(Center,Norm,gp_Dir(-B,A,0.)); }
255 else { Pos = gp_Ax2(Center,Norm,gp_Dir(B,-A,0.)); }
257 TheCirc = gp_Circ(Pos,Radius);
262 //=======================================================================
263 //function : gce_MakeCirc
264 //purpose : Creation d un gp_Circ par son axe <Axis> et son rayon <Radius>.
265 //=======================================================================
266 gce_MakeCirc::gce_MakeCirc(const gp_Ax1& Axis ,
267 const Standard_Real Radius )
270 TheError = gce_NegativeRadius;
273 gp_Dir Norm(Axis.Direction());
274 gp_Pnt Center(Axis.Location());
275 Standard_Real A = Norm.X();
276 Standard_Real B = Norm.Y();
277 Standard_Real C = Norm.Z();
278 Standard_Real Aabs = Abs(A);
279 Standard_Real Babs = Abs(B);
280 Standard_Real Cabs = Abs(C);
283 //=========================================================================
284 // pour determiner l'axe X : +
285 // on dit que le produit scalaire Vx.Norm = 0. +
286 // et on recherche le max(A,B,C) pour faire la division. +
287 // l'une des coordonnees du vecteur est nulle. +
288 //=========================================================================
290 if( Babs <= Aabs && Babs <= Cabs) {
291 if(Aabs > Cabs) { Pos = gp_Ax2(Center,Norm,gp_Dir(-C,0.,A)); }
292 else { Pos = gp_Ax2(Center,Norm,gp_Dir(C,0.,-A)); }
294 else if( Aabs <= Babs && Aabs <= Cabs) {
295 if(Babs > Cabs) { Pos = gp_Ax2(Center,Norm,gp_Dir(0.,-C,B)); }
296 else { Pos = gp_Ax2(Center,Norm,gp_Dir(0.,C,-B)); }
299 if(Aabs > Babs) { Pos = gp_Ax2(Center,Norm,gp_Dir(-B,A,0.)); }
300 else { Pos = gp_Ax2(Center,Norm,gp_Dir(B,-A,0.)); }
302 TheCirc = gp_Circ(Pos,Radius);
306 //=======================================================================
307 //function : gce_MakeCirc
308 //purpose : Creation d un gp_Circ concentrique a un autre gp_circ a une distance +
310 //=======================================================================
311 gce_MakeCirc::gce_MakeCirc(const gp_Circ& Circ ,
312 const Standard_Real Dist )
314 Standard_Real Rad = Circ.Radius()+Dist;
316 TheError = gce_NegativeRadius;
319 TheCirc = gp_Circ(Circ.Position(),Rad);
323 //=======================================================================
324 //function : gce_MakeCirc
325 //purpose : Creation d un gp_Circ concentrique a un autre gp_circ dont le rayon
326 // est egal a la distance de <Point> a l axe de <Circ>.
327 //=======================================================================
328 gce_MakeCirc::gce_MakeCirc(const gp_Circ& Circ ,
331 Standard_Real Rad = gp_Lin(Circ.Axis()).Distance(P);
332 TheCirc = gp_Circ(Circ.Position(),Rad);
335 //=======================================================================
338 //=======================================================================
339 const gp_Circ& gce_MakeCirc::Value() const
341 StdFail_NotDone_Raise_if(!TheError == gce_Done,"");
344 //=======================================================================
345 //function : Operator
347 //=======================================================================
348 const gp_Circ& gce_MakeCirc::Operator() const
352 //=======================================================================
353 //function : operator
355 //=======================================================================
356 gce_MakeCirc::operator gp_Circ() const