// Copyright (c) 1995-1999 Matra Datavision // Copyright (c) 1999-2014 OPEN CASCADE SAS // // This file is part of Open CASCADE Technology software library. // // This library is free software; you can redistribute it and / or modify it // under the terms of the GNU Lesser General Public version 2.1 as published // by the Free Software Foundation, with special exception defined in the file // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT // distribution for complete text of the license and disclaimer of any warranty. // // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. #include #include #include #include #include #include #include //========================================================================= // Circle tangent to a point Point1. + // center on circle OnCirc. + // radius Radius. + // + // Initialize the table of solutions cirsol and all fields. + // Eliminate cases not being the solution. + // Create the circle with center in Point1 of radius Radius. + // Intersect this circle with OnCirc and obtain the center points + // of found solutions. + // Create solutions cirsol. + //========================================================================= GccAna_Circ2dTanOnRad:: GccAna_Circ2dTanOnRad (const gp_Pnt2d& Point1 , const gp_Circ2d& OnCirc , const Standard_Real Radius , const Standard_Real Tolerance ): cirsol(1,2) , qualifier1(1,2) , TheSame1(1,2) , pnttg1sol(1,2), pntcen3(1,2) , par1sol(1,2) , pararg1(1,2) , parcen3(1,2) { gp_Dir2d dirx(1.0,0.0); Standard_Real Tol = Abs(Tolerance); WellDone = Standard_False; NbrSol = 0; Standard_Real Roncirc = OnCirc.Radius(); Standard_Real dist1 = Point1.Distance(OnCirc.Location())-Roncirc; Standard_Real dist2 = Point1.Distance(OnCirc.Location())+Roncirc; if (Radius < 0.0) { Standard_NegativeValue::Raise(); } else if ((dist1-Radius > Tol) || (Tol < Radius-dist2)) { WellDone = Standard_True; } else { Standard_Integer signe = 0; if (Abs(dist1-Radius) < Tol) { signe = 1; } else if (Abs(dist2-Radius) < Tol) { signe = -1; } if (signe != 0) { gp_Ax2d axe(gp_Pnt2d(OnCirc.Location().XY()-Roncirc* gp_Dir2d(OnCirc.Location().X()-signe*Point1.X(), OnCirc.Location().Y()-signe*Point1.Y()).XY()),dirx); cirsol(1) = gp_Circ2d(axe,Radius); // ================================ qualifier1(1) = GccEnt_noqualifier; TheSame1(1) = 0; pnttg1sol(1) = Point1; pntcen3(1) = cirsol(1).Location(); pararg1(1) = 0.0; par1sol(1)=ElCLib::Parameter(cirsol(1),pnttg1sol(1)); parcen3(1) = ElCLib::Parameter(OnCirc,pntcen3(1)); WellDone = Standard_True; NbrSol = 1; } else { IntAna2d_AnaIntersection Intp(OnCirc,gp_Circ2d(gp_Ax2d(Point1,dirx), Radius)); if (Intp.IsDone()) { if (!Intp.IsEmpty()) { for (Standard_Integer i = 1 ; i <= Intp.NbPoints() ; i++) { NbrSol++; gp_Pnt2d Center(Intp.Point(i).Value()); cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius); // ======================================================= qualifier1(1) = GccEnt_noqualifier; TheSame1(1) = 0; pnttg1sol(1) = Point1; pntcen3(1) = cirsol(1).Location(); par1sol(1)=ElCLib::Parameter(cirsol(1),pnttg1sol(1)); parcen3(1) = ElCLib::Parameter(OnCirc,pntcen3(1)); pararg1(1) = 0.0; } } WellDone = Standard_True; } } } }