-// File: IntAna_QuadQuadGeo.cxx
-// Created: Thu Aug 6 12:00:46 1992
-// Author: Laurent BUCHARD
-// <lbr@sdsun2>
-
+// Created on: 1992-08-06
+// Created by: Laurent BUCHARD
+// Copyright (c) 1992-1999 Matra Datavision
+// Copyright (c) 1999-2012 OPEN CASCADE SAS
+//
+// The content of this file is subject to the Open CASCADE Technology Public
+// License Version 6.5 (the "License"). You may not use the content of this file
+// except in compliance with the License. Please obtain a copy of the License
+// at http://www.opencascade.org and read it completely before using this file.
+//
+// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
+// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
+//
+// The Original Code and all software distributed under the License is
+// distributed on an "AS IS" basis, without warranty of any kind, and the
+// Initial Developer hereby disclaims all such warranties, including without
+// limitation, any warranties of merchantability, fitness for a particular
+// purpose or non-infringement. Please see the License for the specific terms
+// and conditions governing the rights and limitations under the License.
//----------------------------------------------------------------------
//-- Purposse: Geometric Intersection between two Natural Quadric
static
gp_Ax2 DirToAx2(const gp_Pnt& P,const gp_Dir& D);
+static
+ void RefineDir(gp_Dir& aDir);
//=======================================================================
//class :
gp_Dir V2=Axe2.Direction();
gp_Pnt P1=Axe1.Location();
gp_Pnt P2=Axe2.Location();
-
+ //
+ RefineDir(V1);
+ RefineDir(V2);
thecoplanar= Standard_False;
thenormal = Standard_False;
Standard_Real denom2 = denom*denom;
Standard_Real ddenom = 1. - denom2;
- denom = ( Abs(ddenom) <= 1.e-9 ) ? 1.e-9 : ddenom;
+ //denom = ( Abs(ddenom) <= 1.e-9 ) ? 1.e-9 : ddenom;
+ denom = ( Abs(ddenom) <= 1.e-16 ) ? 1.e-16 : ddenom;
Standard_Real par1 = dist1/denom;
Standard_Real par2 = -dist2/denom;
IntAna_QuadQuadGeo::IntAna_QuadQuadGeo( const gp_Pln& P
,const gp_Cylinder& Cl
,const Standard_Real Tolang
- ,const Standard_Real Tol)
+ ,const Standard_Real Tol
+ ,const Standard_Real H)
: done(Standard_False),
nbint(0),
typeres(IntAna_Empty),
myPChar(0,0,0)
{
InitTolerances();
- Perform(P,Cl,Tolang,Tol);
+ Perform(P,Cl,Tolang,Tol,H);
}
//=======================================================================
//function : Perform
//purpose :
//=======================================================================
void IntAna_QuadQuadGeo::Perform( const gp_Pln& P
- ,const gp_Cylinder& Cl
- ,const Standard_Real Tolang
- ,const Standard_Real Tol)
+ ,const gp_Cylinder& Cl
+ ,const Standard_Real Tolang
+ ,const Standard_Real Tol
+ ,const Standard_Real H)
{
done = Standard_False;
Standard_Real dist,radius;
}
nbint = 0;
- IntAna_IntConicQuad inter(axec,P,tolang);
+ IntAna_IntConicQuad inter(axec,P,tolang,Tol,H);
if (inter.IsParallel()) {
// Le resultat de l intersection Plan-Cylindre est de type droite.
//
Standard_Real tg1, tg2, aDA1A2, aTol2;
gp_Pnt aPApex1, aPApex2;
+
+ Standard_Real TOL_APEX_CONF = 1.e-10;
+
//
tg1=Tan(Con1.SemiAngle());
tg2=Tan(Con2.SemiAngle());
tg2 = -tg2;
}
//
- //modified by NIZNHY-PKV Thu Dec 1 16:49:47 2005f
aTol2=Tol*Tol;
aPApex1=Con1.Apex();
aPApex2=Con2.Apex();
aDA1A2=aPApex1.SquareDistance(aPApex2);
- //modified by NIZNHY-PKV Wed Nov 30 10:17:05 2005t
//
AxeOperator A1A2(Con1.Axis(),Con2.Axis());
//
Standard_Real d=gp_Vec(D).Dot(gp_Vec(P,Con2.Apex()));
if(Abs(tg1-tg2)>myEPSILON_ANGLE_CONE) {
+ if (fabs(d) < TOL_APEX_CONF) {
+ typeres = IntAna_Point;
+ nbint = 1;
+ pt1 = P;
+ return;
+ }
x=(d*tg2)/(tg1+tg2);
pt1.SetCoord( P.X() + x*D.X()
,P.Y() + x*D.Y()
typeres=IntAna_Circle;
}
else {
- if (fabs(d)<1.e-10) {
+ if (fabs(d) < TOL_APEX_CONF) {
typeres=IntAna_Same;
}
else {
}
}
}// else if((Abs(tg1-tg2)<EPSILON_ANGLE_CONE) && (A1A2.Parallel()))
- //modified by NIZNHY-PKV Wed Nov 30 10:12:39 2005f
// 3
else if (aDA1A2<aTol2) {
- //
- // by NIZNHY-PKV Thu Dec 1 2005
//
// When apices are coinsided there can be 3 possible cases
// 3.1 - empty solution (iRet=0)
//
if (aRD2>(aR2+Tol)) {
iRet=0;
- //printf(" * iRet=0 => IntAna_Empty\n");
typeres=IntAna_Empty; //nothing
+ return;
}
//
iRet=1; //touch case => 1 line
pt1=aQApex1;
gp_Vec aVX(aQApex1, aQX);
dir1=gp_Dir(aVX);
- /*
- printf(" line L1 %lf %lf %lf %lf %lf %lf\n",
- pt1.X(), pt1.Y(), pt1.Z(),
- dir1.X(), dir1.Y(), dir1.Z());
- */
}
else {//iRet=2
dir1=gp_Dir(aVX1);
gp_Vec aVX2(aQApex1, aQX2);
dir2=gp_Dir(aVX2);
- /*
- printf(" line L1 %lf %lf %lf %lf %lf %lf\n",
- pt1.X(), pt1.Y(), pt1.Z(),
- dir1.X(), dir1.Y(), dir1.Z());
- printf(" line L2 %lf %lf %lf %lf %lf %lf\n",
- pt2.X(), pt2.Y(), pt2.Z(),
- dir2.X(), dir2.Y(), dir2.Z());
- */
}
} //else if (aDA1A2<aTol2) {
- //modified by NIZNHY-PKV Wed Nov 30 10:12:41 2005t
- //modified by NIZNHY-IFV Fry Sep 01 15:46:41 2006f
//Case when cones have common generatrix
else if(A1A2.Intersect()) {
//Check if apex of one cone belongs another one
}
}
}
- //modified by NIZNHY-IFV Fry Sep 01 15:46:41 2006t
- // else if(A1A2.Intersect() {
+
else {
typeres=IntAna_NoGeometricSolution;
}
const gp_Cone& Con,
const Standard_Real)
{
+
+ //
done=Standard_True;
+ //
AxeOperator A1A2(Con.Axis(),Sph.Position().Axis());
gp_Pnt Pt=Sph.Location();
+ //
if((A1A2.Intersect() && (Pt.Distance(A1A2.PtIntersect())==0.0))
|| A1A2.Same()) {
gp_Pnt ConApex= Con.Apex();
,param2,param2bis));
}
}
-
//=======================================================================
//function : HasCommonGen
//purpose :
//=======================================================================
-
Standard_Boolean IntAna_QuadQuadGeo::HasCommonGen() const
{
return myCommonGen;
}
-
//=======================================================================
//function : PChar
//purpose :
//=======================================================================
-
const gp_Pnt& IntAna_QuadQuadGeo::PChar() const
{
return myPChar;
}
-
+//=======================================================================
+//function : RefineDir
+//purpose :
+//=======================================================================
+void RefineDir(gp_Dir& aDir)
+{
+ Standard_Integer k, m, n;
+ Standard_Real aC[3];
+ //
+ aDir.Coord(aC[0], aC[1], aC[2]);
+ //
+ m=0;
+ n=0;
+ for (k=0; k<3; ++k) {
+ if (aC[k]==1. || aC[k]==-1.) {
+ ++m;
+ }
+ else if (aC[k]!=0.) {
+ ++n;
+ }
+ }
+ //
+ if (m && n) {
+ Standard_Real aEps, aR1, aR2, aNum;
+ //
+ aEps=RealEpsilon();
+ aR1=1.-aEps;
+ aR2=1.+aEps;
+ //
+ for (k=0; k<3; ++k) {
+ m=(aC[k]>0.);
+ aNum=(m)? aC[k] : -aC[k];
+ if (aNum>aR1 && aNum<aR2) {
+ if (m) {
+ aC[k]=1.;
+ }
+ else {
+ aC[k]=-1.;
+ }
+ //
+ aC[(k+1)%3]=0.;
+ aC[(k+2)%3]=0.;
+ break;
+ }
+ }
+ aDir.SetCoord(aC[0], aC[1], aC[2]);
+ }
+}