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}
]
]
constructor[pts_, deg_] := excecutor[someStructure[pts, deg]]; excecutor[someStructure[pts_, deg_]][t_] := doSomething[someStructure[pts, deg, t]]; myfun = constructor[{{1, 1}, {2, 2}}, 1]; myfun[t]
? $\endgroup$makemyfn[stuff_]
to return objectmyfn[data]
. (2) Formatmyfn
with withMakeBoxes
as in the linked questions in the comments. (3) Computation: Define sub-valuemyfn[datastructure_][input_] := (* computation *)
for the computation, using whatever patterns fordatastructure
that are appropriate. -- Which is what belisarius said, but seems to have been ignored? $\endgroup$Interpolation
is distinct fromInterpolatingFunction
. The insides of the latter are of no concern to users, thus there's no need to do syntax checking on them. $\endgroup$