2
$\begingroup$

I'm trying to make a function that takes in a vector of pure functions (representing a parametric equation) and returns another vector of pure functions representing an offset curve. Here's what I have as an example of an input curve:

HermiteSpline[{p1x_, p1y_}, {p2x_, p2y_}, {t1x_, t1y_}, {t2x_, t2y_}] :=
{p2x (3 #^2 - 2 #^3) + p1x (1 - 3 #^2 + 2 #^3) + (# - 2 #^2 + #^3) t1x + 
(-#^2 + #^3) t2x , p2y (3 #^2 - 2 #^3) + p1y (1 - 3 #^2 + 2 #^3) + (# - 
   2 #^2 + #^3) t1y + (-#^2 + #^3) t2y } &

Basically, some messy function that returns a vector with two elements, both pure functions. Then, I want to make another function that would take this as an argument and do some operations on the curve and return a different curve, like so:

CurveOffset[P_ , radius_] :=  radius {(P[[2]])'[#], (P[[1]])'[#]}/
Sqrt[((P[[1]])'[#])^2 + ((P[[2]])'[#])^2] &

So P would be the argument containing the function, it gets indexed and had its derivative taken, then returns another vector. But I keep getting the following error:

Part::partw: Part 2 of {0.5 (3 Slot[<<1>>]^2-2 Power[<<2>>])+0.2 (1-3 Power[<<2>>]+2 Slot[<<1>>]^3)+(#1-2 Power[<<2>>]+#1^3) 0+(-Slot[<<1>>]^2+#1^3) 0,0.5 (3 Slot[<<1>>]^2-2 Power[<<2>>])+0 (1-3 Power[<<2>>]+2 Slot[<<1>>]^3)+(#1-2 Power[<<2>>]+#1^3) 1+(-Slot[<<1>>]^2+#1^3) 1}& does not exist.

I've been searching around but I'm just not sure what's going wrong or how to fix it. Any help is appreciated, thanks!

$\endgroup$
  • $\begingroup$ try hermiteSpline[{p1x_, p1y_}, {p2x_, p2y_}, {t1x_, t1y_}, {t2x_, t2y_}] := {p2x (3 #^2 - 2 #^3) + p1x (1 - 3 #^2 + 2 #^3) + (# - 2 #^2 + #^3) t1x + (-#^2 + #^3) t2x &, p2y (3 #^2 - 2 #^3) + p1y (1 - 3 #^2 + 2 #^3) + (# - 2 #^2 + #^3) t1y + (-#^2 + #^3) t2y &}? $\endgroup$ – kglr Mar 24 '17 at 21:50
  • $\begingroup$ Just tried - then CurveOffset works okay, but then when I try something like HermiteSpline[{0.2, 0}, {0.5, 0.5}, {0, 1}, {0, 1}][0] which I would want when trying to plot ( like ParametricPlot[HermiteSpline[{0.2, 0}, {0.5, 0.5}, {0, 1}, {0, 1}][t], {t, 0, 1}] ], it doesn't substitute the variable (I get something like {0.5 (3 #1^2 - 2 #1^3) + 0.2 (1 - 3 #1^2 + 2 #1^3) + (#1 - 2 #1^2 + #1^3) 0 + (-#1^2 + #1^3) 0 &, 0.5 (3 #1^2 - 2 #1^3) + 0 (1 - 3 #1^2 + 2 #1^3) + (#1 - 2 #1^2 + #1^3) 1 + (-#1^2 + #1^3) 1 &}[0]). $\endgroup$ – Billy Kalfus Mar 24 '17 at 21:54
  • $\begingroup$ with hermiteSpline you should use Through; i.e. ParametricPlot[ Through@hermiteSpline[{0.2, 0}, {0.5, 0.5}, {0, 1}, {0, 1}][t], {t, 0, 1}] and Through@hermiteSpline[{0.2, 0}, {0.5, 0.5}, {0, 1}, {0, 1}][0] gives {0.2, 0.}. $\endgroup$ – kglr Mar 24 '17 at 21:56
  • $\begingroup$ works, thank you! $\endgroup$ – Billy Kalfus Mar 24 '17 at 21:58
  • $\begingroup$ Billy K, welcome to mma.se. I posted the comment as an answer. $\endgroup$ – kglr Mar 24 '17 at 22:08
2
$\begingroup$

Define hermiteSpline to return a pair of pure functions:

hermiteSpline[{p1x_, p1y_}, {p2x_, p2y_}, {t1x_, t1y_}, {t2x_, t2y_}] :=
Function/@ {p2x (3 #^2 - 2 #^3) + p1x (1 - 3 #^2 + 2 #^3) + (# - 2 #^2 + #^3) t1x + 
 (-#^2 + #^3) t2x , 
 p2y (3 #^2 - 2 #^3) + p1y (1 - 3 #^2 + 2 #^3) + (# -2 #^2 + #^3) t1y + (-#^2 + #^3) t2y } 

or, equivalently,

 hermiteSpline[{p1x_, p1y_}, {p2x_, p2y_}, {t1x_, t1y_}, {t2x_, t2y_}] :=
  {p2x(3 #^2 - 2 #^3) + t1x(# - 2 #^2 + #^3) + t2x(-#^2 + #^3) + p1x (1 - 3 #^2 + 2 #^3)&, 
   p2y(3 #^2 - 2 #^3) + t1y(# - 2 #^2 + #^3) + t2y(-#^2 + #^3) + p1y (1 - 3 #^2 + 2 #^3)&}

Through@hermiteSpline[{0.2, 0}, {0.5, 0.5}, {0, 1}, {0, 1}][0]

{0.2, 0.}

 ParametricPlot[Through@hermiteSpline[{0.2, 0}, {0.5, 0.5}, {0, 1}, {0, 1}][t], 
  {t,  0, 1}]

Mathematica graphics

 CurveOffset[hermiteSpline[{0.2, 0}, {0.5, 0.5}, {0, 1}, {0, 1}], radius] /@ {0, 1, 2}

{{1. radius, 0.}, {1. radius, 0.},{0.889288 radius, -0.457348 radius}}

$\endgroup$
  • 1
    $\begingroup$ FWIW, the example Hermite spline is most easily implemented using Interpolation[]: hs = Interpolation[{{{0}, {0.2, 0}, {0, 1}}, {{1}, {0.5, 0.5}, {0, 1}}}]; ParametricPlot[hs[t], {t, 0, 1}] Then, if the parallel curves are wanted: ParametricPlot[{hs[t] - (1/20) Normalize[Cross[hs'[t]]], hs[t], hs[t] + (1/20) Normalize[Cross[hs'[t]]]}, {t, 0, 1}]. $\endgroup$ – J. M. is away Mar 25 '17 at 4:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.