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.
18 #include <Extrema_ExtElC.hxx>
19 #include <Extrema_POnCurv.hxx>
20 #include <gce_MakeCirc.hxx>
21 #include <gce_MakeDir.hxx>
25 #include <gp_Circ.hxx>
30 #include <StdFail_NotDone.hxx>
32 //=======================================================================
33 //function : gce_MakeCirc
35 // Creation d un cercle 3d de gp passant par trois points. +
36 // Trois cas de figures : +
37 // 1/ Les trois points sont confondus. +
38 // ----------------------------------- +
39 // Le resultat est le cercle centre en Point1 de rayon zero. +
40 // 2/ Deux des trois points sont confondus. +
41 // ---------------------------------------- +
42 // Pas de solution (Erreur : Points confondus). +
43 // 3/ Les trois points sont distinct. +
44 // ---------------------------------- +
45 // On cree la mediatrice a P1P2 ainsi que la mediatrice a P1P3. +
46 // La solution a pour centre l intersection de ces deux droite et +
47 // pour rayon la distance entre ce centre et l un des trois points. +
48 //=========================================================================
49 gce_MakeCirc::gce_MakeCirc(const gp_Pnt& P1 ,
52 //=========================================================================
54 //=========================================================================
55 Standard_Real dist1, dist2, dist3, aResolution;
57 aResolution=gp::Resolution();
59 dist1 = P1.Distance(P2);
60 dist2 = P1.Distance(P3);
61 dist3 = P2.Distance(P3);
63 if ((dist1<aResolution) && (dist2<aResolution) && (dist3<aResolution)) {
64 gp_Dir Dirx(1.,0.,0.);
65 gp_Dir Dirz(0.,0.,1.);
66 TheCirc = gp_Circ(gp_Ax2(P1,Dirx,Dirz), 0.);
69 if (!(dist1 >= aResolution && dist2 >= aResolution)) {
70 TheError = gce_ConfusedPoints;
74 Standard_Real x1,y1,z1,x2,y2,z2,x3,y3,z3;
79 gp_Dir Dir1(x2-x1,y2-y1,z2-z1);
80 gp_Dir Dir2(x3-x2,y3-y2,z3-z2);
82 gp_Ax1 anAx1(P1, Dir1);
84 if (aL12.Distance(P3)<aResolution) {
85 TheError = gce_ColinearPoints;
89 gp_Dir Dir3 = Dir1.Crossed(Dir2);
91 gp_Dir dir = Dir1.Crossed(Dir3);
92 gp_Lin L1(gp_Pnt((P1.XYZ()+P2.XYZ())/2.),dir);
93 dir = Dir2.Crossed(Dir3);
94 gp_Lin L2(gp_Pnt((P3.XYZ()+P2.XYZ())/2.),dir);
96 Standard_Real Tol = 0.000000001;
97 Extrema_ExtElC distmin(L1,L2,Tol);
99 if (!distmin.IsDone()) {
100 TheError = gce_IntersectionError;
103 Standard_Integer nbext;
106 if (distmin.IsParallel()) {
107 TheError = gce_IntersectionError;
110 nbext = distmin.NbExt();
114 TheError = gce_IntersectionError;
117 Standard_Real TheDist = RealLast();
118 gp_Pnt pInt,pon1,pon2;
119 Standard_Integer i = 1;
120 Extrema_POnCurv Pon1,Pon2;
122 if (distmin.SquareDistance(i)<TheDist) {
123 TheDist = distmin.SquareDistance(i);
124 distmin.Points(i,Pon1,Pon2);
127 pInt = gp_Pnt((pon1.XYZ()+pon2.XYZ())/2.);
131 //modified by NIZNHY-PKV Thu Mar 3 11:30:34 2005f
133 //modified by NIZNHY-PKV Thu Mar 3 11:30:37 2005t
134 dist1 = P1.Distance(pInt);
135 dist2 = P2.Distance(pInt);
136 dist3 = P3.Distance(pInt);
137 pInt.Coord(x3,y3,z3);
138 Dir1 = gp_Dir(x1-x3,y1-y3,z1-z3);
139 //modified by NIZNHY-PKV Thu Mar 3 11:31:11 2005f
140 //Dir2 = gp_Dir(x2-x3,y2-y3,z2-z3);
141 //modified by NIZNHY-PKV Thu Mar 3 11:31:13 2005t
143 TheCirc = gp_Circ(gp_Ax2(pInt, Dir3, Dir1),(dist1+dist2+dist3)/3.);
148 //=======================================================================
149 //function : gce_MakeCirc
151 //=======================================================================
152 gce_MakeCirc::gce_MakeCirc(const gp_Ax2& A2 ,
153 const Standard_Real Radius ) {
155 TheError = gce_NegativeRadius;
159 TheCirc = gp_Circ(A2,Radius);
162 //=========================================================================
163 // Creation d un gp_Circ par son centre <Center>, son plan <Plane> et +
164 // son rayon <Radius>. +
165 //=========================================================================
166 gce_MakeCirc::gce_MakeCirc(const gp_Pnt& Center ,
167 const gp_Pln& Plane ,
168 const Standard_Real Radius ) {
169 gce_MakeCirc C = gce_MakeCirc(Center,Plane.Position().Direction(),Radius);
171 TheError = C.Status();
173 //=======================================================================
174 //function : gce_MakeCirc
175 //purpose : Creation d un gp_Circ par son centre <Center>,
176 //sa normale <Norm> et son rayon <Radius>.
177 //=======================================================================
178 gce_MakeCirc::gce_MakeCirc(const gp_Pnt& Center ,
180 const Standard_Real Radius ) {
182 TheError = gce_NegativeRadius;
185 Standard_Real A = Norm.X();
186 Standard_Real B = Norm.Y();
187 Standard_Real C = Norm.Z();
188 Standard_Real Aabs = Abs(A);
189 Standard_Real Babs = Abs(B);
190 Standard_Real Cabs = Abs(C);
193 //=========================================================================
194 // pour determiner l'axe X : +
195 // on dit que le produit scalaire Vx.Norm = 0. +
196 // et on recherche le max(A,B,C) pour faire la division. +
197 // l'une des coordonnees du vecteur est nulle. +
198 //=========================================================================
200 if( Babs <= Aabs && Babs <= Cabs) {
201 if(Aabs > Cabs) { Pos = gp_Ax2(Center,Norm,gp_Dir(-C,0.,A)); }
202 else { Pos = gp_Ax2(Center,Norm,gp_Dir(C,0.,-A)); }
204 else if( Aabs <= Babs && Aabs <= Cabs) {
205 if(Babs > Cabs) { Pos = gp_Ax2(Center,Norm,gp_Dir(0.,-C,B)); }
206 else { Pos = gp_Ax2(Center,Norm,gp_Dir(0.,C,-B)); }
209 if(Aabs > Babs) { Pos = gp_Ax2(Center,Norm,gp_Dir(-B,A,0.)); }
210 else { Pos = gp_Ax2(Center,Norm,gp_Dir(B,-A,0.)); }
212 TheCirc = gp_Circ(Pos,Radius);
216 //=======================================================================
217 //function : gce_MakeCirc
218 //purpose : Creation d un gp_Circ par son centre <Center>,
219 // sa normale <Ptaxis> et son rayon <Radius>
220 //=======================================================================
221 gce_MakeCirc::gce_MakeCirc(const gp_Pnt& Center ,
222 const gp_Pnt& Ptaxis ,
223 const Standard_Real Radius ) {
225 TheError = gce_NegativeRadius;
228 if (Center.Distance(Ptaxis) <= gp::Resolution()) {
229 TheError = gce_NullAxis;
232 Standard_Real A = Ptaxis.X()-Center.X();
233 Standard_Real B = Ptaxis.Y()-Center.Y();
234 Standard_Real C = Ptaxis.Z()-Center.Z();
235 Standard_Real Aabs = Abs(A);
236 Standard_Real Babs = Abs(B);
237 Standard_Real Cabs = Abs(C);
240 //=========================================================================
241 // pour determiner l'axe X : +
242 // on dit que le produit scalaire Vx.Norm = 0. +
243 // et on recherche le max(A,B,C) pour faire la division. +
244 // l'une des coordonnees du vecteur est nulle. +
245 //=========================================================================
247 gp_Dir Norm = gce_MakeDir(Center,Ptaxis);
248 if( Babs <= Aabs && Babs <= Cabs) {
249 if(Aabs > Cabs) { Pos = gp_Ax2(Center,Norm,gp_Dir(-C,0.,A)); }
250 else { Pos = gp_Ax2(Center,Norm,gp_Dir(C,0.,-A)); }
252 else if( Aabs <= Babs && Aabs <= Cabs) {
253 if(Babs > Cabs) { Pos = gp_Ax2(Center,Norm,gp_Dir(0.,-C,B)); }
254 else { Pos = gp_Ax2(Center,Norm,gp_Dir(0.,C,-B)); }
257 if(Aabs > Babs) { Pos = gp_Ax2(Center,Norm,gp_Dir(-B,A,0.)); }
258 else { Pos = gp_Ax2(Center,Norm,gp_Dir(B,-A,0.)); }
260 TheCirc = gp_Circ(Pos,Radius);
265 //=======================================================================
266 //function : gce_MakeCirc
267 //purpose : Creation d un gp_Circ par son axe <Axis> et son rayon <Radius>.
268 //=======================================================================
269 gce_MakeCirc::gce_MakeCirc(const gp_Ax1& Axis ,
270 const Standard_Real Radius )
273 TheError = gce_NegativeRadius;
276 gp_Dir Norm(Axis.Direction());
277 gp_Pnt Center(Axis.Location());
278 Standard_Real A = Norm.X();
279 Standard_Real B = Norm.Y();
280 Standard_Real C = Norm.Z();
281 Standard_Real Aabs = Abs(A);
282 Standard_Real Babs = Abs(B);
283 Standard_Real Cabs = Abs(C);
286 //=========================================================================
287 // pour determiner l'axe X : +
288 // on dit que le produit scalaire Vx.Norm = 0. +
289 // et on recherche le max(A,B,C) pour faire la division. +
290 // l'une des coordonnees du vecteur est nulle. +
291 //=========================================================================
293 if( Babs <= Aabs && Babs <= Cabs) {
294 if(Aabs > Cabs) { Pos = gp_Ax2(Center,Norm,gp_Dir(-C,0.,A)); }
295 else { Pos = gp_Ax2(Center,Norm,gp_Dir(C,0.,-A)); }
297 else if( Aabs <= Babs && Aabs <= Cabs) {
298 if(Babs > Cabs) { Pos = gp_Ax2(Center,Norm,gp_Dir(0.,-C,B)); }
299 else { Pos = gp_Ax2(Center,Norm,gp_Dir(0.,C,-B)); }
302 if(Aabs > Babs) { Pos = gp_Ax2(Center,Norm,gp_Dir(-B,A,0.)); }
303 else { Pos = gp_Ax2(Center,Norm,gp_Dir(B,-A,0.)); }
305 TheCirc = gp_Circ(Pos,Radius);
309 //=======================================================================
310 //function : gce_MakeCirc
311 //purpose : Creation d un gp_Circ concentrique a un autre gp_circ a une distance +
313 //=======================================================================
314 gce_MakeCirc::gce_MakeCirc(const gp_Circ& Circ ,
315 const Standard_Real Dist )
317 Standard_Real Rad = Circ.Radius()+Dist;
319 TheError = gce_NegativeRadius;
322 TheCirc = gp_Circ(Circ.Position(),Rad);
326 //=======================================================================
327 //function : gce_MakeCirc
328 //purpose : Creation d un gp_Circ concentrique a un autre gp_circ dont le rayon
329 // est egal a la distance de <Point> a l axe de <Circ>.
330 //=======================================================================
331 gce_MakeCirc::gce_MakeCirc(const gp_Circ& Circ ,
334 Standard_Real Rad = gp_Lin(Circ.Axis()).Distance(P);
335 TheCirc = gp_Circ(Circ.Position(),Rad);
338 //=======================================================================
341 //=======================================================================
342 const gp_Circ& gce_MakeCirc::Value() const
344 StdFail_NotDone_Raise_if (TheError != gce_Done,
345 "gce_MakeCirc::Value() - no result");
348 //=======================================================================
349 //function : Operator
351 //=======================================================================
352 const gp_Circ& gce_MakeCirc::Operator() const
356 //=======================================================================
357 //function : operator
359 //=======================================================================
360 gce_MakeCirc::operator gp_Circ() const