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