jianbaoxia
CAD master
Hi Bros, I'm JianBaoxia.
Today, while using Handle(Geom_Curve)->value() to obtain some points on a B-spline curve, I encountered some strange phenomena. Therefore, I couldn't wait to discuss and share with you. To illustrate the problem, I wrote a simple demo, which is as follows:
I read in a B-spline curve with parameter values ranging from 0 to 1. Using Handle(Geom_Curve)->value(), I generated five points on the curve with parameter values of {0, 0.005, 0.5, 0.995, 1}. Then, I used "GeomAPI_ProjectPointOnCurve" to calculate the distance from each of the five points to the curve to determine whether they were located on the curve. The answer was affirmative, as the maximum distance between the points and the curve was at the order of 1e-15, which is far smaller than the tolerance of 1e-7. However, when I outputted the points and the curve together, I found that only the first and last points were truly on the curve, while the middle three had some distance away from the curve. I measured the distances of the middle three points on FreeCAD and obtained the values of 1.2e-1, 4.07e-7, and 8.21e-5, respectively. Clearly, the errors of these three points are all greater than the tolerance of 1e-7. As show below:
So, I'm very puzzled as to where the problem lies. According to the formula for NURBS curves, there should be no errors in calculating the points on the curve. Could it be a display issue? Are these five points actually completely on the curve? However, if that were the case, there should be some visible deviation for the first and last points on FreeCAD, but in fact, these two points look completely on the curve.
There is my demo、B-spline curve file: "aEdge.step" and result file: "aSewShape.step":
Today, while using Handle(Geom_Curve)->value() to obtain some points on a B-spline curve, I encountered some strange phenomena. Therefore, I couldn't wait to discuss and share with you. To illustrate the problem, I wrote a simple demo, which is as follows:
I read in a B-spline curve with parameter values ranging from 0 to 1. Using Handle(Geom_Curve)->value(), I generated five points on the curve with parameter values of {0, 0.005, 0.5, 0.995, 1}. Then, I used "GeomAPI_ProjectPointOnCurve" to calculate the distance from each of the five points to the curve to determine whether they were located on the curve. The answer was affirmative, as the maximum distance between the points and the curve was at the order of 1e-15, which is far smaller than the tolerance of 1e-7. However, when I outputted the points and the curve together, I found that only the first and last points were truly on the curve, while the middle three had some distance away from the curve. I measured the distances of the middle three points on FreeCAD and obtained the values of 1.2e-1, 4.07e-7, and 8.21e-5, respectively. Clearly, the errors of these three points are all greater than the tolerance of 1e-7. As show below:
So, I'm very puzzled as to where the problem lies. According to the formula for NURBS curves, there should be no errors in calculating the points on the curve. Could it be a display issue? Are these five points actually completely on the curve? However, if that were the case, there should be some visible deviation for the first and last points on FreeCAD, but in fact, these two points look completely on the curve.
There is my demo、B-spline curve file: "aEdge.step" and result file: "aSewShape.step":
Code:
int main()
{
// read the file
STEPControl_Reader reader;
reader.ReadFile("../aEdge.step");
reader.TransferRoots();
TopoDS_Shape aShape = reader.OneShape();
TopoDS_Edge aEdge;
for (TopExp_Explorer exp(aShape, TopAbs_EDGE); exp.More(); exp.Next())
aEdge = TopoDS::Edge(exp.Current());
Standard_Real _1, _2; // no use
Handle(Geom_Curve) aCur = BRep_Tool::Curve(aEdge, _1, _2);
// sample five points on curve
TColStd_Array1OfReal sampArr(1, 5);
TColgp_Array1OfPnt sampPntsArr(1, 5);
sampArr[1] = 0.;
sampArr[2] = 0.005;
sampArr[3] = 0.5;
sampArr[4] = 0.995;
sampArr[5] = 1.;
for (int i = 1; i <= 5; i++)
{
sampPntsArr = aCur->Value(sampArr);
}
// test whether pnt on curve
for (int i = 1; i <= 5; i++)
{
gp_Pnt pnt = sampPntsArr;
GeomAPI_ProjectPointOnCurve gppc(pnt, aCur); // get the shortest distance bettwen point and curve
if (gppc.LowerDistance() <= Precision::Confusion())
std::cout << "point[" << i << "]: on the curve, the shortest distance is: " << gppc.LowerDistance() << std::endl;
else
std::cout << "! ERROR: point[" << i << "]: not on the curve, the shortest distance is" << gppc.LowerDistance() << std::endl;
}
std::cout << "The Precision::Confusion(): " << Precision::Confusion() << std::endl;
// out put the point and edge for view
BRepBuilderAPI_Sewing aSewMaker;
aSewMaker.Add(aEdge);
for (int i = 1; i <= 5; i++)
aSewMaker.Add(BRepBuilderAPI_MakeVertex(sampPntsArr));
aSewMaker.Perform();
TopoDS_Shape aSewShape = aSewMaker.SewedShape();
STEPControl_Writer writer;
Interface_Static::SetCVal("write.step.schema", "AP203");
IFSelect_ReturnStatus status = writer.Transfer(aSewShape, STEPControl_AsIs);
status = writer.Write("../aSewShape.step");
return 0;
}