void Extrema_ExtElCS::Perform(const gp_Lin& C,
- const gp_Cylinder& S)
+ const gp_Cylinder& S)
{
myDone = Standard_False;
myNbExt = 0;
Standard_Real radius = S.Radius();
Extrema_ExtElC Extrem(gp_Lin(Pos.Axis()), C, Precision::Angular());
if (Extrem.IsParallel()) {
+ // Line direction is similar to cylinder axis of rotation.
mySqDist = new TColStd_HArray1OfReal(1, 1);
myPoint1 = new Extrema_HArray1OfPOnCurv(1, 1);
myPoint2 = new Extrema_HArray1OfPOnSurf(1, 1);
myIsPar = Standard_True;
}
else {
- Standard_Integer i;
-
+ Standard_Integer i, aStartIdx = 0;
+
Extrema_POnCurv myPOnC1, myPOnC2;
Extrem.Points(1, myPOnC1, myPOnC2);
gp_Pnt PonAxis = myPOnC1.Value();
gp_Pnt PC = myPOnC2.Value();
- // line is tangent or outside of the cylunder -- single solution
- if (radius - PonAxis.Distance(PC) < Precision::PConfusion())
- {
- Extrema_ExtPElS ExPS(PC, S, Precision::Confusion());
- if (ExPS.IsDone()) {
- myNbExt = ExPS.NbExt();
- mySqDist = new TColStd_HArray1OfReal(1, myNbExt);
- myPoint1 = new Extrema_HArray1OfPOnCurv(1, myNbExt);
- myPoint2 = new Extrema_HArray1OfPOnSurf(1, myNbExt);
- for (i = 1; i <= myNbExt; i++) {
- myPoint1->SetValue(i, myPOnC2);
- myPoint2->SetValue(i, ExPS.Point(i));
- mySqDist->SetValue(i,(myPOnC2.Value()).SquareDistance(ExPS.Point(i).Value()));
- }
- }
- }
// line intersects the cylinder
- else
+ if (radius - PonAxis.Distance(PC) > Precision::PConfusion())
{
IntAna_Quadric theQuadric(S);
IntAna_IntConicQuad Inters(C, theQuadric);
if (Inters.IsDone())
{
myNbExt = Inters.NbPoints();
+ aStartIdx = myNbExt;
if (myNbExt > 0)
{
- mySqDist = new TColStd_HArray1OfReal(1, myNbExt);
- myPoint1 = new Extrema_HArray1OfPOnCurv(1, myNbExt);
- myPoint2 = new Extrema_HArray1OfPOnSurf(1, myNbExt);
+ // Not more than 2 additional points from perpendiculars.
+ mySqDist = new TColStd_HArray1OfReal(1, myNbExt + 2);
+ myPoint1 = new Extrema_HArray1OfPOnCurv(1, myNbExt + 2);
+ myPoint2 = new Extrema_HArray1OfPOnSurf(1, myNbExt + 2);
Standard_Real u, v, w;
for (i = 1; i <= myNbExt; i++)
{
}
}
}
+
+ // line is tangent or outside of the cylinder
+ Extrema_ExtPElS ExPS(PC, S, Precision::Confusion());
+ if (ExPS.IsDone())
+ {
+ if (aStartIdx == 0)
+ {
+ myNbExt = ExPS.NbExt();
+ mySqDist = new TColStd_HArray1OfReal(1, myNbExt);
+ myPoint1 = new Extrema_HArray1OfPOnCurv(1, myNbExt);
+ myPoint2 = new Extrema_HArray1OfPOnSurf(1, myNbExt);
+ }
+ else
+ myNbExt += ExPS.NbExt();
+
+ for (i = aStartIdx + 1; i <= myNbExt; i++) {
+ myPoint1->SetValue(i, myPOnC2);
+ myPoint2->SetValue(i, ExPS.Point(i - aStartIdx));
+ mySqDist->SetValue(i,(myPOnC2.Value()).SquareDistance(ExPS.Point(i - aStartIdx).Value()));
+ }
+ }
myDone = Standard_True;
}
void Extrema_ExtElCS::Perform(const gp_Lin& C,
- const gp_Sphere& S)
+ const gp_Sphere& S)
{
+ // In case of intersection - return four points:
+ // 2 intersection points and 2 perpendicular.
+ // No intersection - only min and max.
+
myDone = Standard_False;
myNbExt = 0;
myIsPar = Standard_False;
+ Standard_Integer aStartIdx = 0;
- gp_Pnt O = S.Location();
+ gp_Pnt aCenter = S.Location();
- Extrema_ExtPElC Extrem(O, C, Precision::Angular(), RealFirst(), RealLast());
+ Extrema_ExtPElC Extrem(aCenter, C, Precision::Angular(), RealFirst(), RealLast());
Standard_Integer i;
- if (Extrem.IsDone()) {
+ if (Extrem.IsDone() &&
+ Extrem.NbExt() > 0)
+ {
Extrema_POnCurv myPOnC1 = Extrem.Point(1);
+ if (myPOnC1.Value().Distance(aCenter) <= S.Radius())
+ {
+ IntAna_IntConicQuad aLinSphere(C, S);
+ if (aLinSphere.IsDone())
+ {
+ myNbExt = aLinSphere.NbPoints();
+ aStartIdx = myNbExt;
+ // Not more than 2 additional points from perpendiculars.
+ mySqDist = new TColStd_HArray1OfReal(1, myNbExt + 2);
+ myPoint1 = new Extrema_HArray1OfPOnCurv(1, myNbExt + 2);
+ myPoint2 = new Extrema_HArray1OfPOnSurf(1, myNbExt + 2);
+
+ for (i = 1; i <= myNbExt; i++)
+ {
+ Extrema_POnCurv aCPnt(aLinSphere.ParamOnConic(i), aLinSphere.Point(i));
+
+ Standard_Real u,v;
+ ElSLib::Parameters(S, aLinSphere.Point(i), u, v);
+ Extrema_POnSurf aSPnt(u, v, aLinSphere.Point(i));
+
+ myPoint1->SetValue(i, aCPnt);
+ myPoint2->SetValue(i, aSPnt);
+ mySqDist->SetValue(i,(aCPnt.Value()).SquareDistance(aSPnt.Value()));
+ }
+ }
+ }
+
Extrema_ExtPElS ExPS(myPOnC1.Value(), S, Precision::Confusion());
- if (ExPS.IsDone()) {
- myNbExt = ExPS.NbExt();
- mySqDist = new TColStd_HArray1OfReal(1, myNbExt);
- myPoint1 = new Extrema_HArray1OfPOnCurv(1, myNbExt);
- myPoint2 = new Extrema_HArray1OfPOnSurf(1, myNbExt);
- for (i = 1; i <= myNbExt; i++) {
- myPoint1->SetValue(i, myPOnC1);
- myPoint2->SetValue(i, ExPS.Point(i));
- mySqDist->SetValue(i,(myPOnC1.Value()).SquareDistance(ExPS.Point(i).Value()));
- myDone = Standard_True;
+ if (ExPS.IsDone())
+ {
+ if (aStartIdx == 0)
+ {
+ myNbExt = ExPS.NbExt();
+ mySqDist = new TColStd_HArray1OfReal(1, myNbExt);
+ myPoint1 = new Extrema_HArray1OfPOnCurv(1, myNbExt);
+ myPoint2 = new Extrema_HArray1OfPOnSurf(1, myNbExt);
+ }
+ else
+ myNbExt += ExPS.NbExt();
+
+ for (i = aStartIdx + 1; i <= myNbExt; i++)
+ {
+ myPoint1->SetValue(i, myPOnC1);
+ myPoint2->SetValue(i, ExPS.Point(i - aStartIdx));
+ mySqDist->SetValue(i,(myPOnC1.Value()).SquareDistance(ExPS.Point(i - aStartIdx).Value()));
}
}
}
+ myDone = Standard_True;
}
--- /dev/null
+puts "=========="
+puts "OCC25368"
+puts "=========="
+puts ""
+################################################
+# BREPExtrma DistShapeShape gives wrong result for Sphere and Line
+################################################
+
+sphere s 0 0 0 4.5
+rotate s 0 0.5 1 1 1 0.5 34.9
+line l -0.79 0.88 1.22 0.579 1.765 0.576
+
+set extrema_res [extrema l s]
+set extrema_length [llength ${extrema_res} ]
+
+# Amount check
+if {${extrema_length} != 18 } {
+ puts "Error: expected only two lines as result of extrema!"
+}
+
+# Distance check on ext_1
+set info [dump ext_1]
+regexp {Extrema 1 is point : +([-0-9.+eE]+) +([-0-9.+eE]+) +([-0-9.+eE]+)} $extrema_res full x1 y1 z1
+# Point check
+set good_x1 -2.2838350838816694
+set good_y1 -3.6737459810900646
+set good_z1 -0.2660950057268425
+checkreal "Intersection point x:" ${x1} ${good_x1} 0.01 0.01
+checkreal "Intersection point y:" ${y1} ${good_y1} 0.01 0.01
+checkreal "Intersection point z:" ${z1} ${good_z1} 0.01 0.01
+
+
+# Distance check on ext_2
+regexp {Extrema 2 is point : +([-0-9.+eE]+) +([-0-9.+eE]+) +([-0-9.+eE]+)} $extrema_res full x2 y2 z2
+# Point check
+set good_x2 0.29086178559218934
+set good_y2 4.1748550113475211
+set good_z2 2.2952614654595873
+checkreal "Intersection point x:" ${x2} ${good_x2} 0.01 0.01
+checkreal "Intersection point y:" ${y2} ${good_y2} 0.01 0.01
+checkreal "Intersection point z:" ${z2} ${good_z2} 0.01 0.01