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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.