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$
6
  • $\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, 2017 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$ Mar 24, 2017 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, 2017 at 21:56
  • $\begingroup$ works, thank you! $\endgroup$ Mar 24, 2017 at 21:58
  • $\begingroup$ Billy K, welcome to mma.se. I posted the comment as an answer. $\endgroup$
    – kglr
    Mar 24, 2017 at 22:08

1 Answer 1

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
  • 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$ Mar 25, 2017 at 4:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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