There are many built-in functions that return a function object, such as Interpolation[], BSplineFunction[] ,LinearSolveFunction[] and so on.

Now given that I want to build a function called CAGDBSplineFunction[] like the built-in BSplineFunction[] with the help of Cox-DeBoor algorithm.
First trial, please see here
To achieve the dynamic effect and check the validity of the option like the built-in BSplineFunction

I refactored it as below:
CAGDBSplineFunction::invknots =
"Value of option SplineKnots \[Rule] `1` should be a non-decreasing \
real sequence of length `2`, or a symbol Automatic.";
Options[CAGDBSplineFunction] =
{SplineDegree -> Automatic, SplineKnots -> Automatic};
CAGDBSplineFunction /:
MakeBoxes[CAGDBSplineFunction[pts_, opts : OptionsPattern[]], _] :=
Module[{n, sk, sd, range},
n = Length@pts - 1;
sk = OptionValue[SplineKnots];
sd = OptionValue[SplineDegree];
(*check the validity of the option SplineKnots*)
If[sk =!= Automatic,
If[n + 1 + sd != Length[sk] - 1,
Message[CAGDBSplineFunction::invknots, sk, n + 2 + sd];
Return[$Failed]];
range = Through[{First, Last}@sk],
range = {0, 1}
]
]
InterpretationBox[
RowBox[{"CAGDBSplineFunction", "[", "{", #1, ",", #2, "}", ",",
"\"<>\"", "]"}], CAGDBSplineFunction[pts, opts]] & @@ range
]
TEST
pts = {{0, 0}, {1, 1}, {2, -1}, {3, 0}, {4, -2}, {5, 1}};
f = CAGDBSplineFunction[pts]

However, it seems that the option value cannot be achieved in a MakeBoxes construct.
J.M. gives me the following suggestion:
Don't try to do both display and processing at once. Set a definition for evaluating
CAGDBSplineFunction[], and then set a definition for displaying, viaMakeBoxes
According to the J.M.'s hint, I add the defintion to CAGDBSplineFunction[]
CAGDBSplineFunction /:
MakeBoxes[CAGDBSplineFunction[pts_, opts : OptionsPattern[]], _] :=
InterpretationBox[
RowBox[{"CAGDBSplineFunction", "[", "{", #1, ",", #2, "}", ",",
"\"<>\"", "]"}], CAGDBSplineFunction[pts, opts]] & @@
CAGDBSplineFunction[pts, opts]
CAGDBSplineFunction[pts_, opts : OptionsPattern[]] :=
Module[
{n, sk, sd, range},
n = Length@pts - 1;
sk = OptionValue[SplineKnots];
sd = OptionValue[SplineDegree] /. Automatic -> 3;
(*check the validity of the option SplineKnots*)
If[sk =!= Automatic,
If[n + 1 + sd != Length[sk] - 1,
Message[CAGDBSplineFunction::invknots, sk, n + 2 + sd];
Return[$Failed]];
range = Through[{First, Last}@sk],
range = {0, 1}
]
]

Comments
Post a Comment