The problem I'm having is that the function definition given below continually gives me baffling error messages.
I'm trying to turn a list of 3D points into a function that approximates a curve by connecting consecutive points with straight lines. If anyone has a smarter way to do that than what I describe below (a smooth curve would be fine too), I'll accept suggestions! Note that it's vital for the curve to be parametric.
The definition says, in words: "define each location on the 'curve' as a weighted average of the two nearest given points, where the points are provided in a list, and each element in the list is a list of three coordinates. (e.g. {{1,1,1},...})." The effect of weighting (given by 'frac' and '1-frac') is to effectively construct a continuous straight line between each two given points. The 'If' statement ensures that when constructing the last point, the function won't attempt to look for a point after the last point.
Here's the definition:
curve[s_] :=
(frac = 1 - Mod[s*100, 1]) points[[low = Floor[s*100] + 1]] +
If[s < 1.0, (1 - frac) points[[low + 1]], 0]
curve3D = ParametricPlot3D[curve[s], {s, 0.0, 1.0}]
The call to ParametricPlot3D
gives me this error message:
Part::pspec: Part specification 1+Floor[100 s] is neither a machine-sized integer nor a list of machine-sized integers. >>
or sometimes (after a few minutes of debugging) it starts giving this instead:
Part::partw: Part 102 of {{0.,2.0944,15.},{0.015708,2.09432,14.9963},{0.0314159,2.09411,14.9852},{0.0471239,2.09375,14.9667},<<44>>,{0.753982,1.94388,7.97093},{0.76969,1.93806,7.73558},<<51>>} does not exist. >>
The first set of messages seem to be saying that 's' isn't getting evaluated, which makes no sense to me.
The second set say that I'm trying to access the 102nd point (there are only 101 points), which I believe I'm avoiding with the If statement. The message even persists if I change the parametric range of s to {s, 0.0, 0.5} and if I clear the variable "low" beforehand.
Can anyone explain either of these error messages, and what I'm doing wrong? Is it a misuse of ParametricPlot3D
?
For further clarity, here's the output of curve3D (rotated on its side to save space). Note the odd gap in the middle. As you change the parametric range of s (e.g. {s, 0.0, 0.8}) the number and location of the gaps changes. Super weird stuff.
Also, if you want to run my code yourself, here's how you construct the list 'points':
potential[x_, y_] := 20 (Cos[x]^2 + Cos[y]^2 + Cos[x] Cos[y])
nmax = 100;
points = {};
For[n = 0, n <= nmax, n++,
xn = N[(π/2)*n/nmax];
ptrule = FindMinimum[potential[xn, y], {y, π/2}];
pt = {xn, y, potential[xn, y]} /. ptrule[[2]];
AppendTo[points, pt];]
ParametricPlot3D
). Have you tried restarting the kernel on the off chance that some stray definitions are giving you trouble? $\endgroup$ParametricPlot3D
you showed. I am using MMA v. 10.1.0 on Win7-64bit. What version are you on, just in case? I just can't seem to reproduce your problem. Can you simplify your code further to a minimal example that still produces that error? $\endgroup$PlotPoints
option forParametricPlot3D
to a large value. $\endgroup$