MCPcopy Create free account
hub / github.com/BIMCoderLiang/LNLib / FitWithConic

Method FitWithConic

src/LNLib/Geometry/Curve/NurbsCurve.cpp:2806–2882  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

2804}
2805
2806bool LNLib::NurbsCurve::FitWithConic(const std::vector<XYZ>& throughPoints, int startPointIndex, int endPointIndex, const XYZ& startTangent, const XYZ& endTangent, double maxError, std::vector<XYZW>& middleControlPoints)
2807{
2808 VALIDATE_ARGUMENT(throughPoints.size() > 0, "throughPoints", "ThroughPoints size must be greater than zero.");
2809 VALIDATE_ARGUMENT_RANGE(startPointIndex, 0, throughPoints.size() - 1);
2810 VALIDATE_ARGUMENT_RANGE(endPointIndex, startPointIndex + 1, throughPoints.size() - 1);
2811 VALIDATE_ARGUMENT(!startTangent.IsZero(), "startTangent", "StartTangent must not be zero vector.");
2812 VALIDATE_ARGUMENT(!endTangent.IsZero(), "endTangent", "EndTangent must not be zero vector.");
2813
2814 XYZ startPoint = throughPoints[startPointIndex];
2815 XYZ endPoint = throughPoints[endPointIndex];
2816 if (endPointIndex - startPointIndex == 1)
2817 {
2818 return BezierCurve::ComputerMiddleControlPointsOnQuadraticCurve(startPoint, startTangent, endPoint, endTangent, middleControlPoints);
2819 }
2820
2821 double alf1, alf2 = 0.0;
2822 XYZ R(0, 0, 0);
2823 CurveCurveIntersectionType type = Intersection::ComputeRays(startPoint, startTangent, endPoint, endTangent, alf1, alf2, R);
2824 if (type == CurveCurveIntersectionType::Coincident)
2825 {
2826 middleControlPoints.emplace_back(XYZW((startPoint + endPoint) / 2, 1));
2827 return true;
2828 }
2829 else if (type == CurveCurveIntersectionType::Skew || type == CurveCurveIntersectionType::Parallel)
2830 {
2831 return false;
2832 }
2833 if (MathUtils::IsLessThanOrEqual(alf1, 0.0) ||
2834 MathUtils::IsGreaterThanOrEqual(alf2, 0.0))
2835 {
2836 return false;
2837 }
2838 double s = 0.0;
2839 XYZ V = endPoint - startPoint;
2840 XYZ dummy;
2841 for (int i = startPointIndex + 1; i <= endPointIndex - 1; i++)
2842 {
2843 XYZ V1 = throughPoints[i] - R;
2844 type = Intersection::ComputeRays(startPoint, V, R, V1, alf1, alf2, dummy);
2845 if (type != CurveCurveIntersectionType::Intersecting ||
2846 MathUtils::IsLessThanOrEqual(alf1, 0.0) ||
2847 MathUtils::IsGreaterThanOrEqual(alf1, 1.0) ||
2848 MathUtils::IsLessThanOrEqual(alf2, 0.0))
2849 {
2850 return false;
2851 }
2852 double wi = 0.0;
2853 if (CreateOneConicArc(startPoint, V, R, V1, throughPoints[i], dummy, wi))
2854 {
2855 s = s + wi / (1 + wi);
2856 }
2857 }
2858
2859 s = s / (endPointIndex - startPointIndex - 1);
2860 double w = s / (1.0 - s);
2861
2862 std::vector<XYZW> controlPoints = { XYZW(startPoint,1), XYZW(R,w), XYZW(endPoint,1) };
2863 std::vector<double> knotVectors = { 0,0,0,1.0,1.0,1.0 };

Callers

nothing calls this directly

Calls 4

GetPointOnCurveFunction · 0.85
XYZWClass · 0.50
IsZeroMethod · 0.45
DistanceMethod · 0.45

Tested by

no test coverage detected